决策树介绍
决策树(Decision Tree)是一种常用的机器学习算法,广泛应用于分类和回归问题。它是一种树形结构(可以是二叉树或者非二叉树),其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出,最后每个叶节点代表一种分类结果。
其实决策树的分类和人在生活中的决策很相似,举个栗子:
一个女孩的母亲要给这个女孩介绍男朋友,女孩要判断要不要去见面,于是有了下面的对话:
女儿:多大年纪了?
母亲:26
女儿:长的帅不帅?
母亲:挺帅的。
女儿:收入高不?
母亲:不算很高,中等情况。
女儿:是公务员吗?
母亲:是,公务员,在税务局上班呢。
女儿:那好,我去见见。
其实这个女孩的决策过程就是典型的分类树决策,通过年龄、长相、收入和是否公务员等类似的判断变量分为两个结果:见和不见
假设这个女孩对男人的要求是:30岁以下、长相中等以上并且是高收入者或中等以上收入的公务员,那么这个可以用下图表示女孩的决策逻辑。

其中:
绿色节点表示判断条件
橙色节点表示决策结果
箭头表示在一个判断条件在不同情况下的决策路径
在决策树中,对各个节点有如下定义:
根节点(Root Node):最顶层的第一个节点,整棵树的起点,例如上图中的年龄
内部节点(Decision Node):中间做判断的节点,例如上图中的长相,收入等
叶子节点(Leaf Node):最底层、不再分裂的最终节点,输出分类结果,如上图橙色部分。
图中红色箭头表示了上面例子中女孩的决策过程。这幅图基本可以算是一颗决策树,说它"基本可以算"是因为图中的判定条件没有量化,如收入高中低等等,还不能算是严格意义上的决策树,如果将所有条件量化,则就变成真正的决策树了
决策树划分选择
从之前的介绍中我们知道选择最优划分标准是决策树过程中的重点,我们日常的决策判断依赖于个人经验和"自我感觉",在上面的例子中女孩是通过经验和个人感觉来判断出年轻帅气工资高的是"好样本",而实际项目中我们一般没有这方面的经验来选取划分条件变量做到最优的划分,所以在决策树中需要通过量化的计算来判断如何划分能最大的区别出"好坏样本"。
而决策树的划分需要完成两项任务:
- 哪一些维度是更重要的划分维度,例如上面例子中年龄比长相更重要,长相又比收入重要
- 对于某一个特定的维度怎样划分更好。例如年龄中到底是选择30岁划分还是40岁划分,长相是帅的好还是丑的好等等
决策树中是通过计算信息熵来判断如何划分的,用简单的大白话概括一下就是计算什么维度怎么划分可以让结果更"纯",如果好样本中好样本的占比越大,那么结果就越"纯",对于坏样本也是如此。
接下来从数理概念讲解一下相关原理
熵和信息熵
熵(Entropy):是热力学中的概念,是系统的混乱度或无序度的度量。系统越混乱,熵就越大。
信息熵:在信息论中引用了热力学中的概念,用来描述信息的有序和混乱程度,越不确定的事物,它的熵就越大。具体的,随机变量X的熵的表达式如下:
H(X)=−∑i=1npilog2pi=∑i=1npilog21piH(X) = -\sum\limits_{i=1}^{n}p_i log_2p_i=\sum\limits_{i=1}^{n}p_i log_2\frac{1}{p_i}H(X)=−i=1∑npilog2pi=i=1∑npilog2pi1
在这个公式中对数函数一般是以2为底数,但是实际上也可以为其他的数。其中nnn代表X的nnn种不同的离散取值。而pi{p_i}pi表示X取值为iii的概率
很显然,光看这个干巴巴的公式很难理解信息熵的含义。而实际上,根据不同使用场景,我们可以从不同方面来理解:
1、信息熵用来表征信息量,信息量越多,信息熵就越大
举一个例子,金毛和二哈各说了一句话,金毛说:二哈是我的好朋友,二哈说:汪汪汪汪汪汪汪汪

