机器学习之决策树和随机森林及代码示例

一、决策树

决策树学习是机器学习中一类常用的算法。在决策树中,根节点包含样本全集。每个非叶子节点表示一种对样本的分割,通常对应一个划分属性,其将样本分散到不同的子节点中。每个叶子节点对应于决策的结果。因此从根节点到每个叶子节点的路径对应了一个判定序列。

可与下图做比对:

《机器学习之决策树和随机森林及代码示例》

在上图的决策树中,划分属性有年龄、是否为学生、信用率。

划分属性一般采用样本的某个特征或多个特征的组合。

决策树学习是一种有监督学习,根据样本为基础,自顶向下通过递归的方法来对样本进行划分属性。其基本思想是以 信息熵 为度量来构造一棵熵值下降最快的树,直到叶子节点处的熵值为0。

二、信息熵

1. 定义

“信息熵”是度量样本集合纯度最常用的一种指标。假定在当前样本集合D中有k类样本(样本的标签有k类),其中第i类样本所占样本集合的比例为pi(i = 1,2,…..,k),则样本集合D的信息熵可定义为

《机器学习之决策树和随机森林及代码示例》

(熵:Entropy)

2. 信息熵与纯度的关系

由信息熵的公式,我们可以看出,当样本集合中只存在一类样本时,k=1,p1=1,这时信息熵Ent(D)的值为0;当样本集合存在2类样本时,若每类样本的概率为1/2,这时信息熵Ent(D)的值为1;…… 当信息熵Ent(D)的值越,则样本集合D的纯度越

若我们需要的决策树是以 信息熵 为度量来构造一棵样本的熵值下降最快、结点纯度越来越高的树。那我们怎么对样本集合分割?如何选择我们的最优划分属性(特征)来作为我们分割样本集合时的非叶子节点?

于此,我们需要对样本的各个特征进行度量,选出当前最好的划分属性作为树的分隔结点,使得我们的分类最纯。

通常的度量方法有如下方法:

  • 信息增益(ID3)

  • 信息增益率(C4.5)

  • 基尼系数(CART)

三、信息增益

1. 单个分支的信息熵

若样本中有一个离散特征《机器学习之决策树和随机森林及代码示例》 ,其有k个可能的取值 《机器学习之决策树和随机森林及代码示例》。若我们使用特征 《机器学习之决策树和随机森林及代码示例》 作为决策树的分隔结点对样本集合D进行划分,则会产生 k 个分支节点。

在这k个分支节点中,第 i 个分支节点包含样本集合D中所有属性 《机器学习之决策树和随机森林及代码示例》 上取值为 《机器学习之决策树和随机森林及代码示例》 的样本。我们将第 i 个分支节点的样本集记作 《机器学习之决策树和随机森林及代码示例》

我们可以根据 信息熵 的公式计算出 《机器学习之决策树和随机森林及代码示例》 的信息熵为 《机器学习之决策树和随机森林及代码示例》

2. 所有分支的信息熵的加权

同理,我们可以得到其他分支的信息熵。因此,可算出特征 《机器学习之决策树和随机森林及代码示例》 划分后所有分支的样本集合的 信息熵 的加权为 《机器学习之决策树和随机森林及代码示例》

其中 |D| 表示样本集合D中的样本个数,|Di| 表示 第 i 个分支的样本集合的样本个数。

由上可得到未划分前的样本集合D的信息熵 《机器学习之决策树和随机森林及代码示例》 和 根据样本特征 《机器学习之决策树和随机森林及代码示例》 所划分后的所有分支样本集合的信息熵的加权 《机器学习之决策树和随机森林及代码示例》

3. 信息增益

因此,我们将划分前后的信息熵之差作为我们所说的“信息增益”,因此其公式为 《机器学习之决策树和随机森林及代码示例》
其中 《机器学习之决策树和随机森林及代码示例》 为划分样本集合的某个特征。

一般而言,信息增益越大,则意味着信息熵下降越快,分支的样本集合纯度越高。

因为我们的决策树需要熵值下降最快,因此我们要选择的最优划分属性为 《机器学习之决策树和随机森林及代码示例》,其中 ai为用于划分样本集合D的第i个特征。

但我们会发现,当某个特征的分支很多(特征的值分得较细,比如日期)时,分支节点样本集合的纯度会很大,所有分支样本集合的信息熵的权重和《机器学习之决策树和随机森林及代码示例》 会变得很小,导致信息增益会变得很大。因而 信息增益 对 分支比较多的特征 有所偏爱,有时会出现过拟合的现象。

