• 概念:决策树(Decision Tree)是一种非参数的有监督学习方法,它能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题。

    image.png
    例如有上面这一张是否是哺乳动物的分类表,决策树能够根据这张表进行分类操作,如下图:
    image.png
    假如我们现在发现了一种新物种Python,它是冷血动物,体表带鳞片,并且不是胎生,我们就可以通过这棵决策树来判断它的所属类别。

    • 决策树的经典代表算法 - ID3算法

      决策树的原理的可解释性非常强,很多算法也比较简单,我们先来看最经典的决策树代表算法 - ID3算法

      在划分数据集之前之后信息发生的变化称为信息增益,知道如何计算信息增益,我们就可以计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。

      这里又引入了另一个概念——熵。这里先不展开说了,我们记住他的概念:一个事情它的随机性越大就越难预测,公式为: image.png 具体来说这个概率p越小,最后熵就越大(也就是信息量越大),如果极端情况一件事情概率为1,它的熵就变成0了。比如,你如果能预测一个彩票的中奖号码就发达了。但是,如果你能预测明天太阳从东边升起来则毫无价值。这样衡量一个信息价值的事,就可以由熵来表示。

      聪明的你或许已经发现了,决策树算法其实就是为了找到能够迅速使熵变小,直至熵为0的那条路径,这就是信息增益的那条路。我们将对每个特征划分数据集的结果计算一次信息熵,然后判断按照哪个特征划分数据集是最好的划分方式。

      举个容易理解的例子: 解决问题:预设4个自变量:天气、温度、湿度、风速,预测学校会不会举办运动会? 步骤一:假设我们记录了某个学校14届校运会按时举行或取消的记录,举行或者取消的概率分别为:9/14、5/14,那么它的信息熵,这里也叫先验熵,为: 步骤二:我们同时记录了当天的天气情况,发现天气好坏和校运会举行还是取消有关。14天中,5次晴天(2次举行、3次取消)、5次雨天(3次举行、2次取消)、4次阴天(4次举行)。相对应的晴天、阴天、雨天的后验熵。 image.png 步骤三:我们计算知道天气情况后的条件熵。 步骤四:我们计算在有没有天气情况这个条件前后的信息增益就是。 步骤五:我们依次计算在有没有温度、湿度、风速条件前后的信息增益。 步骤六:根据设置的阈值,若信息增益的值大于设置的阈值,选取为我们的特征值,也就是我们上图中的矩形节点。 步骤七:生成决策树。选取信息增益最大的自变量作为根节点。其他的特征值依次选取为内部节点。 比如上面的例子是这样的过程: image.png 经过如上步骤,我们得到决策树。可以看到,最终们只选取了3个特征值作为内部节点。 image.png

    • 决策树算法的核心是要解决两个问题:

    1)如何从数据表中找出最佳节点和最佳分枝?
    2)如何让决策树停止生长,防止过拟合(决策树是天生过拟合的模型)?

    首先先解释什么为过拟合:
    在给你一组数据的时候,我们通常希望能够分出一些数据作为训练集,训练出能够进行工作的模型,比如上方例子中建立一棵决策树就是模型从训练集进行训练出来的,用来分类的模型,我们还需要分出一些数据做测试集,来检测我们的模型的准确度(预测值和真实值的差异)为多少。而过拟合就是模型在训练集上的表现很好,却在模型的测试集上表现很糟糕,这种泛化能力比较差的现象就是过拟合。

    1. #通常来说,训练集上的分数不要和测试集上的分数差太多
    2. rfc.score(Xtrain,train)
    3. rfc.score(Xtest,YTest)
    • 决策树有五种类型(前两种的使用比较多):

    image.png

    • CART决策树的重要参数
    1. criterion:不纯度,是衡量构建决策树优劣的重要指标,不纯度越低,决策树对训练集的拟合越好。
      输入”entropy“,使用信息熵(Entropy) 输入”gini“,使用基尼系数(Gini Impurity),默认基尼系数

    image.png
    注:其中t代表给定的节点,i代表标签的任意分类, 代表标签分类i在节点t上所占的比例。当使用信息熵时,sklearn实际计算的是基于信息熵的信息增益(Information Gain),即父节点的信息熵和子节点的信息熵之差。比起基尼系数,信息熵对不纯度更加敏感,对不纯度的惩罚最强。所以信息熵作为指标时,决策树的生长会更加“精细”,因此对于高维数据或者噪音很多的数据,信息熵很容易过拟合,基尼系数在这种情况下效果往往比较好。

    1. random_state:random_state用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显,低维度的数据 (比如鸢尾花数据集),随机性几乎不会显现。输入任意整数,会一直长出同一棵树,让模型稳定下来(便于模型的调参)。

    2. plitter:也是用来控制决策树中的随机选项的,有两种输入值,一种是”best”,优先选择更重要的特征进行分枝,另一种是”random”,随机分枝,这个参数一定程度上也可以防止过拟合,默认best。

    3. max_depth:限制树的最大深度,超过设定深度的树枝全部剪掉(剪枝神器)。

    4. min_samples_leaf:限定,一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,默认=1。

    5. min_samples_split最小训练样本数,一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,默认=2。

    6. max_features:限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。(一般不用,因为太过于暴力,如果希望通过降维的方式防止过拟合,建议使用PCA,ICA或者特征选择模块中的降维算法。)

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

      1. clf = tree.DecisionTreeClassifier(criterion="entropy"#entropy:不纯度的英文,采用的方法
      2. ,random_state=30#random_state:随机模式固定,防止结果跳动
      3. ,splitter="random")#splitter:选“best”则选择更重要的生成决策树,选“random”则更随机生成,防止过拟合
      4. clf = clf.fit(Xtrain, Ytrain) #fit:训练的接口
      5. score = clf.score(Xtest, Ytest) #返回预测的准确度
    • **重要属性和接口决策树最常用的接口还有apply和predict。apply中输入测试集返回每个测试样本所在的叶子节点的索引,predict输入测试集返回每个测试样本的标签。注意,所有接口中要求输入X_train和X_test的部分,输入的特征矩阵必须至少是一个二维矩阵,sklearn不接受任何一维矩阵作为特征矩阵被输入。
      1. #apply返回每个测试样本所在的叶子节点的索引
      2. clf.apply(Xtest)
      3. #predict返回每个测试样本的分类/回归结果
      4. clf.predict(Xtest)
      决策树的重要属性有featureimportances,用来查看特征的重要性(返回一个小数,小数越高特征越重要)
      1. [*zip(feature_name,clf.feature_importances_)]#一一对应,根节点对于决策树的贡献永远是最大的
    • 回归树的新参数
    1. criterion回归树衡量分枝质量的指标,支持的标准有三种
      • mean squared error(MSE):输入”mse”使用均方误差mean squared error(MSE),父节点和叶子节点之间的均方误差的差额将被用来作为特征选择的标准,这种方法通过使用叶子节点的均值来最小化L2损失。
      • 费尔德曼均方误差:输入“friedman_mse”使用费尔德曼均方误差,这种指标使用弗里德曼针对潜在分枝中的问题改进后的均方误差。
      • 绝对平均误差MAE(mean absolute error):输入”mae”使用绝对平均误差MAE(mean absolute error),这种指标使用叶节点的中值来最小化L1损失。

    注意:回归树的接口score默认返回的是R平方,并不是MSE
    R平方可以为正为负(如果模型的残差平方和远远大于 模型的总平方和,模型非常糟糕,R平方就会为负),而均方误差永远为正。

    小知识:虽然均方误差永远为正,但是sklearn当中使用均方误差作为评判标准时,却是计算”负均方误差“(neg_mean_squared_error)。这是因为sklearn在计算模型评估指标的时候,会考虑指标本身的性质,均 方误差本身是一种误差,所以被sklearn划分为模型的一种损失(loss),因此在sklearn当中,都以负数表示。真正的 均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字。