机器学习:决策树

本文详细介绍了决策树的学习算法,包括ID3、C4.5和CART。ID3算法利用信息增益选择划分属性,C4.5通过信息增益率克服ID3的偏好,而CART则是基于基尼指数。文章还涵盖了剪枝、连续属性离散化等关键概念,并提供了Python代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


决策树是很好理解的,如下图。
图片源自维基百科
构造决策树的关键是找到最优划分属性,这个过程中需要解决两个基本问题:

  • 【选择划分属性】若样本有N个属性,那么有 N ! N! N!种属性划分的情况,采用穷举法是不可接受的;
  • 【判定准则】需要有一种指标来判断属性划分的好坏。

然后还需要解决一些其它问题:

  • 连续属性离散化
  • 剪枝

公式符号约定

为了便于讨论,有必要统一公式语言,这里采用西瓜书中的公式语言。

样本集合为 D D D D D D的信息熵为 Ent ⁡ ( D ) \operatorname{Ent}(D) Ent(D)
假定选取的属性 a a a V V V个可能的取值 { a 1 , a 2 , . . . , a V } \{a^1, a^2, ..., a^V\} {a1,a2,...,aV},则用 a a a可以将集合划分为 V V V份,第 v v v份是属性 a a a取值为 a v a^v av的所有样本集合记做 D v D^v Dv
集合加上绝对值就是值集合的大小,如 ∣ D ∣ |D| D表示集合中含有的样本数量。

ID3算法

ID3算法会执行多轮,每轮找一个“当前最优属性”。不难发现,循环N轮则会生成一个高度为N的决策树。

理论学习

【选择划分属性】ID3每轮选择的属性只是当前的最优属性,因此是一种贪心算法,这并不能保证最终选择的划分属性是最优的。但我们不能怪ID3,因为穷举法的性能是不可接受的,所以贪心法已经是一个很不错的妥协了。
例如对于有ABCDE5个属性的样本集,前两轮选择了划分属性CE,第三轮认为CEACEBCED都要好,那么根据贪心法就会选择CEA,贪心法只考虑眼前的最优解。

【判定准则】ID3采用信息增益(information gain) 来判定属性选取的好坏,这借助于香农提出的信息论。
在信息论中信息熵(information entropy)越小则纯度越高,信息熵的公式自己查。
信息增益(information gain)是用划分前的信息熵减去划分后的信息熵,由于划分后集合会被划分为多份,因此划分后集合的信息熵需要加权平均后再比较。

信息熵计算公式:
Ent ⁡ ( D ) = − ∑ k = 1 ∣ Y ∣ p k log ⁡ 2 p k \operatorname{Ent}(D)=-\sum_{k=1}^{|\mathcal{Y}|} p_{k} \log _{2} p_{k} Ent(D)=k=1Ypklog2pk
信息增益计算公式:
Gain ⁡ ( D , a ) = Ent ⁡ ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ Ent ⁡ ( D v ) \operatorname{Gain}(D, a)=\operatorname{Ent}(D)-\sum_{v=1}^{V} \frac{\left|D^{v}\right|}{|D|} \operatorname{Ent}\left(D^{v}\right) Gain(D,a)=Ent(D)v=1VDDvEnt(Dv)

总结,ID3算法的关键点:贪心算法、信息增益、加权平均。

代码实现(Python)

信息熵计算函数:
ID3算法实现:

C4.5算法

ID3采用信息增益准则,缺点是会偏好取值数目较多的属性。例如ID3偏向选取职业而不是性别,因为职业有许多种取值这会在信息增益的计算中有优势。

C4.5对ID3做了改进,它采用信息增益率作为准则。

理论学习

信息增益率是添加了 IV ⁡ ( a ) \operatorname{IV}(a) IV(a)作为分母,我们把它称为 a a a的固有值,固有值的计算公式和信息熵公式其实是一样的,属性 a a a的取值越多则固有值越大。

信息增益率计算公式:
Gain_ratio ⁡ ( D , a ) = Gain ⁡ ( D , a ) IV ⁡ ( a ) \operatorname{Gain\_ratio}(D, a)=\frac{\operatorname{Gain}(D, a)}{\operatorname{IV}(a)} Gain_ratio(D,a)=IV(a)Gain(D,a)

固有值计算公式:
IV ⁡ ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ log ⁡ 2 ∣ D v ∣ ∣ D ∣ \operatorname{IV}(a)=-\sum_{v=1}^{V} \frac{\left|D^{v}\right|}{|D|} \log _{2} \frac{\left|D^{v}\right|}{|D|} IV(a)=v=1VDDvlog2DDv

虽然信息增益率解决了ID3的问题(即偏好取值数量大的属性),但它的问题刚好相反,它偏好取值数量小的属性。【选取划分属性】为了解决这一问题,C4.5先选出信息增益高于平均值的属性,然后再从中选信息增益率最高的,这个办法虽然治标不治本但还是很有效的。

代码实现(Python)

信息增益率计算函数:
C4.5算法实现:

CART算法

理论学习

CART采用基尼指数(Gini index)作为属性划分准则,基尼值 Gini ⁡ ( D ) \operatorname{Gini}(D) Gini(D)越小则数据集的纯度越高。
Gini ⁡ ( D ) = ∑ k = 1 ∣ Y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ Y ∣ p k 2 \begin{aligned} \operatorname{Gini}(D) &=\sum_{k=1}^{|\mathcal{Y}|} \sum_{k^{\prime} \neq k} p_{k} p_{k^{\prime}} \\ &=1-\sum_{k=1}^{|\mathcal{Y}|} p_{k}^{2} \end{aligned} Gini(D)=k=1Yk̸=kpkpk=1k=1Ypk2
而属性 a a a的基尼指数的计算公式如下。
Gini_index ⁡ ( D , a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ Gini ⁡ ( D v ) \operatorname{Gini\_index}(D, a)=\sum_{v=1}^{V} \frac{\left|D^{v}\right|}{|D|} \operatorname{Gini}\left(D^{v}\right) Gini_index(D,a)=v=1VDDvGini(Dv)

代码实现(Python)

使用sklearn库

import numpy as np
from sklearn import tree
from graphviz import Source

if __name__ == '__main__':
    np.random.seed(42)
    X = np.random.randint(10, size=(100, 4))
    Y = np.random.randint(2, size=100)
    a = np.column_stack((Y, X))
    clf = tree.DecisionTreeClassifier(criterion='gini', max_depth=3)
    clf = clf.fit(X, Y)

    graph = Source(tree.export_graphviz(clf, out_file=None))
    graph.format = 'png'
    graph.render('cart_tree', view=True)

剪枝操作解决过拟合问题

剪枝分为预剪枝和后剪枝两种。预剪枝算法时间开销小,但有欠拟合的风险。后剪枝算法耗时久,但生成的模型往往优于预剪枝。

连续属性离散化

决策树的树形结构决定了它很难处理连续型属性(如年龄、收入、身高),因此需要进行离散化。
在C4.5中采取了最简单的离散化方法:二分法,对于连续型属性a,它还会寻找一个分界点t,分为小于t和大于t两类。假如样本在属性a上有n种取值,那么t的取值就有n-1种可能,如下
T a = { a i + a i + 1 2 ∣ 1 ⩽ i ⩽ n − 1 } T_{a}=\left\{\frac{a^{i}+a^{i+1}}{2} | 1 \leqslant i \leqslant n-1\right\} Ta={2ai+ai+11in1}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值