现在我们算一下每句话的信息熵,这里把每句话中每个字出现的概率作为p代入公式。
金毛说了八个字,每个字都不一样:"二"的概率是18\frac{1}{8}81 ,"哈"的概率也是18\frac{1}{8}81 ...,每个字的概率都是18\frac{1}{8}81。
再看二哈,二哈的句子也包含八个字,但是每个字都一样,都是"汪",所以"汪"字出现的概率是1
代入信息熵的公式,金毛和二哈说的信息熵就分别是3和0:

让我们理解一下这个例子,金毛和二哈的句子长度都一样,都是八个字,但因为金毛说的句子包含的不同的字更多,便比二哈的只由一个"汪"字组成的句子拥有了更多的信息量,所以金毛句子的信息熵便大于二哈的句子
2、信息熵表征集合的纯度,集合纯度(purity)越高,信息熵就越小
实际上,上述的例子,一个句子我们也可以把它认为是一个由汉字组成的集合。
从集合的角度出发来理解,那么:
金毛句子的集合就是:{"二","哈","是","我","的","好","朋","友"}
二哈句子的集合就是:{"汪","汪","汪","汪","汪","汪","汪","汪"}。
我们可以看到,二哈句子集合的"纯度"非常高,只有一个字,一点也不混乱,所以纯度很高,而金毛句子集合的纯度就比较低了。
替换成我们上面说的决策树的例子,如果经过不同的划分后有两个结果,分别为
集合1:{"好男人","好男人","好男人","好男人","好男人","好男人","好男人","好男人"}
集合2:{"好男人","好男人","好男人","好男人","坏男人","坏男人","坏男人","好男人"}
那么计算出的的集合1对应的信息熵就更低,也很好理解对应的划分可以更好的把"好男人"和"坏男人"分出来,自然是更好的划分.
信息增益
决策树计算最优划分有多种算法,这里先介绍最基本的ID3算法的相关理论,其他算法原理后续补充
信息增益(Information Gain)代表了在知道了 某个条件下,信息的不确定性减少的程度。信息增益的计算公式为:
g(D,A)=H(D)−H(D∣A)g(D,A) = H(D) - H(D|A)g(D,A)=H(D)−H(D∣A)
其中H(D)H(D)H(D)为熵,即D的不确定性,H(D∣A)H(D|A)H(D∣A)为条件熵,表示在A的条件下D的不确定性。
假设训练数据集D和特征A,计算信息增益的步骤如下:
第一步:计算数据集D的经验熵:
H(D)=−∑k=1K∣Ck∣∣D∣log2∣Ck∣∣D∣=−∑k=1Kp(x)log21p(x)H(D) = -\sum\limits_{k=1}^{K}\frac{|C_k|}{|D|} log_2\frac{|C_k|}{|D|}= -\sum\limits_{k=1}^{K}p(x) log_2\frac{1}{p(x) }H(D)=−k=1∑K∣D∣∣Ck∣log2∣D∣∣Ck∣=−k=1∑Kp(x)log2p(x)1
其中,∣Ck∣|{C_k}|∣Ck∣为第kkk类样本的数目,∣D∣|D|∣D∣为数据集D的数目,p(x)p(x)p(x)即代表 某一类样本的概率 。
第二步:计算特征A对数据集D的条件熵H(D|A)
H(D∣A)=∑i=1n∣Di∣∣D∣H(Di)=−∑i=1n∣Di∣∣D∣∑k=1K∣Dik∣∣D∣log2∣Dik∣∣D∣H(D|A) = \sum\limits_{i=1}^{n}\frac{|D_i|}{|D|}H(D_i)=-\sum\limits_{i=1}^{n}\frac{|D_i|}{|D|}\sum\limits_{k=1}^{K}\frac{|D_{ik}|}{|D|} log_2\frac{|D_{ik}|}{|D|} H(D∣A)=i=1∑n∣D∣∣Di∣H(Di)=−i=1∑n∣D∣∣Di∣k=1∑K∣D∣∣Dik∣log2∣D∣∣Dik∣
第三步:计算信息增益:
g(D,A)=H(D)−H(D∣A)g(D,A) = H(D) - H(D|A)g(D,A)=H(D)−H(D∣A)
一般而言,信息增益越大,则意味着使用属性A来进行划分所获得的"纯度提升" 越大。因此,我们可使用信息增益来进行决策树的划分属性选择。ID3决策树学习算法就是以信息增益为准则来选择划分属性的。
手工计算过程
接下来依旧使用一个例子来看一下信息增益的计算过程,逐步手动计算选择最佳划分标准。
首先建一个数据集
py
mport numpy as np
import pandas as pd
from math import log2
data = {
"天气": ["晴", "晴", "阴", "雨", "雨", "雨", "阴", "晴", "晴", "雨", "晴", "阴", "阴", "雨"],
"温度": ["热", "热", "热", "凉", "冷", "冷", "冷", "凉", "冷", "凉", "凉", "凉", "热", "凉"],
"湿度": ["高", "高", "高", "正常", "正常", "正常", "正常", "高", "正常", "正常", "正常", "高", "正常", "高"],
"风力": ["弱", "强", "弱", "弱", "弱", "强", "强", "弱", "弱", "弱", "强", "强", "弱", "强"],
"适合户外活动": ["否", "否", "是", "是", "是", "否", "是", "否", "是", "是", "是", "是", "是", "否"]
}
df = pd.DataFrame(data)
print(df)
生成后数据如下:

我们将使用上述数据集来构建一个决策树,以预测"是否适合户外活动"。
第一步:计算整个数据集的熵
首先,计算目标变量"适合户外活动"的熵。数据集中共有14个样本,其中9个是"是",5个是"否"。
H(D)=−(914log2914+514log2514)≈0.9403 H(D) = -\left(\frac{9}{14} \log_2 \frac{9}{14} + \frac{5}{14} \log_2 \frac{5}{14}\right) \approx 0.9403 H(D)=−(149log2149+145log2145)≈0.9403
第二步:计算每个特征的条件熵
以特征"天气"作为例子:
天气=晴:5个样本,2"是",3"否";
天气=阴:4个样本,4"是",0"否";
天气=雨:5个样本,3"是",2"否"。
计算每个子集的熵:
H(A晴)=−(25log225+35log235)≈0.9709H(A阴)=−(44log244+04log204)=0H(A雨)=−(35log235+25log225)≈0.9709 H(A_{\text{晴}}) = -\left(\frac{2}{5} \log_2 \frac{2}{5} + \frac{3}{5} \log_2 \frac{3}{5}\right) \approx 0.9709 \\15pt H(A_{\text{阴}}) = -\left(\frac{4}{4} \log_2 \frac{4}{4} + \frac{0}{4} \log_2 \frac{0}{4}\right) = 0 \\15pt H(A_{\text{雨}}) = -\left(\frac{3}{5} \log_2 \frac{3}{5} + \frac{2}{5} \log_2 \frac{2}{5}\right) \approx 0.9709 H(A晴)=−(52log252+53log253)≈0.9709H(A阴)=−(44log244+40log240)=0H(A雨)=−(53log253+52log252)≈0.9709
则"天气"对应的条件熵为:
H(D∣A天气)=514H(A晴)+414H(A阴)+514H(A雨)≈0.6935H(D|A_{天气})= \frac{5}{14} H(A_{\text{晴}}) + \frac{4}{14} H(A_{\text{阴}}) + \frac{5}{14} H(A_{\text{雨}})\approx 0.6935H(D∣A天气)=145H(A晴)+144H(A阴)+145H(A雨)≈0.6935
第三步:计算每个特征的信息增益
特征"天气"的信息增益为:
g(D,A天气))=H(D)−H(D∣A天气)≈0.9403−0.6935≈0.2468g(D,A_\text{天气})) = H(D) - H(D|A_\text{天气}) \approx 0.9403 - 0.6935 \approx 0.2468g(D,A天气))=H(D)−H(D∣A天气)≈0.9403−0.6935≈0.2468
按照同样的方法计算其他特征(温度、湿度、风力)的信息增益,选择信息增益最大的特征作为根节点。
假设最终选择"天气"作为根节点,继续对"天气=晴"和"天气=雨"的子集进行递归分裂,直到叶节点为纯净或满足停止条件。
https://blog.csdn.net/qq_31763735/article/details/145170137
https://www.zhihu.com/tardis/bd/art/339380585
https://blog.csdn.net/kevinjin2011/article/details/125147134
https://www.cnblogs.com/pinard/p/6050306.html
https://segmentfault.com/a/1190000045251623
