这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战
一 概述篇
1.1 决策树的工作原理
决策树(Decision Tree)作为一种非参数的有监督学习方法,可以从一系列有特征和标签的数据中总结出决策规则,以树状图的结构来呈现,解决分类和回归的问题,适用于各种数据; 对于节点 根节点:没有进边,有出边 中间节点:既有进边也有出边,进边只有一条,出边可以有很多条,都是针对特征的提问 叶子节点:有进边,没有出边,每个叶子节点都有一个类别标签 子节点和父节点:在两个相连的节点中,更接近根节点的是父节点,另一个是子节点 决策树算法的核心就是要解决两个关键性的问题,如何从数据表中找出最佳的节点和最佳的分支(你要提问,要对哪个特征提问是最好的呢?),如何让决策树停止生长,防止过拟合?(有那么多特征,要提问多少就停止呢)
1.2 sklearn 的基本建模流程
对于这个流程,分类树对应的代码是:
from sklearn import tree #导入需要的模块
clf= tree .DecisionTreeClassifier() #实例化
clf =clf.fit(x_train,y_train) #用训练集数据训练模型
result = clf .score(x_test ,y_test ) #导入测试集,从接口中调用需要的信息
二 重要参数
2.1 criterion
决策树需要找出最佳节点和最佳的分枝方法,对分类树来说,衡量这个"最佳"的指标叫做"不纯度"。通常说,不纯度越低,决策树对训练集的拟合越好。不纯度基于节点来计算,树中的每个节点都会有一个不纯度,并且子节点的不纯度一定是低于父节点的,也就是说,在同一棵决策树上,叶子节点的不纯度一定是最低的。 Criterion决定不纯度的计算方法。sklearn中两种选择;
- 输入"entropy",使用信息嫡(Entropy)
- 输入"gini",使用基尼系数(Gini lmpurity)
其中t代表给定的节点,i代表标签的任意分类,p(i|t)代表标签分类i在节点t上所占的比例。注意,当使用信息嫡时,sklearn实际计算的是基于信息嫡的信息增益(Information Gain),即父节点的信息嫡和子节点的信息嫡之差。在实际使用中,信息熵和基尼系数的效果基 本相同。信息熵的计算比基尼系数缓慢一些,因为基尼系数的计算不涉及对数,通常情况下可以两者都试一下
2.2 决策树的基本流程
from sklearn import tree
from sklearn.datasets import load_wine #自带的红酒数据集
from sklearn.model_selection import train_test_split
#数据探索
wine=load_wine()
wine.data
wine.data.shape
wine.target
import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)
#划分训练集和测试集,进行建模
x_train,x_test,y_train,y_test=train_test_split(wine.data,wine.target,test_size=0.3)
x_train.shape
x_test.shape
#建立模型
clf =tree.DecisionTreeClassifier(criterion='entropy',random_state=200)
clf=clf.fit(x_train,y_train)
score=clf.score(x_test,y_test) #预测的准确度
score #结果0.944
2.3 ,将树画出,需要提前安装graphviz
feature_name= ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
import graphviz
dot_data=tree.export_graphviz(clf
,out_file=None
,feature_names=feature_name
,class_names=['A','B','C']
,filled=True
,rounded=True
)
graph=graphviz.Source(dot_data)
graph
2.2.1 特征的重要性
clf.feature_importances_
[*zip(feature_name,clf.feature_importances_)]
2.4 剪枝参数
在不加限制的情况下,一棵决策树会生长到衡量不纯度的指标最优,或者没有更多的特征可用为止。这样的决策树 往往会过拟合,即在训练集上表现很好,在测试集上却表现糟糕。收集的样本数据不可能和整体 的状况完全一致,因此当一棵决策树对训练数据有了过于优秀的解释性,它肯定包含了训练样本中的噪 声,导致它对未知数据的拟合程度不足。为了让决策树有更好的泛化性,要对决策树进行剪枝
2.4.1 max_depth
限制树的最大深度,超过设定深度的树枝全部剪掉,在高维度低样本量时非常有效,建议从=3开始尝试,看看拟合的效 果再决定是否增加设定深度。
2.4.2 mn_samples_leaf&min_samples_split
- min_samples_leaf:一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分 枝就不会发生,或者,分枝会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生,这个参数的数量设置得太小会引 起过拟合,设置得太大就会阻止模型学习数据。一般来说,建议从=5开始,
- min_samples_split:一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则 分枝就不会发生
clf=tree.DecisionTreeClassifier(criterion='entropy'
,random_state=200
,splitter='random'
,max_depth=3
,min_samples_leaf=10
,min_samples_split=10
)
clf=clf.fit(x_train,y_train)
dot_data=tree.export_graphviz(clf
,feature_names=feature_name
,class_names=['A酒','B酒','C酒']
,filled=True
,rounded=True
)
graph=graphviz.Source(dot_data)
graph
2.5 使用学习曲线确定最优的剪枝参数
import matplotlib.pyplot as plt
test=[]
for i in range(10):
clf=tree.DecisionTreeClassifier(max_depth=i+1
,criterion='entropy'
,random_state=200
,splitter='random'
)
clf=clf.fit(x_train,y_train)
score=clf.score(x_test,y_test)
test.append(score)
plt.figure(figsize=(10,8))
plt.plot(range(1,11),test,color='blue',label='max_depth')
plt.grid(alpha=0.3)
plt.legend()
plt.show()
2.6 目标权重参数
2.6.1 class_weight&min_weight_fraction_leaf
样本不平衡是指在一组数据集中,标签的一类天生占有很大的比例,用class_weight参数对样本标签进行一定的均衡,给 少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。该参数默认None,此模式表示自动给 与数据集中的所有标签相同的权重,有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配min_ weight_fraction_leaf这个基于权重的剪枝参数来使用。
2.7 重要属性和接口
属性是在模型训练之后,能够调用查看的模型的各种性质。对决策树来说,最重要的是feature_importances_,能 够查看各个特征对模型的重要性,除此之外,决策树最常用的接口还有apply和predict。apply中输入测试集返回每个测试样本所在的叶子节 点的索引,predict输入测试集返回每个测试样本的标签,
#返回每个测试样本所在的叶子节点的索引
clf.apply(x_test)
clf.predict(x_test) #返回每个测试样的分类结果
有了这些知识,基本上分类树的使用就能够掌握了,接下来再到实例中去磨练就好了哦!