
决策树,老熟人了,机器学习最常见的算法之一;GBDT,XGBoost的基础,搞懂它很关键,能给别人讲清楚也就基本搞懂了。
本文默认读者已经学过决策树,算是一个课后笔记,风格是一切从简,希望以后的我能看着开头的思维导图就能在10分钟内给别人讲明白什么是决策树。
我尽量用自己的话来描述,而不是课本的规范化语言,可能会有些不严谨的地方。(主要参考的是西瓜书)
希望能提供一个与网络上其他讲决策树的博文不一样的视角。
决策树的本质
其实就是一堆if-else构成的树,比如下面这颗决策树,就是一颗根据天气和温度决定要不要出门的决策树。

用代码表示就是:
if 天气 == "雨":
print("宅家")
else:
if 温度 == "凉":
print("出门")
else:
print("宅家")
同时可以看到:
-
蓝色的非叶子结点就是用来判断是否要出门的特征
-
绿色的叶子结点就是分类的结果,在机器学习里就是标签
怎么创建一棵决策树
现在已经对决策树有个感性认识了,关键是怎么创建一棵决策树。肯定不能凭空想象暗度陈仓就弄出一棵树来,对于机器学习问题,决策树的构建基于数据集。
这里给出一个数据集,统计了小樱在不同天气和温度的情况下选择出门🏃还是宅家🏠
| 序号 | 天气 | 温度 | 选择 |
|---|---|---|---|
| 1 | 晴☀️ | 热🔥 | 宅家🏠 |
| 2 | 晴☀️ | 热🔥 | 宅家🏠 |
| 3 | 晴☀️ | 热🔥 | 出门🏃 |
| 4 | 晴☀️ | 凉❄️ | 出门🏃 |
| 5 | 晴☀️ | 凉❄️ | 出门🏃 |
| 6 | 雨☔️ | 凉❄️ | 宅家🏠 |
| 7 | 雨☔️ | 凉❄️ | 宅家🏠 |
| 8 | 雨☔️ | 凉❄️ | 宅家🏠 |
| 9 | 雨☔️ | 凉❄️ | 宅家🏠 |
| 10 | 雨☔️ | 凉❄️ | 宅家🏠 |
然后思路应该是:把困难的问题分解成简单的问题
一下搞出个决策树还是太难了,先来思考下怎么创建树的结点吧,毕竟结点有了,多创几个结点连在一起就是一棵决策树了。
怎么创建结点
之前谈过,非叶子结点就是用来判断标签的特征,上面那个数据集通过简单的统计可以知道:
- 有5天晴天☀️,5天下雨☔️。
- 3天热天🔥,7天凉天❄️。
把特征作为结点,就可以把原本大的数据集,分成小的数据集,这也符合我们解决问题的思路。比如原本完整的数据集是这样的:

数字和图标分别代表样本序号和样本标签。
假设分别以天气和温度来划分数据集,就把大的数据集化成了小的数据集。

分析问题变化的情况:
- 问题数变多了,本来1个大问题,现在是2个小问题
- 数据集变小了
- 特征变少了,用天气划分数据集后,就只剩下温度了,同理用温度划分数据集后只剩天气了。
理论上还是血赚,毕竟算1000个2+2要比算一个21000更容易。
怎么判断哪个特征更适合做结点?
但上面有两种划分方式,凭直觉,应该选哪个特征来划分?
其实不能凭直觉,选法很简单:“尽可能使划分后数据子集的样本更纯。”更纯的意思就是更单一的意思,比如以天气来划分,是下雨时☔️小樱都选择了待家里🏠。这个够单一了吧。
但作为算法,需要有一个公式能算出数据集样本的纯度,这就引出了决策树的几个算法
选择特征的算法
1. ID3算法
信息熵
先拍出一个公式,这个公式就能算数据集样本的纯度。
Ent(D)=−∑k=1Kpklog2pk
\text{Ent}(D)=-\sum^K_{k=1}p_klog_2p_k
Ent(D)=−k=1∑Kpklog2pk
公式计算的结果叫信息熵(information entropy),看过科幻的话对熵这个概念应该比较好理解,宇宙总在熵增,也就是宇宙总是朝着更混乱的方向前进。信息熵也差不多,样本的信息熵越大,样本越不纯(混乱)。
-
这里的DDD是数据集,可以理解成上面那张表。
-
KKK表示这个数据集的样本有多少个标签,我们这里K=2K=2K=2,只有出门和宅家两个标签
-
pkp_kpk表示第k个标签的样本数占总样本数的比例,假设k=1k=1k=1表示宅家,k=2k=2k=2表示出门,那p1=7/10=0.7p_1=7/10=0.7p1=7/10=0.7,p2=0.3p_2=0.3p2=0.3
这个数据集的信息熵就是:
Ent(D)=−(0.7×log20.7+0.3×log20.3)=0.8813
\text{Ent}(D)=-(0.7\times log_20.7+0.3\times log_20.3)=0.8813
Ent(D)=−(0.7×log20.7+0.3×log20.3)=0.8813
这个公式为什么能衡量样本纯度?
其实还是用例子解释比较好,如果一个数据集,有一类标签的样本非常多,那这个类别的样本数的占比就非常高。可以理解为pi=1p_i=1pi=1,其他的pk∣k≠i=0p_{k|k\ne i}=0pk∣k=i=0。带进上面那个公式,算出的信息熵就是0,也就是样本很纯。
对于K=2K=2K=2的情况,Ent(D)=−(plog2p+(1−p)log2(1−p))\text{Ent}(D)=-(plog_2p+(1-p)log_2(1-p))Ent(D)=−(plog2p+(1−p)log2(1−p))

