决策树算法笔记整理1 - 如何划分?(信息熵,不纯度及信息增益)

1. 帮助理解的前置case

1.1 case1:相亲

参考CSDN其他blog

决策树,顾名思义,是一种树,一种依托于策略抉择而建立起来的树。
套用俗语,决策树分类的思想类似于找对象。现想象一个女孩的母亲要给这个女孩介绍男朋友,于是有了下面的对话:

在这里插入图片描述

这个女孩的决策过程就是典型的分类树决策。
相当于通过年龄、长相、收入和是否公务员对将男人分为两个类别:见和不见。假设这个女孩对男人的要求是:30岁以下、长相中等以上并且是高收入者或中等以上收入的公务员,那么这个可以用下图表示女孩的决策逻辑:
在这里插入图片描述

1.2 case2:招聘面试

也就是说,决策树的简单策略就是,好比公司招聘面试过程中筛选一个人的简历,如果你的条件相当好比如说某985/211重点大学博士毕业,那么二话不说,直接叫过来面试,如果非重点大学毕业,但实际项目经验丰富,那么也要考虑叫过来面试一下,即所谓具体情况具体分析、决策。

1.3 case3:高尔夫球

参考Wikipedia https://zh.wikipedia.org/wiki/决策树

小王是一家著名高尔夫俱乐部的经理。但是他被雇员数量问题搞得心情十分不好。某些天好像所有人都来玩高尔夫,以至于所有员工都忙的团团转还是应付不过来,而有些天不知道什么原因却一个人也不来,俱乐部为雇员数量浪费了不少资金。

小王的目的是通过下周天气预报寻找什么时候人们会打高尔夫,以适时调整雇员数量。因此首先他必须了解人们决定是否打球的原因。

在2周时间内我们得到以下记录:
在这里插入图片描述
天气状况有晴,云和雨;气温用华氏温度表示;相对湿度用百分比;还有有无风。当然还有顾客是不是在这些日子光顾俱乐部。最终他得到了14行5列的数据表格。

决策树模型就被建起来用于解决问题。
在这里插入图片描述
决策树是一个有向无环图。根结点代表所有数据。分类树算法可以通过变量outlook,找出最好地解释非独立变量play(打高尔夫的人)的方法。变量outlook的范畴被划分为以下三个组:

晴天,多云天和雨天。

我们得出第一个结论:如果天气是多云,人们总是选择玩高尔夫,而只有少数很着迷的甚至在雨天也会玩。

接下来我们把晴天组的分为两部分,我们发现顾客不喜欢湿度高于70%的天气。最终我们还发现,如果雨天还有风的话,就不会有人打了。

这就通过分类树给出了一个解决方案。小王(老板)在晴天,潮湿的天气或者刮风的雨天解雇了大部分员工,因为这种天气不会有人打高尔夫。而其他的天气会有很多人打高尔夫,因此可以雇用一些临时员工来工作。

2. 决策树必备概念:从比特化到信息熵

2.1 比特化

假设存在离散随机变量X,取值与概率如下:

取值概率
A1/4
B1/4
C1/4
D1/4

现在有一组由X变量组成的序列:BACADDCBAC……,如果现在希望将这个序列进行网络传输,我们可以将每种取值使用两个位进行编码:

取值编码
A00
B01
C10
D11

编码后,我们可以得到这样的序列:01001000111110010010……,而字符的平均编码长度为。
E = 2 ∗ 1 4 + 2 ∗ 1 4 + 2 ∗ 1 4 + 2 ∗ 1 4 = 2 E = 2 * \frac{1}{4} + 2 * \frac{1}{4}+ 2 * \frac{1}{4}+ 2 * \frac{1}{4} = 2 E=241+241+241+241=2
不过,如果当变量X的取值概率不同时,不同的编码方式可能会带来不同的编码长度。

取值概率
A1/2
B1/4
C1/8
D1/8

当然,我们依然可以采用之前的编码方式,这样,一个字符使用两个位进行编码。这样,平均编码长度为:
E = 2 ∗ 1 2 + 2 ∗ 1 4 + 2 ∗ 1 8 + 2 ∗ 1 8 = 2 E = 2 * \frac{1}{2} + 2 * \frac{1}{4}+ 2 * \frac{1}{8}+ 2 * \frac{1}{8} = 2 E=221+241+281+281=2
然而,考虑到X取值的不均衡性,我们可以更换编码方式,进而减少编码长度,降低网络传输量。

取值编码
A0
B10
C110
D111

