sklearn-决策树

机器学习的集成工具sklearn,这里主要对决策树中的分类树使用进行说明。
视频讲解

class sklearn.tree.DecisionTreeClassifier (criterion=’gini’, splitter=’best’, max_depth=None,
min_samples_split=2,min_samples_leaf=1,min_weight_fraction_leaf=0.0,max_features=None,random_state=None,max_leaf_nodes=None,min_impurity_decrease=0.0,min_impurity_split=None,class_weight=None,presort=False)

sklearn建模基本流程:

  1. 实例化,建立评估模型对象
  2. 通过模型接口训练模型
  3. 通过模型接口提取需要的信息
from sklearn import tree
clf=tree.DescisionTreeClassifier()                       #实例化建模对象
clf=clf.fit(x_train,y_train)                            #用训练集训练模型
result=clf.score(x_test,y_test)                         #导入测试集,从接口中调用需要的信息

小项目实践

重要参数

criterion
未来将表格转化为一棵树,决策树需要找出最佳节点和最佳分支方法,对于分类树来说衡量这种分支选择好坏的称作“不纯度”,不纯度越低决策树的拟合效果越好。不纯度是基于结点计算的,树中的每个节点都有个不纯度,子节点的不纯度一定低于父节点的不纯度,在同一棵决策树上叶子节点的不纯度一定是最低的。
criterion是用来决定不出度计算方法的,sklearn提供了两种计算方法:
sklearn-决策树_第1张图片
sklearn-决策树_第2张图片
sklearn-决策树_第3张图片
这里开始使用决策树进行简单的实践,采用sklearn中的红酒数据集。

#导入相应的模块
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
#数据集探索
wine=load_wine()
wine.data.shape
wine.target
#如果数据集是一张表,则应该这样操作
import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)  #将数据集的特征值和标签值进行连接,因为在列的维度上连接,所以axis=1.

sklearn-决策树_第4张图片

#得到数据集的特征标签
wine.feature_names
#得到数据集的目标值标签
wine.target_names
#对训练数据集进行划分,分为训练集和验证集
Xtrain,Xtest,Ytrain,Ytest=train_test_split(wine.data,wine.target,test_size=0.3)   #test_size规定验证集所占的比重
Xtrain.shape           #观察训练集的大小
wine.data.shape   #观察总数据集的大小
#决策树模型的构建
clf=tree.DecisionTreeClassifier(criterion="entropy")     #采用熵进行构建
clf=clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)       #得出分类的准确率
score

0.9074074074074074
#探寻每个特征值的重要性
clf.feature_importances_
[*zip(feature_name,clf.feature_importances_)]
[('酒精', 0.0),
 ('苹果酸', 0.021292049628603066),
 ('灰', 0.0),
 ('灰的碱性', 0.0),
 ('镁', 0.0),
 ('总酚', 0.0),
 ('类黄酮', 0.44736728516836155),
 ('非黄烷类酚类', 0.0),
 ('花青素', 0.0),
 ('颜色强度', 0.16982636821321825),
 ('色调', 0.0),
 ('od280/od315稀释葡萄酒', 0.014200239145886785),
 ('脯氨酸', 0.3473140578439304)]

由结果可看出不同的特征值的重要性不同,重要性为0的特征值其去掉对决策树无影响。
我们已经在只了解一个参数的情况下,建立了一棵完整的决策树。但是回到建立模型,score会在某个值附近波动, 引起画出来的每一棵树都不一样。它为什么会不稳定呢?如果使用其他数据集,它还会不稳定吗?我们之前提到过,无论决策树模型如何进化,在分枝上的本质都还是追求某个不纯度相关的指标的优化,而正如我们提到的,不纯度是基于节点来计算的,也就是说,决策树在建树时,是靠优化节点来追求一棵优化的树,但最优的节点能够保证最优的树吗?集成算法被用来解决这个问题:sklearn表示,既然一棵树不能保证最优,那就建更多的不同的树,然后从中取最好的。怎样从一组数据集中建不同的树?在每次分枝时,不从使用全部特征,而是随机选取一部分特征,从中选取不纯度相关指标最优的作为分枝用的节点。这样,每次生成的树也就不同了。

#random_state参数
clf=tree.DecisionTreeClassifier(criterion="entropy",random_state=25)
clf=clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
score

0.9074074074074074              #这时不管运行多少次最终结果都不会改变,相当与在多个决策树中选取了最优的那棵

random_state &splitter
random_state用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显,低维度的数据(比如鸢尾花数据集),随机性几乎不会显现。输入任意整数,会一直长出同一棵树,让模型稳定下来。
splitter也是用来控制决策树中的随机选项的,有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看),输入“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。这也是防止过拟合的一种方式。当你预测到你的模型会过拟合,用这两个参数来帮助你降低树建成之后过拟合的可能性。当然,树一旦建成,我们依然是使用剪枝参数来防止过拟合。