四、信息增益率(比)

1. 定义

为减少信息增益的偏好可能带来的不好影响,可以使用“信息增益率/比”来选择最优的划分特征。

采用与上面同样的符号,信息增益率的定义为 《机器学习之决策树和随机森林及代码示例》

其中 分子为 以特征 《机器学习之决策树和随机森林及代码示例》 作为分隔节点时的信息增益。分母 《机器学习之决策树和随机森林及代码示例》 称为特征《机器学习之决策树和随机森林及代码示例》 的“固有值”(intrinsic value)。

2. 特征的固有值

特征的固有值定义为: 《机器学习之决策树和随机森林及代码示例》 。其中 k 为特征 《机器学习之决策树和随机森林及代码示例》 的可能取值数目,即可将样本集合D划分为k个分支节点。其中 |D| 表示样本集合D中的样本个数,|Di| 表示 第 i 个分支的样本集合中的样本个数。(个人理解为特征的纯度)

当特征 《机器学习之决策树和随机森林及代码示例》 可能的取值越多时,其特征的固有值通常会很大,导致信息增益率会变小,在一定程度上解决了信息增益偏好分支多的特征带来的问题。但需注意的是,信息增益率在某种程序上可能对可取值数目较少的属性有所偏好。

五、基尼值

1. 定义

样本集合D的纯度除了使用信息熵来定义,也可以使用基尼值来度量。

样本集合D的纯度可用基尼值来度量:《机器学习之决策树和随机森林及代码示例》

若在当前样本集合D中标签有k类,其中第 i 类样本所占样本集合的比例为Pi(i = 1,2,…..,k)

从公式可以看出,《机器学习之决策树和随机森林及代码示例》 反映了从样本集合D中随机抽取两个样本,其类别标记不一致的概率(一个为pi,另一个为(1- pi))。

因此,基尼值 《机器学习之决策树和随机森林及代码示例》,则样本集合D的纯度越

2. 所有分支的基尼值的加权

同理,对于样本中的某一个离散特征 《机器学习之决策树和随机森林及代码示例》 ,其有k个可能的取值 《机器学习之决策树和随机森林及代码示例》。若我们使用特征 《机器学习之决策树和随机森林及代码示例》 对样本集合D进行划分,则会产生 k 个分支子节点。

那我们可以得到,由样本特征《机器学习之决策树和随机森林及代码示例》 所划分后的分支样本集合的基尼值的加权为 《机器学习之决策树和随机森林及代码示例》 。其中 k 为特征 《机器学习之决策树和随机森林及代码示例》 的可能取值数目,可将样本集合D划分为k个分支节点。

其中 |D| 表示样本集合D中的样本个数,|Di| 表示 第 i 个分支的样本集合中的样本个数。

为使生成的决策树分类最纯,因此我们根据 基尼值 的方法要选择的最优划分属性为 《机器学习之决策树和随机森林及代码示例》 ,其中 ai为用于划分样本集合D的第i个特征。

六、决策树的剪枝

1. 完整树的问题

决策树对训练样本具有很好的分类能力。而一棵对样本完全分类的决策树(完整树),对未知的测试数据未必有很好的预测能力,泛化能力较差,容易出现过拟合现象。

完整树:决策树T的每个叶子节点的样本集合中的样本都为同一类型。

过拟合会导致构建出过于复杂的决策树,为解决这个问题,可以通过剪枝的方法来简化已生成的决策树,即将某个划分属性的节点的分支减掉,并将该节点作为一个某个决策结果的叶子节点(对应的决策结果可采用占多数的样本标记)。那怎么判断某个划分属性的节点是否需要剪枝呢?(剪枝在于减少叶子节点的数量)

2. 剪枝的算法

因而,我们需要设计一个分类误差评估函数,然后通过极小化决策树整体的损失函数实现剪枝。

设决策树 T 有 n 个叶子节点,设第t个叶子节点的样本集合Dt有Nt个样本,这些样本的标记类别不一定相同,假设样本集合Dt中的样本有k种标记类别,第i种类别的样本有Nti个。

那么,第t个叶子节点的样本集合的经验熵 《机器学习之决策树和随机森林及代码示例》定义为:《机器学习之决策树和随机森林及代码示例》

可以看出,当第t个叶子节点的样本集合只有一种标记类型时,经验熵为0。

