sklearn-DecisionTreeClassifier


sklearn-DecisionTreeClassifier的基本用法

决策树的流程

计算全部特征的不纯度,选取不纯度指标最优的特征来分支,在第一个特征的分支下,计算全部特征的不纯度指标,选取不纯度指标最优的特征继续分支

DecisionTreeClassifier的核心参数:criterion

为了要将表格转化为一棵树,决策树需要找出最佳节点和最佳的分枝方法,对分类树来说,衡量这个“最佳”的指标
叫做“不纯度”。通常来说,不纯度越低,决策树对训练集的拟合越好。现在使用的决策树算法在分枝方法上的核心
大多是围绕在对某个不纯度相关指标的最优化上。

  • entropy 信息熵
  • gini 基尼系数

建树

1.导入需要的算法库和模块

from sklearn import tree    
from sklearn.datasets import load_wine    
from sklearn.model_selection import train_test_split      

2.探索数据

wine = load_wine()                  #将数据库中的练习数据导入       
wine.data.shape                     #获取数据结构——178行,13列,即13个特征
>(178,13)     


wine.target                         #因为wine是一个字典,所以我们可以通过键来获取对于的值     
>array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
      2, 2])
import pandas as pd
pd.concat([pd.DataFrame(wine.data), pd.DataFrame(wine.target)], axis=1)        #将数据和标签都传入pd.DataFrame,生成表格,更方便的查看数据结构                              

在这里插入图片描述

wine.feature_names                  #查看特征名              
>['alcohol',
'malic_acid',
'ash',
'alcalinity_of_ash',
'magnesium',
'total_phenols',
'flavanoids',
'nonflavanoid_phenols',
'proanthocyanins',
'color_intensity',
'hue',
'od280/od315_of_diluted_wines',
'proline']                
wine.targets_names                #查看标签名
>array(['class_0', 'class_1', 'class_2'], dtype='<U7')           

3.将数据划分为训练集和测试集

Xtrain,Xtest,Ytrain,Ytest = train_test_split(wine.data, wine.target, test_size=0.3) 
#给出数据和标签,test_size是指30%做测试集,剩下的70%做训练集
Xtrain.shape
>(124, 13)

Xtest.shape
>(54, 13)

查看数据结构,确认原始数据已经被分成70%和30%两部分



建模三部曲

第一步: 实例化

clf = tree.DecisionTreeClassifier(criterion="entropy")     #criterion 默认是基尼系数,此处我们选择使用信息熵

第二部: 训练模型

clf = clf.fit(Xtrain, Ytrain)

第三步: 打分

score = clf.score(Xtest, Ytest)   #用测试集来打分,返回的是一个准确度accuracy                 
                       
score                 
>>0.9259259259259259              #在此处每次打分的结果都可能不一样


画图

feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
import graphviz
dot_data = tree.export_graphviz(clf, 
                               feature_names=feature_name, 
                               class_names=['琴酒','雪莉', '贝尔摩德'], 
                               filled=True, 
                               rounded=True
)
#   分别传入模型 clf ;特征名 ; 标签名
#   filled表示是否填充颜色,不纯度越低,颜色越深
#   rounded表示方框的圆度
graph = graphviz.Source(dot_data)
graph

在这里插入图片描述

接下来查看我们感兴趣的数值,并针对性的分析

clf.feature_importances_             #虽然返回了数值,但是看不懂,需要连接前面的特征       
>>array([0.        , 0.        , 0.        , 0.01424694, 0.        ,
        0.        , 0.47329119, 0.        , 0.02568071, 0.31227528,
        0.        , 0.        , 0.17450589])

# 此处返回的是特征值的权重
[*zip(feature_name, clf.feature_importances_)]      #用 *zip 连接特征名和对于数值
>>[('酒精', 0.0),
('苹果酸', 0.0),
('灰', 0.0),
('灰的碱性', 0.01424693586672224),
('镁', 0.0),
('总酚', 0.0),
('类黄酮', 0.4732911864435072),
('非黄烷类酚类', 0.0),
('花青素', 0.02568070945422599),
('颜色强度', 0.31227528031774815),
('色调', 0.0),
('od280/od315稀释葡萄酒', 0.0),
('脯氨酸', 0.17450588791779637)]

可以看到 类黄酮 的数值最高,所以在决策树的顶端作为根结点

模型的分值随机变化,那么我们如何获得稳定的模型呢?

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

score
>>0.8888888888888888

在模型中加入random_state参数控制模型,使模型稳定,数值本身通过调试选择合适值;如果加入splitter=“random”可以让模型更加随机,从而防止过拟合,适用于特征值相当大的时候。

可以说 criterion 用来规定不纯度的计算,random_statesplitter用来控制决策树的随机度


最后我们对训练集的拟合程度怎么样呢?

score_train = clf.score(Xtrain,Ytrain)         
             
score_train            
>>1.0               

因为训练集的精准度在92%,所以虽然我们测试集的打分是满分,也是正常现象。如果训练集打分只有80%,则考虑模型过拟合。



剪枝策略-剪枝参数调优

剪枝策略对决策树有巨大的影响,正确的剪枝策略是优化决策树算法的核心。

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个训练样本,这个节点才允许被分枝,否则 分枝就不会发生。

max_features & min_impurity_decrease

一般max_depth使用,用作树的”精修“
max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。和max_depth异曲同工,max_features是用来限制高维度数据的过拟合的剪枝参数,但其方法比较暴力,是直接限制可以使用的特征数量而强行使决策树停下的参数,在不知道决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型学习不足。如果希望通过降维的方式防止过拟合,建议使用PCA,ICA或者特征选择模块中的降维算法。

min_impurity_decrease限制信息增益的大小,信息增益小于设定数值的分枝不会发生。

>clf = tree.DecisionTreeClassifier(criterion="entropy"
                                  ,random_state=20
                                  ,splitter='random'
                                  ,max_depth=4
                             #    ,min_samples_leaf=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     
score_train = clf.score(Xtrain,Ytrain)

score_train
>>0.9758064516129032

可以看出通过剪枝后的模型,比原来分值更高


那么如何确定最优的剪枝参数呢?

使用确定超参数的曲线来进行判断,继续使用我们已经训练好的决策树模型clf。超参数的学习曲线,是一条以超参数的取值为横坐标,模型的度量指标为纵坐标的曲线,它是用来衡量不同超参数取值下模型的表现的线。在我们建好的决策树里,我们的模型度量指标就是score。

import matplotlib.pyplot as plt
test = []
for i in range(10):
   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()

在这里插入图片描述
图中可得当 max_depth=4时最优

猜你喜欢

转载自blog.csdn.net/weixin_45044758/article/details/107339804