可以看到p接近0或1时信息熵低,样本更纯
总结一下,信息熵的作用:
- 衡量数据集纯不纯
- 信息熵越小,数据集越纯(样本越单一)
信息增益
那接下来的任务就简单了,分别计算以天气、温度划分后的数据子集的信息熵就好了。
使用一个叫信息增益的东西融合计算结果:
Gain(D,a)=Ent(D)−∑v=1V∣Dv∣∣D∣Ent(Dv)
\text{Gain}(D,a)=\text{Ent}(D)-\sum_{v=1}^V \frac{|D^v|}{|D|}\text{Ent}(D^v)
Gain(D,a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
符号解释:
- aaa表示特征,也就是“天气”和“温度”
- VVV表示特征有多少个取值,这里天气和温度都只有2个取值,也就是V=2V=2V=2
- ∣D∣|D|∣D∣和∣Dv∣|D^v|∣Dv∣,这个表示数据集和数据子集的样本数量。
如果数据子集越纯,数据子集的信息熵就越小,则信息增益越大,因此选信息增益大的特征作为决策树结点

先计算4个子集的信息熵:
Ent(D雨)=−(1×log20+0×log21)=0Ent(D晴)=−(25×log225+35×log235)=0.9709Ent(D凉)=−(57×log257+27×log227)=0.8631Ent(D热)=−(23×log223+13×log213)=0.9183
\begin{aligned}
\text{Ent}(D^{雨})&=-(1\times log_20 + 0\times log_21) =0\\
\text{Ent}(D^{晴})&=-(\frac{2}{5}\times log_2\frac{2}{5} + \frac{3}{5}\times log_2\frac{3}{5}) =0.9709\\
\text{Ent}(D^{凉})&=-(\frac{5}{7}\times log_2\frac{5}{7} + \frac{2}{7}\times log_2\frac{2}{7}) =0.8631\\
\text{Ent}(D^{热})&=-(\frac{2}{3}\times log_2\frac{2}{3} + \frac{1}{3}\times log_2\frac{1}{3}) =0.9183\\
\end{aligned}
Ent(D雨)Ent(D晴)Ent(D凉)Ent(D热)=−(1×log20+0×log21)=0=−(52×log252+53×log253)=0.9709=−(75×log275+72×log272)=0.8631=−(32×log232+31×log231)=0.9183
计算a=天气a=天气a=天气和a=温度a=温度a=温度时的信息增益
Gain(D,a=天气)=Ent(D)−(∣D雨∣∣D∣Ent(D雨)+∣D晴∣∣D∣Ent(D晴))=0.8813−(510×0+510×0.9709)=0.3958
\begin{aligned}
\text{Gain}(D,a=天气)&=\text{Ent}(D)-(\frac{|D^雨|}{|D|}\text{Ent}(D^雨) + \frac{|D^晴|}{|D|}\text{Ent}(D^晴))\\
&=0.8813-(\frac{5}{10}\times 0 + \frac{5}{10}\times 0.9709)\\
&=0.3958
\end{aligned}
Gain(D,a=天气)=Ent(D)−(∣D∣∣D雨∣Ent(D雨)+∣D∣∣D晴∣Ent(D晴))=0.8813−(105×0+105×0.9709)=0.3958
Gain(D,a=温度)=Ent(D)−(∣D凉∣∣D∣Ent(D凉)+∣D热∣∣D∣Ent(D热))=0.8813−(710×0.8631+310×0.9183)=0.0016 \begin{aligned} \text{Gain}(D,a=温度)&=\text{Ent}(D)-(\frac{|D^凉|}{|D|}\text{Ent}(D^凉) + \frac{|D^热|}{|D|}\text{Ent}(D^热))\\ &=0.8813-(\frac{7}{10}\times 0.8631 + \frac{3}{10}\times 0.9183)\\ &=0.0016 \end{aligned} Gain(D,a=温度)=Ent(D)−(∣D∣∣D凉∣Ent(D凉)+∣D∣∣D热∣Ent(D热))=0.8813−(107×0.8631+103×0.9183)=0.0016
可以看到,天气的信息增益更大,所以第一个划分结点就选天气。
其实之后的操作也差不多,数据集更大些,特征更多些,选特征的操作还是一样的。
总结:
- 信息熵怎么算Ent(D)=−∑k=1Kpklog2pk\text{Ent}(D)=-\sum^K_{k=1}p_klog_2p_kEnt(D)=−∑k=1Kpklog2pk
- 信息增益怎么算Gain(D,a)=Ent(D)−∑v=1V∣Dv∣∣D∣Ent(Dv)\text{Gain}(D,a)=\text{Ent}(D)-\sum_{v=1}^V \frac{|D^v|}{|D|}\text{Ent}(D^v)Gain(D,a)=Ent(D)−∑v=1V∣D∣∣Dv∣Ent(Dv)
2. C4.5算法
ID3有个小问题:如果特征取值越多,它的信息增益就越大,比如极端情况下,使用序号来作为决策树结点。

每一个数据子集只有1个样本,显然计算得到的样本子集的信息熵为0。信息增益Gain(D,a=序号)=Ent(D)=0.8813Gain(D,a=序号)=Ent(D)=0.8813Gain(D,a=序号)=Ent(D)=0.8813
那讲道理这是不科学的。
所以要给对这种特征取值多的特征一定的惩罚。
具体是使用信息增益率代替信息增益:
Gain_ratio(D,a)=Gain(D,a)IV(a) \text{Gain\_ratio}(D,a)=\frac{\text{Gain}(D,a)}{\text{IV}(a)} Gain_ratio(D,a)=IV(a)Gain(D,a)
IV(a)\text{IV}(a)IV(a)是特征aaa的固有值(intrinsic value)。特点:
- 特征aaa的取值数目越多,IV(a)IV(a)IV(a)越大
- 很像信息熵
IV(a)=−∑v=1V∣Dv∣∣D∣log2∣Dv∣∣D∣ \text{IV}(a)=-\sum_{v=1}^V\frac{|D^v|}{|D|}log_2\frac{|D^v|}{|D|} IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
可以这么理解,特征取值数目越多,说明你这个样本划分的越混乱。划分得越混乱,那信息增益率就越小。
使用信息增益率计算:
IV(a=天气)=−(510log2510+510log2510)=1IV(a=温度)=−(710log2710+310log2310)=0.8813IV(a=序号)=−(110log2110×10)=3.3219Gain_ratio(D,a=天气)=Gain_ratio(D,a=天气)IV(a=天气)=0.39581=0.3958Gain_ratio(D,a=温度)=Gain_ratio(D,a=温度)IV(a=温度)=0.00160.8813=0.0018Gain_ratio(D,a=序号)=Gain_ratio(D,a=序号)IV(a=序号)=0.88133.3219=0.2653
\begin{aligned}
\text{IV}(a=天气)&=-(\frac{5}{10}log_2\frac{5}{10} + \frac{5}{10}log_2\frac{5}{10})=1\\
\text{IV}(a=温度)&=-(\frac{7}{10}log_2\frac{7}{10} + \frac{3}{10}log_2\frac{3}{10})=0.8813\\
\text{IV}(a=序号)&=-(\frac{1}{10}log_2\frac{1}{10} \times10)=3.3219\\
\text{Gain\_ratio}(D,a=天气)&=\frac{\text{Gain\_ratio}(D,a=天气)}{\text{IV}(a=天气)}= \frac{0.3958}{1}=0.3958\\
\text{Gain\_ratio}(D,a=温度)&=\frac{\text{Gain\_ratio}(D,a=温度)}{\text{IV}(a=温度)}= \frac{0.0016}{0.8813}=0.0018 \\
\text{Gain\_ratio}(D,a=序号)&=\frac{\text{Gain\_ratio}(D,a=序号)}{\text{IV}(a=序号)}= \frac{0.8813}{3.3219}=0.2653
\end{aligned}
IV(a=天气)IV(a=温度)IV(a=序号)Gain_ratio(D,a=天气)Gain_ratio(D,a=温度)Gain_ratio(D,a=序号)=−(105log2105+105log2105)=1=−(107log2107+103log2103)=0.8813=−(101log2101×10)=3.3219=IV(a=天气)Gain_ratio(D,a=天气)=10.3958=0.3958=IV(a=温度)Gain_ratio(D,a=温度)=0.88130.0016=0.0018=IV(a=序号)Gain_ratio(D,a=序号)=3.32190.8813=0.2653
经过信息增益率计算之后,还是选择天气作为结点。
3. 基尼指数
我觉得基尼指数和ID3的信息增益其实比较类似,理解了ID3,就很容易理解基尼指数了。
基尼值表示从数据集(有放回?)的随机抽取两个样本,这两个样本类别标记不一样的概率。
基尼值越低,表示抽到两个样本类别一样的概率越高,说明数据集越纯
Gini(D)=1−∑k=1Kpk2
\text{Gini}(D)=1-\sum_{k=1}^Kp_k^2
Gini(D)=1−k=1∑Kpk2
所以就要求划分子集后,基尼指数越低越好。
基尼指数定义就是:
Gini_index(D,a)=∑v=1V∣Dv∣∣D∣Gini(Dv) \text{Gini\_index}(D,a)=\sum_{v=1}^V\frac{|D^v|}{|D|}\text{Gini}(D^v) Gini_index(D,a)=v=1∑V∣D∣∣Dv∣Gini(Dv)
总结:
- 基尼值越低,样本越纯

6598

被折叠的 条评论
为什么被折叠?