下面给出我们的决策树 T 的损失函数的定义:《机器学习之决策树和随机森林及代码示例》。其中n为叶子节点数,也可以用|T|来表示,α为经验值参数(α≥0)。

C(T)表示决策树对训练数据的预测误差,参数α控制两者之间的影响,α越大,要求模型越简单,α=0表示不考虑模型的复杂度(即可以产生较多的叶子节点)。

剪枝的过程,就是当α确定时,选择损失函数最小的模型。分类越细,叶子节点的经验熵就越小,C(T)越小,但是由于分类越细会导致叶子节点的数目会很多,α|T|(或αn)越大。损失函数反映的是两者的平衡。

决策树的生成过程只考虑了样本集合分类的纯度,只考虑更好地拟合训练数据,而剪枝过程在于减小整体的复杂度。

决策树的剪枝算法:固定某个经验值α,对划分属性的结点进行剪枝预估,若剪枝后,决策树损失函数减小了,则减掉该结点的叶节点,将该结点作为新的叶节点,该结点对应的决策结果可以为其样本集合中占多数的样本标记。(或构造不同的α值得到一些备选树,通过交叉验证的方法得到最优树)

七、随机森林

1. Bagging

Bootstrap:一种有放回的抽样方法。

Bagging( bootstrap aggregation)的策略:从样本集中进行有放回地选出n个样本;在样本的所有特征上,对这n个样本建立分类器;重复上述两步m次,获得m个样本分类器;最后将测试数据都放在这m个样本分类器上,最终得到m个分类结果,再从这m个分类结果中决定数据属于哪一类(多数投票制)。

2. 随机森林

随机森林采用了Bagging策略,且在其基础上进行了一些修改,采用了两个随机:

  1. 从训练样本集中使用Bootstrap采样(随机有放回)选出n个样本。

  2. 设样本共有b个特征,从这b个特征中只随机选择k个特征来分割样本,通过计算选择最优划分特征作为节点来划分样本集合来建立决策树。(与Bagging的不同之处:没有使用全部的特征,这样可以避免一些过拟合的特征,不再对决策树进行任何剪枝)

  3. 重复以上两步m次,可建立m棵决策树

  4. 这m棵决策树形成了森林,可通过简单多数投票法(或其他投票机制)来决定森林的输出,决定属于哪一类型。(针对解决回归问题,可以采用单棵树输出结果总和的平均值)

随机森林在一定程序上提高了泛化能力,而且可以并行地生成单棵树。

八、代码示例

使用决策树和随机森林进行手写数字(sklearn中的digits数据)的预测:

from sklearn import datasets
digits = datasets.load_digits();

X = digits.data // 特征矩阵
y = digits.target // 标签矩阵
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3., random_state=8) // 分割训练集和测试集
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
estimators = {}

# criterion: 分支的标准(gini/entropy)
estimators['tree'] = tree.DecisionTreeClassifier(criterion='gini',random_state=8) # 决策树

# n_estimators: 树的数量
# bootstrap: 是否随机有放回
# n_jobs: 可并行运行的数量
estimators['forest'] = RandomForestClassifier(n_estimators=20,criterion='gini',bootstrap=True,n_jobs=2,random_state=8) # 随机森林
from sklearn.model_selection import cross_val_score
import datetime

for k in estimators.keys():
    start_time = datetime.datetime.now()
    print '----%s----' % k
    estimators[k] = estimators[k].fit(X_train, y_train)
    pred = estimators[k].predict(X_test)
    print pred[:10]
    print("%s Score: %0.2f" % (k, estimators[k].score(X_test, y_test)))
    scores = cross_val_score(estimators[k], X_train, y_train,scoring='accuracy' ,cv=10)
    print("%s Cross Avg. Score: %0.2f (+/- %0.2f)" % (k, scores.mean(), scores.std() * 2))
    end_time = datetime.datetime.now()
    time_spend = end_time - start_time
    print("%s Time: %0.2f" % (k, time_spend.total_seconds()))
----tree----
[6 2 1 5 0 9 0 1 8 7]
tree Score: 0.84
tree Cross Avg. Score: 0.84 (+/- 0.08)
tree Time: 0.22
----forest----
[6 2 1 5 0 9 0 1 1 6]
forest Score: 0.97
forest Cross Avg. Score: 0.96 (+/- 0.04)
forest Time: 3.87

可看出来随机森林比决策树更强大一些,但随机森林需要构造多颗树,花费的时间比较多

    原文作者:数据挖掘
    原文地址: https://juejin.im/entry/58a80de7128fe100648d6fc0
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