目录
一、初次简单使用
1.导入我们的数据集
2.查看我们的数据集
3.划分测试集和训练集
查看训练集
查看测试集
查看测试集的标签
4.使用决策树对我们的模型进行训练
5.使用graphviz查看我们的二叉树
二、优化决策树
1.特征的贡献值
2.重要参数
1.random_state & splitter
2.剪枝参数
max_depth
min_samples_leaf & min_samples_split
max_features & min_impurity_decrease
可视化查看如何选取参数的方法
class_weight & min_weight_fraction_leaf
3.重要的属性和接口
一、初次简单使用
1.导入我们的数据集
from sklearn import tree#导入红酒数据集#sklearn的datasets库中有大量的数据集from sklearn.datasets import load_wine#从sklearn的模型选择中导入训练集,测试集分类from sklearn.model_selection import train_test_split
2.查看我们的数据集
将我们的红酒数据放入wine中
wine=load_wine()
查看一下红酒数据集
wine
#获取wine数据集中的数据wine.data
#这里的标签为0,1,2,是一个三分类的数据集wine.target
#查看数据集有几行几列wine.data.shape
import pandas as pd#将wine数据集的数据和标签联系起来,axis,连接方向为横向连接,也就是说左边的0-12列都是我们的红酒的数据,我们右边的最后一列是我们的标签pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)
#这些特征的标题wine.feature_names
#类别wine.target_names
3.划分测试集和训练集
#30%用作测试集,剩下的70%用作训练集#x所对应的是红酒的数据,而y对应的是红酒的标签Xtrain,Xtest,Ytrain,Ytest=train_test_split(wine.data,wine.target,test_size=0.3)
查看训练集
Xtrain
Xtrain.shape
查看测试集
Xtest
查看测试集的标签
Ytrain
4.使用决策树对我们的模型进行训练
#第一步:实例化#classify,简写clf,分类器clf=tree.DecisionTreeClassifier(criterion="entropy")#第二步:将模型带入我们的分类器中进行训练clf=clf.fit(Xtrain,Ytrain)#第三步:给我们的训练结果打分#这个score就得到了我们的打分结果,返回预测的准确度accuracyscore=clf.score(Xtest,Ytest)
#这个score在我们上面每一次重新划分测试集和训练集之后都是会发生变化的#因为我们上面的train_test_split是随机划分测试集和训练集的,#所以说每一次导入的数据和模型都是不一样的#但是这个score每一次重新执行上面的三个步骤之后都会发生变化#这是因为我们的sklearn再每一次建树的时候,并没有选择全部的特征,而是选取一部分特征,从中选取不纯度相关指标最优的作为分支用的结点,#这样,每次生成的树也就不同了#也就是说假设有一个果农,想要栽培出一棵最好的苹果树,果农最好的方法并不是从一个最好的苹果中选取一个最饱满的种子,然后将这一棵种子种下,#这样不一定能够种出最好的果树#果农可以采用更好的方法,就是同时种下一批种子,等待这些种子全部生根发芽,然后从这片树中找到一棵最好的苹果树,#这也就是我们的sklearn所采用的的方法#但是这样会让我们的模型不稳定了,每次跑出来的结果都不一样了。#将在下面讲述如何解决score
5.使用graphviz查看我们的二叉树
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']#查看建模出来的这棵树是什么样子的,我们需要导入graphviz库import graphvizdot_data=tree.export_graphviz(#第一个,输入已经训练好的模型clf,#第二个,特征的名字feature_names=feature_name,#第三个,标签的名字class_names=["琴酒","雪莉","贝尔摩德"],#要不要给每一个结点填充颜色,也就是我们下面的树中的每一个框中我们是否要填充颜色,#其中颜色越深,就代表着我们的不纯度越低,也就是说我们的纯度越高filled=True,#rounded表示是我们下面生成的树的结点是圆框的还是直角框的。rounded=True,)
#将我们画的树给导出来graph=graphviz.Source(dot_data)graph#每一个框的第一行都是对于下面两棵子树的分类标准#第二行entropy是我们设置的不纯度的指标,#越往下不纯度的指标是越来越少的,也就是纯度越来越高,到达叶子节点的时候不纯度是0,也就是确定了我们的标签类别#samples包含的样本数量#value是每一个样本标签数量的占比,就比方说根节点的框中43:50:31,就是说"琴酒","雪莉","贝尔摩德"的比例是43:50:31#class是当前结点所属于的标签
二、优化决策树
1.特征的贡献值
#从上面的树中我们看到决策树并没有将全部的特征都用于分类,但是我们怎么才能知道每一个特征对于决策树的贡献呢?#使用下面的代码就能够求得每一个特征对于我们决策树的贡献clf.feature_importances_#对决策树的贡献值越大的,其数值就越高
#使用zip函数将我们的特征名字和具体的特征的贡献值联系起来#我们注意到我们的类黄酮的特征贡献值是最高的。#并且类黄酮就是我们的根节点,也就是说根节点的特征贡献值会是最高的[*zip(feature_name,clf.feature_importances_)]
2.重要参数
1.random_state & splitter
random_state用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显,低维度的数据(比如鸢尾花数据集),随机性几乎不会显现。输入任意整数,会一直长出同一棵树,让模型稳定下来。
splitter也是用来控制决策树中的随机选项的,有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看),输入“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。这也是防止过拟合的一种方式。当你预测到你的模型会过拟合,用这两个参数来帮助你降低树建成之后过拟合的可能性。当然,树一旦建成,我们依然是使用剪枝参数来防止过拟合。
#这里我们确定了随机模式是30,所以我们无论重复执行多少次下面的代码,得到的结果都是一样的#random_state用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显,低维度的数据#(比如鸢尾花数据集),随机性几乎不会显现。输入任意整数,会一直长出同一棵树,让模型稳定下来clf=tree.DecisionTreeClassifier(criterion="entropy",random_state=30)clf=clf.fit(Xtrain,Ytrain)score=clf.score(Xtest,Ytest)#返回预测结果的准确度score
#使用splitter也可以控制决策树的随机性#有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会#优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看),输入“random",决策树在#分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。这#也是防止过拟合的一种方式。当你预测到你的模型会过拟合,用这两个参数来帮助你降低树建成之后过拟合的可能#性。当然,树一旦建成,我们依然是使用剪枝参数来防止过拟合。
将splitter设置为random的结果
#将splitter设置为random来查看我们的训练的模型的准确率clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30#这里的splitter如果在添加之后让我们的模型的准确性更高,我们就将将这个参数保留#如果这个splitter让我们的模型准确率变低了,我们就将这个参数注释掉,splitter="random")clf = clf.fit(Xtrain, Ytrain)score = clf.score(Xtest, Ytest)score
这里树太大了,只截取了一部分
将splitter设置为best的结果
#将splitter设置为best来查看我们的训练的模型的准确率clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30#这里的splitter如果在添加之后让我们的模型的准确性更高,我们就将将这个参数保留#如果这个splitter让我们的模型准确率变低了,我们就将这个参数注释掉,splitter="best")clf = clf.fit(Xtrain, Ytrain)score = clf.score(Xtest, Ytest)score
查看我们生成的树
import graphvizdot_data = tree.export_graphviz(clf,feature_names= feature_name,class_names=["琴酒","雪莉","贝尔摩德"],filled=True,rounded=True)graph = graphviz.Source(dot_data)graph
2.剪枝参数
在不加限制的情况下,一棵决策树会生长到衡量不纯度的指标最优,或者没有更多的特征可用为止。这样的决策树往往会过拟合,这就是说,它会在训练集上表现很好,在测试集上却表现糟糕。我们收集的样本数据不可能和整体的状况完全一致,因此当一棵决策树对训练数据有了过于优秀的解释性,它找出的规则必然包含了训练样本中的噪声,并使它对未知数据的拟合程度不足。
#我们的树对训练集的拟合程度如何?score_train = clf.score(Xtrain, Ytrain)score_train
为了让决策树能够有更好的泛化性,我们要就决策树进行剪枝。剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树算法的核心。
sklearn为我们提供了不同的剪枝策略
max_depth
限制树的最大深度,超过设定深度的树枝全部剪掉
这是用得最广泛的剪枝参数,在高维度低样本量时非常有效。决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效地限制过拟合。在集成算法中也非常实用。实际使用时,建议从=3开始尝试,看看拟合的效果再决定是否增加设定深度。
min_samples_leaf & min_samples_split
min_samples_leaf限定,一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,或者,分枝会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生一般搭配max_depth使用,在回归树中有神奇的效果,可以让模型变得更加平滑。这个参数的数量设置得太小会引起过拟合,设置得太大就会阻止模型学习数据。一般来说,建议从=5开始使用。如果叶节点中含有的样本量变化很大,建议输入浮点数作为样本量的百分比来使用。同时,这个参数可以保证每个叶子的最小尺寸,可以在回归问题中避免低方差,过拟合的叶子节点出现。对于类别不多的分类问题,=1通常就是最佳选择。
min_samples_split限定,一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生。
clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random"#限定我们的树的深度只有4层,后面多余4层的部分全部都被砍掉了 ,max_depth=4#一个节点在分枝后的每个子节点都必须包含至少5个训练样本,min_samples_leaf=5#一个节点必须要包含至少10个训练样本,这个节点才允许被分枝,min_samples_split=10)clf = clf.fit(Xtrain, Ytrain)dot_data = tree.export_graphviz(clf,feature_names= feature_name,class_names=["琴酒","雪莉","贝尔摩德"],filled=True,rounded=True)graph = graphviz.Source(dot_data)graph
树太大了,只截了一部分
查看当前模型的打分结果
clf.score(Xtrain,Ytrain)
clf.score(Xtest,Ytest)
max_features & min_impurity_decrease
一般max_depth使用,用作树的”精修“ max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。和max_depth异曲同工, max_features是用来限制高维度数据的过拟合的剪枝参数,但其方法比较暴力,是直接限制可以使用的特征数量 而强行使决策树停下的参数,在不知道决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型 学习不足。如果希望通过降维的方式防止过拟合,建议使用PCA,ICA或者特征选择模块中的降维算法。
min_impurity_decrease限制信息增益(父节点和子节点的信息熵的差(子节点的信息熵一定会小于父节点的信息熵))的大小,信息增益小于设定数值的分枝不会发生。这是在0.19版本中更新的 功能,在0.19版本之前时使用min_impurity_split。
确认最优的剪枝参数 那具体怎么来确定每个参数填写什么值呢?这时候,我们就要使用确定超参数的曲线来进行判断了,继续使用我们 已经训练好的决策树模型clf。超参数的学习曲线,是一条以超参数的取值为横坐标,模型的度量指标为纵坐标的曲 线,它是用来衡量不同超参数取值下模型的表现的线。在我们建好的决策树里,我们的模型度量指标就是score。
可视化查看如何选取参数的方法
import matplotlib.pyplot as plttest = []for i in range(10):#测试最大深度为多少的时候能让我们的树的score达到最高的值clf = tree.DecisionTreeClassifier(max_depth=i+1,criterion="entropy",random_state=30,splitter="random")clf = clf.fit(Xtrain, Ytrain)score = clf.score(Xtest, Ytest)test.append(score)plt.plot(range(1,11),test,color="red",label="max_depth")plt.legend()plt.show()
class_weight & min_weight_fraction_leaf
完成样本标签平衡的参数。样本不平衡是指在一组数据集中,标签的一类天生占有很大的比例。比如说,在银行要 判断“一个办了信用卡的人是否会违约”,就是是vs否(1%:99%)的比例。这种分类状况下,即便模型什么也不 做,全把结果预测成“否”,正确率也能有99%。因此我们要使用class_weight参数对样本标签进行一定的均衡,给 少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。该参数默认None,此模式表示自动给 与数据集中的所有标签相同的权重。 (你在倒入决策树的时候,你什么都不写的话,class_weight会自动帮你调整不平衡,使其为1:1,)
有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配min_ weight_fraction_leaf这个基于权重的剪枝参数来使用。另请注意,基于权重的剪枝参数(例如min_weight_ fraction_leaf)将比不知道样本权重的标准(比如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使 用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重的总和的一小部分。
3.重要的属性和接口
属性是在模型训练之后,能够调用查看的模型的各种性质。对决策树来说,最重要的是feature_importances_,能够查看各个特征对模型的重要性。
sklearn中许多算法的接口都是相似的,比如说我们之前已经用到的fit和score,几乎对每个算法都可以使用。除了这两个接口之外,决策树最常用的接口还有apply和predict。apply中输入测试集返回每个测试样本所在的叶子节点的索引,predict输入测试集返回每个测试样本的标签。
在这里不得不提的是,所有接口中要求输入X_train和X_test的部分,输入的特征矩阵必须至少是一个二维矩阵。sklearn不接受任何一维矩阵作为特征矩阵被输入。如果你的数据的确只有一个特征,那必须用reshape(-1,1)来给矩阵增维;如果你的数据只有一个特征和一个样本,使用reshape(1,-1)来给你的数据增维。
#只需要输入测试集的特征#apply返回每个测试样本所在的叶子节点的索引clf.apply(Xtest)
#只需要输入测试集的特征#predict返回每个测试样本的分类/回归结果clf.predict(Xtest)
如果觉得《【机器学习笔记】【决策树】【分类树】》对你有帮助,请点赞、收藏,并留下你的观点哦!