1、导入包
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
from sklearn import model_selection
import matplotlib.pyplot as plt
2、导入数据
采用鸢尾花数据集。鸢尾花数据集一共有 150个数据,这些数据分为3类(分别为setosa,versicolor,virginica),每类50个数据。每个数据包含4个属性:萼片(sepal)长度、萼片宽度、花瓣(petal)长度、花瓣宽度。
def load_data():
iris=datasets.load_iris() # scikit-learn 自带的 iris 数据集
X_train=iris.data
y_train=iris.target
return model_selection.train_test_split(X_train, y_train,test_size=0.25,
random_state=0,stratify=y_train)# 分层采样拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4
在这里采用分层采样。因为原始数据集中,前50个样本都是类别0,中间50个样本都是类别1,最后50个类别都是类别2。如果不采取分层采用,那么最后切分得到的测试数据集就不是无偏的了。
3、DecisionTreeClassifier分类函数
# DecisionTreeClassifier分类函数
def test_DecisionTreeClassifier(*data):
X_train,X_test,y_train,y_test=data
clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
print("Training score:%f"%(clf.score(X_train,y_train)))
print("Testing score:%f"%(clf.score(X_test,y_test)))
代入数据:
X_train,X_test,y_train,y_test=load_data() # 产生用于分类问题的数据集
test_DecisionTreeClassifier(X_train,X_test,y_train,y_test) # 调用 test_DecisionTreeClassifier
运行结果:
Training score:1.000000
Testing score:0.973684
4、criterion对于分类性能的影响
criterion: 一个字符串,指定切分质量的评价准则。
1)'gini': 表示切分时评价准则是6ini系数。
2)'entropy': 表示切分时评价准则是熵。
def test_DecisionTreeClassifier_criterion(*data):
X_train,X_test,y_train,y_test=data
criterions=['gini','entropy']
for criterion in criterions:
clf = DecisionTreeClassifier(criterion=criterion)
clf.fit(X_train, y_train)
print("criterion:%s"%criterion)
print("Training score:%f"%(clf.score(X_train,y_train)))
print("Testing score:%f"%(clf.score(X_test,y_test)))
代入数据
X_train,X_test,y_train,y_test=load_data() # 产生用于分类问题的数据集
test_DecisionTreeClassifier_criterion(X_train,X_test,y_train,y_test) # 调用 test_DecisionTreeClassifier_criterion
运行结果如下:
可以看到对于本问题二者对于训练集的拟合都非常完美( 100% ),对于测试集的预测都较高,但是稍有不同;使用6ini系数的策略预测性能较高。
criterion:gini
Training score:1.000000
Testing score:0.947368
criterion:entropy
Training score:1.000000
Testing score:0.921053
5、检验随机划分与最优划分的影响
def test_DecisionTreeClassifier_splitter(*data):
X_train,X_test,y_train,y_test=data
splitters=['best','random']
for splitter in splitters:
clf = DecisionTreeClassifier(splitter=splitter)
clf.fit(X_train, y_train)
print("splitter:%s"%splitter)
print("Training score:%f"%(clf.score(X_train,y_train)))
print("Testing score:%f"%(clf.score(X_test,y_test)))
带入数据
X_train,X_test,y_train,y_test=load_data() # 产生用于分类问题的数据集
test_DecisionTreeClassifier_splitter(X_train,X_test,y_train,y_test) # 调用 test_DecisionTreeClassifier_splitter
运行结果如下
可以看到对于本问题二者对于训练集的拟合都非常完美( 100% ),对于测试集的预测都较高,但是稍有不同;使用最优划分的性能要高于随机划分。
splitter:best
Training score:1.000000
Testing score:0.973684
splitter:random
Training score:1.000000
Testing score:0.973684
6、考察决策树深度影响
决策树的深度对应着树的复杂度。决策树越深,则模型越复杂,给出函数。
def test_DecisionTreeClassifier_depth(*data,maxdepth):
X_train,X_test,y_train,y_test=data
depths=np.arange(1,maxdepth)
training_scores=[]
testing_scores=[]
for depth in depths:
clf = DecisionTreeClassifier(max_depth=depth)
clf.fit(X_train, y_train)
training_scores.append(clf.score(X_train,y_train))
testing_scores.append(clf.score(X_test,y_test))
## 绘图
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
ax.plot(depths,training_scores,label="traing score",marker='o')
ax.plot(depths,testing_scores,label="testing score",marker='*')
ax.set_xlabel("maxdepth")
ax.set_ylabel("score")
ax.set_title("Decision Tree Classification")
ax.legend(framealpha=0.5,loc='best')
plt.show()
带入数据
X_train,X_test,y_train,y_test=load_data() # 产生用于分类问题的数据集
test_DecisionTreeClassifier_depth(X_train,X_test,y_train,y_test,maxdepth=100) # 调用 test_DecisionTreeClassifier_depth
运行结果如下
可以看到随着树深度的增加( 对应着模型复杂度的提高),模型对训练集和预测集的拟合都在提高。这里训练数据集大小仅为150,不考虑任何条件,只需要- -棵深度为log2 150≤8的二叉树就能够完全拟合数据,使得每个叶子节点最多只有一个样本。考虑到决策树算法中的提前终止条件(比如叶子节点中所有样本都是同一类则不再划分,此时叶节点中有超过一一个样本),则树的深度小于8。