reference: scikit-learn决策树算法类库使用小结
from itertools import product
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
# 仍然使用自带的iris数据
iris = datasets.load_iris()
#只使用了两个特征,便于在二维平面上表示决策空间的分布
X = iris.data[:, [0, 2]]
y = iris.target
# 训练模型,限制树的最大深度4
clf = DecisionTreeClassifier(max_depth=4)
#拟合模型
clf.fit(X, y)
# 画图
#X[:,0]表示从开始倒结尾元素以默认step=1进行切片,并且取切片的所有元素的第一个元素
# 相当于取了数据第一列的特征
#X[:,1]相当于取了数据第三列的特征
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),
np.arange(y_min, y_max, 0.1))
#根据Z值的不同确定是在不同的决策空间中
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
#contour绘制等高线图,contourf不绘制等高线,用不同颜色表示不同高度
plt.contourf(xx, yy, Z, alpha=0.4)
#绘制散点图
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)
plt.show()
博客中的最后一段代码有问题
from IPython.display import Image
from sklearn import tree
import pydotplus
dot_data = tree.export_graphviz(clf, out_file=None,
#feature_names=iris.feature_names,
#因为上面建立的决策树使用了两个特征,没有完全使用数据中所有的特征,所以需要修改,不过作者生成的图和我修改后好像是一样的
feature_names=iris.feature_names[::2],
class_names=iris.target_names,
filled=True, rounded=True,
special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png())
下面需要说明一点的是sklearn中DecisionTree算法的需要注意的地方:
决策树三大流行算法ID3、C4.5和CART
sklearn.tree.DecisionTreeClassifier基本上使用的是CART,稍稍有区别的是它对CART的计算性能进行了优化。你是不可以指定它使用其他算法的。但是你可以设置sklearn.tree.DecisionTreeClassifier中criterion参数为”entropy”,也就是信息增益,这样就类似于ID3了(其实与其仍有很大的不同,因为sklean里的decision tree模型,不管是回归还是分类,都限制为二叉树。)。C4.5是基于信息增益率的,所以sklearn.tree.DecisionTreeClassifier做不到C4.5算法。
sklearn.tree.DecisionTreeClassifier是无法处理nominal的数据类型,下面的有一个例子
#coding=utf-8
import arff
from itertools import product
import numpy as np
import matplotlib.pyplot as plt # plt 用于显示图片
from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
import matplotlib.image as mpimg # mpimg 用于读取图片
from sklearn import tree
import os
dataset=arff.load(open("D:/res/weather.nominal.arff"),encode_nominal=True)
features=np.array(dataset['data'])
X=features[:,[0,1,2,3]]
y=features[:,4]
clf=DecisionTreeClassifier(criterion='entropy')
clf.fit(X,y)
feat_names=[name[0] for name in dataset['attributes'][0:4]]
with open("D:/res/out.dot", 'w') as f:
f = tree.export_graphviz(clf, out_file=f,
feature_names=feat_names,
class_names=dataset['attributes'][4][1],
filled=True,rounded=True,
special_characters=True)
os.system('dot -Tpng d:/res/out.dot -o d:/res/out.png')
os.system('d:/res/out.png')
得到的树为:
使用的数据集是Weka中的weather数据,可以看到算法在划分一个属性时先把属性值排序(虽然有些标称属性排序是没有意义的),然后找一个数值将属性值分成两个集合.