1 概念

决策树(Decision Tree)是一种树形结构的监督学习算法,广泛用于分类和回归任务。

它通过分而治之的策略,自根至叶将数据集划分为更纯的子集。树的内部节点代表特征属性测试,分支代表测试输出,叶节点代表最终决策结果。因其白盒模型特性,易于理解、可视化和解释。

它的核心思想非常简单:通过不断地问简单的问题,把范围一步步缩小,最终得到一个确定的答案

大概就是。你今天下班回家,想亲手做顿饭放松一下。但你不确定具体要做什么,你的大脑其实就会自动构建一棵决策树来帮你做决定。你通过问一系列只要回答的小问题,把一个复杂的大决定(吃什么),拆解成了一步步的路径。比如下面的例子。

第一个问题:今天有充足的时间吗?

  • 是 ➡️ 顺着树枝往下走,遇到下一个问题:冰箱里有肉吗?
    • 回答 ➡️ 结论:做个耗时的炖肉。
    • 回答没有 ➡️ 结论:做个精致的素菜。
  • 否 (想快点吃上饭) ➡️ 顺着另一根树枝往下走,遇到下一个问题:非常饿吗?
    • 回答 ➡️ 结论:快速煮个面条。
    • 回答 ➡️ 结论:拌个简单的沙拉。

决策树长什么样?

根节点(Root Node): 树的最顶端,也就是你问的第一个、也是最关键的问题(比如今天有充足的时间吗?)。

内部节点(Internal Node): 树枝中间的那些后续问题(比如冰箱里有肉吗?)。

叶子节点(Leaf Node): 树的最末端,也就是最终的决定或分类结果(比如煮个面条)。到了叶子这里,问题就问完了,游戏结束。

感觉就是⬇️

决策树基础| Javen Chen's Blog

2 学习必备基础

上面其实知道决策树是什么时候接下来就是要知道要怎么才能把最重要的特征放在根,下一步又是什么节点了。

比如对于一些人来说,长得帅就是比有钱重要的多多多!!那我们如何去选择最重要的那个特征第一选择呢?这就需要你计算咯!!所以需要学习以下2个很重要的概念

2-1 信息熵 Information Entropy

上面的比喻来说。这棵树怎么知道第一个问题应该问时间充不充足,而不是问今天穿了什么颜色的衣服呢?

这就回到我们刚才聊过的信息熵了。机器在构建这棵树时,会在每一步挑问题。它挑选的标准就是:哪个问题能让剩下的选项变得最清晰、最不混乱?(也就是让信息熵下降最多)

因为今天穿了什么颜色的衣服对决定晚饭吃什么毫无帮助(信息熵没有下降)。而时间充不充足能瞬间帮你排除掉一大半不现实的菜谱,让你的目标变得非常纯净,所以它成了最完美的根节点。在决策树中,信息熵是用来衡量一个数据集的混乱度不纯度的指标。

  • 熵越小:数据越纯,越整齐(比如一筐全是苹果,毫无悬念)。
  • 熵越大:数据越乱,越难预测(比如一筐里有 5 个苹果、5 个橘子,随便抓一个,你很难确定是什么)。

那如何计算呢?

假设我们有一个数据集 D,里面有 c种不同的类别。第 i 种类别在数据集中所占的比例(概率)是 pi。那么这个数据集的信息熵 H(D)的公式是

H(D)=i=1cpilog2(pi)H(D) = - \sum_{i=1}^{c} p_i \log_2(p_i)
  • pi某个类别的概率。
  • log代表 以 2 为底的对数。因为 pi 肯定是0-1之间的小数。所以出来的对数必定是负数或 0。
  • 前面的负号为了把最终结果变成正数,方便我们比较。
  • 把所有类别的 pi 和log2(pi) 算出来后,全部加在一起。

⬆️ 什么玩意儿?不会算,那么直接给例子。

