决策树的概念
决策树是一种非参数的监督学习方法,既可以用于分类,也可以用于回归。
决策树的目标是创建一个模型,从数据特征中进行学习,进而推断出简单决策规则,用来预测目标变量的值
决策树的决策过程就是从根节点开始,测试待分类项中对应的特征属性,并按照其值选择输出分支,直到叶子节点,将叶子节点的存放的类别作为决策结果。
# 个人理解
就是按照一定的决策树构建规则来构建一个决策树,
将数据集中的各个属性(特征)转化为决策树的分支
和根(按照决策树的构建规则选择根和分支)
转化规则,将所有的属性当做一个一个的问题,n个属性,就有n个问题,
分为n步来问,每个步骤问一个问题,每个步骤得到一个回答,
根据回答进行分支,然后继续选择属性来问问题
举个例子,如下所示,实际上也是一个决策树的过程,只是这棵树,已经被构建完毕>>
女儿:多大年纪了?
母亲:26
女儿:长的帅不帅?
母亲:挺帅的。
女儿:收入高不?
母亲:不算很高,中等收入。
女儿:是公务员吗?
母亲:是,在税务局上班呢。
女儿:那好,我去见见。
图形化展示决策树的概念>>
如何构建决策树
决策树可以看做是由若干个点(根节点和其他节点)构成,根节点存放着所有的数据(整个数据集),然后从根节点开始,从数据集中选择属性,从属性中找出分裂规则(问题),根据属性中的问题,对于整个数据集进行分裂,然后不断的找出下一个属性,得到问题,再分裂,直到满足以下条件:
- 树达到指定的最大深度(max_depth),每次分割视为一层。
- 所有叶子节点中的样本属于同一个类别(足够纯)。
- 所有叶子节点包含的样本数量小于指定的最小分类样本(min_samples_split)数量。
决策树构建规则
具上述所说,那如何从诸多属性中找到合适的属性,作为跟节点,然后再找到其他属性作为第一层,第二层,第n层的节点呢,以及如何从属性中得到问题,如下所示:
1. 将数据集中的每一个特征看成是一种划分可能。
* 对于划分方式,可以分为离散型与连续性属性。
* 离散型属性,每一个类别可以划分为属于类别A与不属于类别A(二叉树)。
* 连续性属性,可以划分为大于等于A与小于A。
2. 从根节点开始,选择可获的(最大信息增益)的特征进行节点划分。
3. 划分的目的就是,可以在每次划分时,实现对信息增益的最大化
所谓之最大信息增益:
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 不纯度度量标准
总结
实际上,信息增益就是父节点的不纯度减去所有子节点不纯度。
信息熵与比特化
比特化
现在有一组由X变量组成的序列:BACADDCBAC……,如果现在希望将这个序列进行网络传输,我们可以将每种取值使用两个位进行编码:
编码结束之后,原本的BACADDCBAC就转化为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=2∗41+2∗41+2∗41+2∗41=2
不过,如果当变量X的取值概率不同时,不同的编码方式可能会带来不同的编码长度
我们依然可以使用一开始的编码方式,但是这样一来,长度无法降低。
考虑到x取值的不均衡性,为了降低编码长度,我们采用新的编码方式。
这样的编码方式,可以实现,在不混淆取值意义的前提下,当A的概率最高的时候,它的长度是最小的,保证了整体的长度减少。
那这个时候,我们的每个字符的平均编码长度为:
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=1∗21+2∗41+3∗81+3∗81=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=−log221∗21−log241∗41−log281∗81−log281∗81=1.75
信息熵
具上述所示,我们的随机变量X可能有m个值,那么这些值的出现的概率就是p1,p2,p3,…pn
对于一组序列信息来讲,可以使用这些变量的期望来表示每个变量需要多少个比特位来描述信息
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)=−p1∗log2p1−p2∗log2p2−p3∗log2p3−……−pm∗log2pm
以上的表示就是变量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
为了方便理解,我们可以认为:
- 信息熵=不确定性=样本均衡性=不纯度
- 反之,不确定性越大,信息熵越大,不纯度越大
得到了信息熵(不纯度)的公式,我们就可以通过这个公式去一个一个的求信息增益
出于简化与缩小组合搜索空间的考虑,很多库实现的都是二叉决策树,每个父节点分为两个子节点(左节点与右节点):
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)
从上可以看出,子节点的不纯度越低,信息增益就越大。因而,我们分裂属性的方式,就是应该使得子节点的不纯度越低越好。
决策树思路总结
以上种种,我们可以总结为:
- 得到经历过数据清洗转化,可以用来建模的【样本数据集】,这个数据集包含样本和标签
- 将数据集中样本的属性拿出来,分析属性,找出离散值和连续值属性
- 对于这些离散值和连续值求最大信息增益,作为根节点,并且找到问题
- 根据问题,从根节点中分裂,然后如果没有达到停止构建的条件,就继续往下构建,继续对能够分裂的节点进行求最大增益,分裂
- 就这样,不断的求最大增益,不断的得到各个节点,最终,构建完整个决策树
- 然后开始用预测样本进行预测,这个预测的样本,分为俩种:
- 类型是分类,那就按照决策树的规则从根节点开始,层层通过问题,走到是同类回答的节点上,这个节点的类型(要是不完全纯粹,那就是最多的)就是预测样本的类型
- 类型是回归,那就也按照决策树的规则从根节开始,层层通过问题,走到是同类回答的节点上,求这个这个节点上的平均值,就是这个预测样本的平均值
求最大信息增益的细节(用上例的是否可以偿还债务来说明,一共十个样本)
先从第一个属性开始(假设是否拥有房产作为父节点):
分析:
1. 父节点,这个属性对应的标签(无法偿还债务),是(0.3),否(0.7)
2. 这个属性有俩个值(是否有房产),我们按照是否有房产作为问题,可以得到俩个节点
3. 这样,第一个子节点(根据是有房产得到),标签值为 否的为概率为1,为是的概率为0
4. 第二个子节点(根据没有房产得到),标签值的概率 为 三个为是,三个为否,就是都是0.5
所以:
I
E
(
D
有
房
产
)
=
−
4
/
4
∗
l
o
g
2
4
/
4
−
0
∗
l
o
g
2
0
=
0
I_E(D_{有房产}) = -4/4 * log_24/4 - 0 * log_20 = 0
IE(D有房产)=−4/4∗log24/4−0∗log20=0
I
E
(
D
无
房
产
)
=
−
0.5
∗
l
o
g
2
0.5
−
0.5
∗
l
o
g
2
0.5
=
1
I_E(D_{无房产}) = -0.5 * log_20.5 - 0.5 * log_20.5 = 1
IE(D无房产)=−0.5∗log20.5−0.5∗log20.5=1
因此,属性“拥有房产”的信息增益为:
I
G
E
(
拥
有
房
产
)
=
0.88
−
0.4
∗
0
−
0.6
∗
1
=
0.28
IG_E(拥有房产) = 0.88 - 0.4 * 0 - 0.6 * 1 = 0.28
IGE(拥有房产)=0.88−0.4∗0−0.6∗1=0.28
同理:
I
G
E
(
婚
姻
)
=
0.205
IG_E(婚姻) = 0.205
IGE(婚姻)=0.205
将属性年收入作为父节点,然后发现这个属性是一个 连续值
为了方便处理,我们需要将连续值进行排序
然后分析值,发现,经过排序后的属性对应的标签值,有俩个分界点,求这俩个分界点的平均值,作为分界线,分别求出对应的信息熵
I
E
(
D
收
入
<
80
)
=
−
1
∗
l
o
g
2
1
−
0
∗
l
o
g
2
0
=
0
I_E(D_{收入<80}) = -1 * log_21 - 0 * log_20 = 0
IE(D收入<80)=−1∗log21−0∗log20=0
I
E
(
D
收
入
>
=
80
)
=
−
3
/
8
∗
l
o
g
2
3
/
8
−
5
/
8
∗
l
o
g
2
5
/
8
=
0.954
I_E(D_{收入>=80}) = -3/8 * log_23/8 - 5/8 * log_25/8 = 0.954
IE(D收入>=80)=−3/8∗log23/8−5/8∗log25/8=0.954
I
G
E
(
收
入
=
80
)
=
0.88
−
0.2
∗
0
−
0.8
∗
0.954
=
0.117
IG_E(收入=80) = 0.88 - 0.2 * 0 - 0.8 * 0.954 = 0.117
IGE(收入=80)=0.88−0.2∗0−0.8∗0.954=0.117
同样的方式:
I
E
(
D
收
入
<
97.5
)
=
−
0.4
∗
l
o
g
2
0.4
−
0.6
∗
l
o
g
2
0.6
=
0.97
I_E(D_{收入<97.5}) = -0.4 * log_20.4 - 0.6 * log_20.6 = 0.97
IE(D收入<97.5)=−0.4∗log20.4−0.6∗log20.6=0.97
I
E
(
D
收
入
>
=
97.5
)
=
−
1
∗
l
o
g
2
1
−
0
∗
l
o
g
2
0
=
0
I_E(D_{收入>=97.5}) = -1 * log_21 - 0 * log_20 = 0
IE(D收入>=97.5)=−1∗log21−0∗log20=0
I
G
E
(
收
入
=
97.5
)
=
0.88
−
0.5
∗
0.97
−
0.5
∗
0
=
0.395
IG_E(收入=97.5) = 0.88 - 0.5 * 0.97 - 0.5 * 0 = 0.395
IGE(收入=97.5)=0.88−0.5∗0.97−0.5∗0=0.395
从上面的结果中可知,相比于收入=80来说,收入=97.5可以获得更大的信息增益。
所以,我们知道,根据最大信息增益,我们得到我们需要年收入作为根节点,拥有房产是第二个,··········
小知识点:
上述,我们在衡量不纯度的时候,都是使用信息熵。
实际上,衡量信息熵的方式有三种:
1. 信息熵
2. 基尼系数
3. 错误率
备注:
* 在决策树中,错误率不被使用;
* 由于错误率在特定的时候会得到相同的信息增益,不利于我们处理
以上,就是整个决策树的实现思路;
决策树代码实现(核心代码)
建立决策树的主要是以下三种算法
- ID3
- C4.5
- CART(Classification And Regression Tree)
# sklearn.tree提供树形结构的模块
# DecisionTreeClassifier用于分类的决策树。
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=None).fit(X, y)
上边一大推理论,实际上,sklearn都为我们实现了,、
我们只需要调用相关的函数就可以实现
# 小结(1)
决策树虽然既可以适用于回归算法,也可以适用于分类算法
但是,相对来说,适用于回归情况的时候,会有突变的情况发生,效果并不好
# 小结(2)
在调用训练的时候, 决策树的深度对于决策树影响较大,需要谨慎调整
# 小结(3)
决策树不受数据标准化的影响