clf=tree.DecisionTreeClassifier(criterion="entropy",random_state=25,splitter="best")
clf=clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
score

0.9074074074074074

添加该参数增加特征选择的随机性后发现效果没变了,这说明该数据集模型不适合该参数,参数的选择需要在实际中自己尝试。
剪枝参数
在不加限制的情况下,一棵决策树会生长到衡量不纯度的指标最优,或者没有更多的特征可用为止。这样的决策树往往会过拟合,这就是说,它会在训练集上表现很好,在测试集上却表现糟糕。我们收集的样本数据不可能和整体的状况完全一致,因此当一棵决策树对训练数据有了过于优秀的解释性,它找出的规则必然包含了训练样本中的噪声,并使它对未知数据的拟合程度不足。这就是所谓的过拟合现象。

#我们的树对训练集的拟合程度如何?
score_train = clf.score(Xtrain, Ytrain)
score_train
1.0      

结果发现完全拟合训练集,其实这就是过拟合现象,但发现在验证集上准确率也不错,说明这其实是一个不错的模型,但接下来将要进行防止过拟合的剪枝操作。
剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树算法的核心。 sklearn提供了不同的剪枝策略。
max_depth
限制树的最大深度,超过设定深度的树枝全部剪掉这是用得最广泛的剪枝参数,在高维度低样本量时非常有效。决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效地限制过拟合。在集成算法中也非常实用。实际使用时,建议从=3开始尝试,看看拟合的效果再决定是否增加设定深度。
min_samples_leaf & min_samples_split
min_samples_leaf限定,一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,或者,分枝会朝着满足每个子节点都包含min_sample_leaf个样本的方向去发生。一般搭配max_depth使用,在回归树中有神奇的效果,可以让模型变得更加平滑。这个参数的数量设置得太小会引起过拟合,设置得太大就会阻止模型学习数据。一般来说,建议从=5开始使用。对于类别不多的分类问题,=1通常是最佳选择。
min_samples_split限定,一个结点必须包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生。

clf=tree.DecisionTreeClassifier(criterion="entropy",random_state=25,splitter="best",max_depth=3,
                                min_samples_leaf=3,min_samples_split=3)
clf=clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
print("the accuracy of test:")
print(score)
train_score=clf.score(Xtrain,Ytrain)
print("the acuracy of train:")
print(train_score)

the accuracy of test:
0.9259259259259259
the acuracy of train:
0.9838709677419355

添加剪枝操作后发现模型效果提升了,说明剪枝起到了作用,减小了过拟合现象,增强了模型的泛化性。
max_features & min_impurity_decrease
一般max_depth使用,用作树的”精修“
max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。和max_depth异曲同工,**max_features是用来限制高维度数据的过拟合的剪枝参数,**但其方法比较暴力,是直接限制可以使用的特征数量而强行使决策树停下的参数,在不知道决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型学习不足。如果希望通过降维的方式防止过拟合,建议使用PCA,ICA或者特征选择模块中的降维算法。
min_impurity_decrease限制信息增益的大小,信息增益小于设定数值的分枝不会发生。这是在0.19版本种更新的功能,在0.19版本之前时使用。
一般情况下只要设置前面的剪枝参数就可以完成大部分的机器学习操作,后面的这几个采取默认值即可。
重要属性接口
属性是在模型训练之后,能够调用查看的模型的各种性质。对决策树来说,最重要的feature_importances_,能够查看各个特征对模型的重要性。
sklearn中许多算法的接口都是相似的,比如说我们之前已经用到的fit和score,几乎对每个算法都可以使用。除了这两个接口之外,决策树最常用的接口还由apply和predict。apply中输入测试集返回每个测试样本所在的叶子节点的索引,predict输入测试集返回每个测试样本的标签。

#apply返回每个测试样本所在的叶子节点的索引
clf.apply(Xtest)
#predict返回每个测试样本的分类/回归结果
clf.predict(Xtest)
array([10,  9, 10, 10, 10,  2,  4,  2,  2, 10,  2,  4, 10,  4,  5,  2, 10,
        4,  9,  2,  4, 10,  5,  8,  4,  2,  4,  4, 10, 10, 10,  4,  4, 10,
        4, 10, 10,  2,  4,  2,  4,  8,  9,  4,  2,  4, 10,  2,  9,  9,  4,
        2,  2, 10], dtype=int64)
array([0, 1, 0, 0, 0, 1, 2, 1, 1, 0, 1, 2, 0, 2, 1, 1, 0, 2, 1, 1, 2, 0,
       1, 1, 2, 1, 2, 2, 0, 0, 0, 2, 2, 0, 2, 0, 0, 1, 2, 1, 2, 1, 1, 2,
       1, 2, 0, 1, 1, 1, 2, 1, 1, 0])

你可能感兴趣的:(sklearn)