假设我们有一个装了 10 个球的盲盒,球只有两种颜色:红色蓝色

  • 极端情况 1:最混乱的状态(5 红 5 蓝)

    • 红球概率 p1 = 5/10 = 0.5 = 1/2
    • 蓝球概率 p1 = 5/10 = 0.5 = 1/2
    H(D)=[p1log2(p1)+p2log2(p2)]H(D) = - [ p_1 \log_2(p_1) + p_2 \log_2(p_2) ] H(D)=[0.5×(1)+0.5×(1)]H(D) = - [ 0.5 \times (-1) + 0.5 \times (-1) ] H(D)=[0.50.5]=[1]=1H(D) = - [ -0.5 - 0.5 ] = - [ -1 ] = 1

    最后结果就是1。结论➡️当两种类别势均力敌(各占 50%)时,混乱度最高,信息熵达到最大值 1。

  • 极端情况 2:最纯粹的状态(10 红 0 蓝)

    • 红球概率 p1 = 10/10 = 1

    • 蓝球概率 p2 = 0/10 = 0

      H(D)=[1×log2(1)+0]H(D) = - [ 1 \times \log_2(1) + 0 ] H(D)=[1×0+0]=0H(D) = - [ 1 \times 0 + 0 ] = 0

    最后结果就是0。当数据里只有一种东西时,没有任何不确定性,信息熵为 0。

  • 一般情况:偏向某一边(7 红 3 蓝)

    • 红球概率 p1 = 7/10 = 0.7
    • 蓝球概率 p2 = 3/10 = 0.3
    H(D)=[0.7log2(0.7)+0.3log2(0.3)]H(D) = - [ 0.7 \log_2(0.7) + 0.3 \log_2(0.3) ]

    这里就不能口算log了,那么就是计算器计算

    log2(0.7)0.515\log_2(0.7) \approx -0.515 log2(0.3)1.737\log_2(0.3) \approx -1.737

    最后继续计算

    H(D)[(0.7×0.515)+(0.3×1.737)]H(D) \approx - [ (0.7 \times -0.515) + (0.3 \times -1.737) ] H(D)[0.36050.5211]0.8816H(D) \approx - [ -0.3605 - 0.5211 ] \approx 0.8816

    你可以看到,随着红球变多(从 5 个变成 7 个),数据集变得稍微纯了一点,所以信息熵从最大值 1 下降到了 0.8816。

2-2 信息增益 Information Gain

如果把信息熵比作房间的混乱程度,那么信息增益就是你打扫了一次房间后,混乱程度减少了多少

决策树在每一次要分叉(提问)的时候,都会把所有能问的问题在心里默默算一遍,然后挑出一个能让信息增益最大(也就是让混乱度下降最多)的问题。接下来就是有点难的公式理解了

我们一般用 D 代表我们要处理的数据集,用 a 代表我们用来分类的某个特征(比如大小颜色)

信息增益的正式数学公式是这样的⬇️

Gain(D,a)=H(D)v=1VDvDH(Dv)Gain(D, a) = H(D) - \sum_{v=1}^{V} \frac{|D^v|}{|D|} H(D^v)

下面给一个盲盒例子。

总共 10 个球:7 个红球,3 个蓝球。

大球有 5 个:全是红球(5 红 0 蓝)。小球有 5 个:有红有蓝(2 红 3 蓝)。整理成表格是这样的。

编号 (ID)属性:大小 (feature)结果:颜色 (label)
1
2
3
4
5
6
7
8
9
10

现在计算等目的就是

通过按大小分类,我们到底获得了多少信息增益

① 计算分开前的总信息熵(总混乱度)

在没按大小分类前,我们面对的是一堆混在一起的 10 个球。

  • 红球概率:p1 = 7/10 = 0.7
  • 蓝球概率:p2 = 3/10 = 0.3

我们套用信息熵公式

H()=(0.7log2(0.7)+0.3log2(0.3))H(总) = - \left( 0.7 \log_2(0.7) + 0.3 \log_2(0.3) \right)

借助计算器算一下对数。然后代入进去

H()=((0.7×0.5146)+(0.3×1.7370))H(总) = - \left( (0.7 \times -0.5146) + (0.3 \times -1.7370) \right) H()=(0.36020.5211)=0.8813H(总) = - \left( -0.3602 - 0.5211 \right) = 0.8813

② 分别计算分开后的子节点信息熵

按大小分开后,变成了两堆球,我们挨个算它们的混乱度。

1. 大球堆(5 个球,5 红 0 蓝)

  • 红球概率:p1 = 5/5 = 1

  • 蓝球概率:p2 = 0/5 = 0

    H(大球)=(1log2(1)+0)=0H(大球) = - \left( 1 \log_2(1) + 0 \right) = 0

    (合理,完全不乱,混乱度为 0。)