因为A出现的概率最高,因此,我们将出现概率最高的,使用最短的位进行编码,而将出现概率低的C,D使用较长的位编码,这样就可以降低编码长度。我们使用不等长的编码方式时需要注意,任何一个短编码都不可以作为长编码的前缀,否则就会造成混淆。
调整之后,每个字符编码的平均位数(编码长度)为
E = 1 ∗ 1 2 + 2 ∗ 1 4 + 3 ∗ 1 8 + 3 ∗ 1 8 = 1.75 E = 1 * \frac{1}{2} + 2 * \frac{1}{4}+ 3 * \frac{1}{8}+ 3 * \frac{1}{8} = 1.75 E=121+241+381+381=1.75
我们可以表示为如下的形式:
E = − l o g 2 1 2 ∗ 1 2 − l o g 2 1 4 ∗ 1 4 − l o g 2 1 8 ∗ 1 8 − l o g 2 1 8 ∗ 1 8 = 1.75 E = -log_2\frac{1}{2} * \frac{1}{2} - log_2\frac{1}{4} * \frac{1}{4} - log_2\frac{1}{8} * \frac{1}{8} - log_2\frac{1}{8} * \frac{1}{8} = 1.75 E=log22121log24141log28181log28181=1.75

2.2 信息熵(with codes)

观察上式,有什么规律吗?
假设现在随机变量X具有m个值,分别为: V 1 , V 2 , . . . . , V m V_1,V_2,....,V_m V1,V2,....,Vm。并且各个值出现的概率如下:
在这里插入图片描述
对于一组序列信息来讲,可以使用这些变量的期望来表示每个变量需要多少个比特位来描述信息:
E ( X ) = − p 1 ∗ l o g 2 p 1 − p 2 ∗ l o g 2 p 2 − p 3 ∗ l o g 2 p 3 − … … − p m ∗ l o g 2 p m E(X) = -p_1 * log_2p_1 - p_2 * log_2p_2 - p_3 * log_2p_3 - …… - p_m * log_2p_m E(X)=p1log2p1p2log2p2p3log2p3pmlog2pm
以上的表示就是变量X的信息熵,表示为:
H ( X ) = − ∑ i = 1 m p i l o g 2 p i H(X) = -\sum_{i=1}^{m}p_ilog_2p_i H(X)=i=1mpilog2pi

2.2.1 信息熵概念

信息熵就是用来描述系统信息量的不确定度。不确定性越大,则信息熵越大,反之,信息熵越小。
在这里插入图片描述
例如,4只猎豹参与赛跑,每只猎豹的能力都是旗鼓相当,平分秋色。我们很难确定哪只猎豹会获得胜利,因此,这种情况下,不确定性很大,信息熵就大。但是,假设让1只猎豹与3只蜗牛进行赛跑,则猎豹取胜便是毋容置疑的,因此,这种情况下,不确定性很小,信息熵就小。
因此,对于随机变量X,其分布越均衡,则不确定性越多,信息熵越大。其分布越不均衡,则不确定性越少,信息熵越少。

2.2.2 信息熵程序python解释
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.family"] = "SimHei"
mpl.rcParams["axes.unicode_minus"] = False

# 计算概率值,概率值由0到1逐渐增大。
p = np.linspace(0.01, 0.99, 100)
# 计算概率逐渐改变的时候,信息熵的变化情况。
h = -p * np.log2(p) - (1 - p) * np.log2(1 - p)
plt.plot(p, h)
plt.xlabel("概率1取值")
plt.ylabel("信息熵")
plt.title("两个随机随机变量不同取值-信息熵对比")
plt.show()

当概率为0.5的时候,信息熵最大,不纯度最大,不确定性也越大。
在这里插入图片描述

3. 决策树概念

  • 决策树一种非参数监督学习方法,用于分类与回归。
  • 目标是创建一个模型,从数据特征中进行学习,进而推断出的简单决策规则,用来预测目标变量的值。
  • 决策树是一种树形结构,通过做出一系列决策(选择)来对数据进行划分,这类似于针对一系列问题进行选择。
  • 决策树的决策过程就是从根节点开始,测试待分类项中对应的特征属性,并按照其值选择输出分支,直到叶子节点,将叶子节点的存放的类别作为决策结果。

根据某些条件,判断是否能偿还债务?

例如,我们有如下的数据集:
在这里插入图片描述

例如,我们可以按照如下的方式进行划分选择:
在这里插入图片描述

4. 构建决策树