2. 小球堆(5 个球,2 红 3 蓝)

  • 红球概率:p1 = 2/5 = 0.4

  • 蓝球概率:p2 = 3/5 = 0.6

    H(小球)=(0.4log2(0.4)+0.6log2(0.6))H(小球) = - \left( 0.4 \log_2(0.4) + 0.6 \log_2(0.6) \right)
log2(0.4)1.3219\log_2(0.4) \approx -1.3219 log2(0.6)0.7370\log_2(0.6) \approx -0.7370 H(小球)=(0.52880.4422)=0.9710H(小球) = - \left( -0.5288 - 0.4422 \right) = 0.9710

小球堆里红蓝比例接近一半一半,所以比较混乱,数值接近 1。

③ 计算分开后的加权平均信息熵

现在我们有了大球的混乱度(0)和小球的混乱度(0.9710)。因为大球和小球各占了总数的一半(5 个),我们需要按比例把它们加起来。

  • 大球堆占总数的权重:5/10 = 0.5
  • 小球堆占总数的权重:5/10 = 0.5
加权总熵=(0.5×H(大球))+(0.5×H(小球))加权总熵 = (0.5 \times H(大球)) + (0.5 \times H(小球)) 加权总熵=(0.5×0)+(0.5×0.9710)=0.4855加权总熵 = (0.5 \times 0) + (0.5 \times 0.9710) = 0.4855

按大小分类后,整体的混乱度降到了 0.4855。

④ 计算最终的信息增益

这就是最后一步减法了。

信息增益 = 分类前的总混乱度 - 分类后的加权总混乱度

信息增益=0.88130.4855=0.3958信息增益 = 0.8813 - 0.4855 = 0.3958

最终答案: 通过问球是大的还是小的,我们把混乱度减少了 0.3958,这就是这个条件带来的信息增益!

拆解公式

为了让更具有通用性就拆解一下最初的公式

公式的左半边:老规矩,算总账

  • Gain(D, a):这就是我们要算的最终结果——在数据集 D 上,按属性 a 划分带来的信息增益
  • H(D):划分前,整个大盲盒的初始信息熵(也就是我们刚才算出来的总混乱度 0.8813 例子:红蓝球7/3)。

公式的右半边:算分家后的加权平均

右边这一大坨 其实就是我们在第三步算的**加权平均混乱度**。

v=1VDvDH(Dv)\sum_{v=1}^{V} \frac{|D^v|}{|D|} H(D^v)
  • V:属性 a 分出了几个岔路。比如按大小分,只有大和小两路,那么 V = 2。
  • v:代表具体的某一条岔路(比如第 1 路是大球,第 2 路是小球)。
  • |D|:盲盒里总共的球数(10 个)。
  • |D^v|:分家后,跑到第 v 条岔路里的球数(比如大球有 5 个)。
  • D^v| / |D|:这就是权重比例(比如 5/10 = 0.5)。
  • H(D^v):这条岔路自己内部的信息熵(比如大球堆的混乱度 0,小球堆的混乱度 0.9710)。
  • sum (求和符号):意思是把每一条岔路的权重 * 内部混乱度挨个算出来,然后全部加在一起。

把我们的盲盒例子代入公式

如果把我们刚才算的具体文字替换进这个公式里,它长这样

Gain(盲盒,大小)=H(总盲盒)(大球堆总盲盒H(大球堆)+小球堆总盲盒H(小球堆))Gain(盲盒, 大小) = H(总盲盒) - \left( \frac{|大球堆|}{|总盲盒|} H(大球堆) + \frac{|小球堆|}{|总盲盒|} H(小球堆) \right)

把数字填进去,

Gain=0.8813(510×0+510×0.9710)=0.3958Gain = 0.8813 - \left( \frac{5}{10} \times 0 + \frac{5}{10} \times 0.9710 \right) = 0.3958

所有的数学符号,最终都落在了这个非常接地气的逻辑上

原先的混乱度,减去按比例算出来的现在的混乱度,就是我赚到的清晰度(信息增益)。

上面就是所有的基础。接下来要具体说一些决策树了。