决策树可以看做由若干个节点构成,其中,每个节点存放一定数量的样本(根节点存放所有样本数据)

4.1 构建决策树的过程

决策树的构建过程就是根据属性(特征)条件来分割节点(样本数据),直到满足以下条件:

  • 树达到指定的最大深度(max_depth),每次分割视为一层。
  • 所有叶子节点中的样本属于同一个类别(足够纯)。…信息熵最小。
  • 所有叶子节点包含的样本数量小于指定的最小分类样本(min_samples_split数量。

  • 最大纯度,就是信息熵为0,失衡的情况。
    如果达到最大深度,就容易产生过拟合的现象。
  • 深度怎么算?就是回答问题的数量:回答一个问题,就是一个深度,回答两个问题,就是两个深度。
    比如,只分到如下图,那就是一个深度,只回答了一个问题。
    在这里插入图片描述
  • 最小分类样本(min_samples_split)类似leaf_size,最小包含多少个样本,最多包含多少个样本。scikitlearn中有这个参数。

4.2 引出两个关键问题

  • 从刚才的决策树看,我们是否可以先根据“拥有房产”或“婚姻情况”属性先进行划分?
  • 年收入为什么选择以97.5来进行划分,而不是其他值?

构建决策树的关键步骤就是分裂属性,分裂属性是指在某个节点按照某一类特征属性的不同划分构建不同的分支,其目标就是让各个分裂子集(一个分裂子类中待分类的项)尽可能的属于同一个类别。


  • why尽可能的属于同一个类别?
    要不然会很麻烦,两个子节点都需要分下去。

  • 关键是如何确立分割点?
    观察,离散值(是否单身):二分之一;连续值(收入),多分之一。

  • 问题引出:哪一个特征信息增益越大,我们就按照哪一个特征进行划分。

无参数模型,训练的是树,跟决策相关,不同的条件,不同的选择
有些资料说是分裂属性,但这里主张分割样本
过程也就是属性取不同的值,然后不断把样本集缩小
从树根开始不断的做出决断

4.3 构建决策树的规则

构建决策树的规则如下:

  • 将数据集中的每一个特征看成是一种划分可能。(对于划分方式,可以分为离散型与连续性属性。)
    1. 对于离散型属性,每一个类别可以划分为一个节点(多叉树),或者属于类别A与不属于类别A(二叉树)。
    2. 对于连续性属性,可以划分为大于等于A与小于A。
  • 从根节点开始,选择可获的最大信息增益(IG-Information gain)的特征进行节点划分。
  • 划分的目的就是,可以在每次划分时,实现对信息增益的最大化。

最大信息增益定义如下:
I G ( D p , f ) = I ( D p ) − ∑ j = 1 n N j N p I ( D j ) IG(D_p, f) = I(D_p) - \sum_{j=1}^{n}\frac{N_j}{N_p}I(D_j) IG(Dp,f)=I(Dp)j=1nNpNjI(Dj)
在这里插入图片描述

  • f f f 划分的特征
  • D p D_p Dp 父节点
  • D j D_j Dj 第j个子节点
  • N p N_p Np 父节点中样本的数量
  • N j N_j Nj 第j个子节点样本的数量
  • I I I 不纯度度量标准

实际上,信息增益就是父节点的不纯度减去所有子节点不纯度
出于简化与缩小组合搜索空间的考虑,很多库**(scikit-learn)实现的都是二叉决策树**,每个父节点分为两个子节点(左节点与右节点):
I G ( D p , f ) = I ( D p ) − N l e f t N p I ( D l e f t ) − N r i g h t N p I ( D r i g h t ) IG(D_p, f) = I(D_p) - \frac{N_{left}}{N_p}I(D_{left}) - \frac{N_{right}}{N_p}I(D_{right}) IG(Dp,f)=I(Dp)NpNleftI(Dleft)NpNrightI(Dright)
从上可以看出,子节点的不纯度越低,信息增益就越大。因而,我们分裂属性的方式,就是应该使得子节点的不纯度越低越好。

在这里插入图片描述
比如按照年收入划分,不纯度信息肯定是固定的了。
比如十叉树,空间搜索特别庞大。不利于实现和操作

5. 不纯度度量标准

不纯度信息可以采用如下方式度量:

  • 信息熵(Entropy)
  • 基尼系数(Gini Index)
  • 错误率(classification error)

  • 习惯说,不纯度越高,信息熵越高。btw,正比好理解。
  • 所以,我们衡量的依据:通过哪一个特征能够让我们哪个节点的不纯度最低,就是信息熵最低,(纯度最高),就更好衡量。
  • 失衡度越高,我们预测出来的信心指数会越高。
  • 一个子节点所有样本都属于同一个类别,那我们预测出来的概率就是100%,就是一个非常高的信心指数。
  • 决策树划分目的:就是让不纯度达到最低,信息熵达到最小

5.1 信息熵

I H ( t ) = − ∑ i = 1 c p ( i ∣ t ) l o g 2 p ( i ∣ t ) I_H(t) = -\sum_{i=1}^{c}p(i|t)log_2p(i|t) IH(t)=i=1cp(it)log2p(it)

  • p(i|t) 节点t中,属于类别c的样本占特定节点t中样本总数的比例(概率)。

如果样本以相同的比例分布于不同的类别时,熵的值最大。如果所有的样本都属于同一个类别,则熵为0,此时,不纯度最低。

5.2 基尼系数

I G ( t ) = 1 − ∑ i = 1 c p ( i ∣ t ) 2 I_G(t) = 1 - \sum_{i=1}^{c}p(i|t)^2 IG(t)=1i=1cp(it)2
同样,与熵类似,当样本以相同的比例分布于不同的类别时,基尼系数的值最大。当所有的样本都属于同一个类别,则基尼系数为0,此时,不纯度最低。

参阅:Wikipedia中关于基尼系数的描述
https://zh.wikipedia.org/wiki/基尼系数

经济学中:基尼系数的实际数值只能介于这两种极端情况,即0~1之间。基尼系数越小,年收入分配越平均;基尼系数越大,年收入分配越不平均。

5.3 错误率

I E ( t ) = 1 − m a x { p ( i ∣ t ) } I_E(t) = 1 - max\{p(i|t)\} IE(t)=1max{p(it)}

通常不建议使用错误率在决策树的构建过程中使用,因为其对节点中类别样本数量的变动不敏感。
例如,在父节点p中,存在两个类别,各40个样本,父节点进行划分,分为两个子节点,如下:
在这里插入图片描述

BTW: 很明显看出B的不纯度最低,信息熵最低,最好…

然而,在A,B两种划分情况下,使用错误率得到的信息增益都是相同的(信息增益都是0.25)。
在这里插入图片描述

如果使用基尼系数,A划分的方式,信息增益为0.125,B划分的方式,信息增益为0.16,因此,B划分的方式,子节点处类别的不纯度更低,信息增益更大,所以,B划分的方式更好。
在这里插入图片描述

使用信息熵评估时,A划分的方式,信息增益为0.19,B划分的方式,信息增益为0.31,同样是B划分的方式更好。
在这里插入图片描述

5.4 程序解释(with codes)

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.family"] = "SimHei"
mpl.rcParams["axes.unicode_minus"] = False

# 生成概率的范围
p = np.linspace(0.01, 0.99, 100)

# 计算基尼系数值。
def gini(p):
    return 1 - p ** 2 - (1 - p) ** 2

# 计算信息熵。
def entropy(p):
    return - p * np.log2(p) - (1 - p) * np.log2(1 - p)

# 计算错误率
def error(p):
    return 1 - np.max([p, 1 - p], axis=0)

x = np.linspace(0.01, 0.99, 200)
# 计算信息熵
en = entropy(x)
# 将信息熵进行缩放。因为信息熵的取值范围为[0, 1],而基尼系数与错误率的取值范围为[0, 0.5],为了能够统一区间,
# 所以进行缩放,以便于可视化观察效果。
en2 = en * 0.5
# 计算错误率。
err = error(x)
# 计算基尼系数
g = gini(x)
fig = plt.figure()
for i, lab, ls, c, in zip([en, en2, g, err], ["信息熵", "信息熵(缩放)", "基尼系数", "错误率"], 
        ["-", ":", "--", "-."], ["r", "g", "b", "y"]):
    # 分别绘制信息熵,基尼系数与错误率的曲线,随着概率的变化而发生改变。
    plt.plot(x, i, label=lab, linestyle=ls, lw=2, color=c)
    plt.legend(loc="upper center", bbox_to_anchor=(0.5, 1.15),
            ncol=4, fancybox=True, shadow=False)
    plt.axhline(y=0.5, linewidth=1, color='k', linestyle="--")
    plt.axhline(y=1.0, linewidth=1, color='k', linestyle="--")
    plt.ylim([0, 1.1])
    plt.xlabel("p(i=1)")
    plt.ylabel("纯度系数")
plt.show()

在这里插入图片描述

  • 16
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值