文章目录
决策树学习采用的是自顶向下的递归方法,其基本思想是以信息熵为度量构造一颗熵值下降最快的树,到叶子节点处,熵值为0。其具有可读性、分类速度快的优点,是一种有监督学习。最早提及决策树思想的是Quinlan在1986年提出的ID3算法和1993年提出的C4.5算法,以及Breiman等人在1984年提出的CART算法。
注:熵是描述系统混乱的量,熵越大说明系统越混乱,携带的信息就越少,熵越小说明系统越有序,携带的信息越多。
决策树过程
决策树(decision tree):是一种基本的分类与回归方法,此处主要讨论分类的决策树。
决策树通常有三个步骤:特征选择、决策树的生成、决策树的修剪。
从根节点开始,对实例的某一特征进行测试,根据测试结果将实例分配到其子节点,此时每个子节点对应着该特征的一个取值,如此递归的对实例进行测试并分配,直到到达叶节点,最后将实例分到叶节点的类中。
- 特征选择:
特征选择表示从众多的特征中选择一个特征作为当前节点分裂的标准,如何选择特征有不同的量化评估方法,从而衍生出不同的决策树,如ID3(通过信息增益选择特征)、C4.5(通过信息增益比选择特征)、CART(通过Gini指数选择特征)等。
目的(准则):使用某特征对数据集划分之后,各数据子集的纯度要比划分钱的数据集D的纯度高(也就是不确定性要比划分前数据集D的不确定性低) - 决策树的生成
根据选择的特征评估标准,从上至下递归地生成子节点,直到数据集不可分则停止决策树停止生长。这个过程实际上就是使用满足划分准则的特征不断的将数据集划分成纯度更高,不确定行更小的子集的过程。 - 决策树的裁剪
决策树容易过拟合,一般需要剪枝来缩小树结构规模、缓解过拟合。
重点说一下特征选择。
ID3
熵
在信息论中,熵(entropy)是随机变量不确定性的度量,也就是熵越大,则随机变量的不确定性越大。设X是一个有限个值得离散随机变量,其概率分布为:
P
(
X
=
x
i
)
=
p
i
,
i
=
1
,
2
,
⋯
,
n
P(X=x_{i}) = p_{i}, \qquad i=1,2,\cdots ,n
P(X=xi)=pi,i=1,2,⋯,n
则随机变量X的熵定义为:
H
(
X
)
=
−
∑
i
=
1
n
p
i
l
o
g
p
i
H(X) = -\sum_{i=1}^{n}p_{i}logp_{i}
H(X)=−i=1∑npilogpi
条件熵
设有随机变量(X, Y),其联合概率分布为:
P
(
X
=
x
i
,
Y
=
y
−
i
)
=
p
i
j
,
i
=
1
,
2
,
⋯
,
n
;
j
=
1
,
2
,
⋯
,
m
.
P(X=x_{i},Y=y-{i})=p_{ij}, \qquad i=1,2,\cdots,n;j=1,2,\cdots,m.
P(X=xi,Y=y−i)=pij,i=1,2,⋯,n;j=1,2,⋯,m.
条件熵H(Y|X)表示在已知随机变量X的条件下,随机变量Y的不确定性。随机变量X给定的条件下随机变量Y的条件熵H(Y|X),定义为X给定条件下Y的条件概率分布的熵对X的数学期望:
H
(
Y
∣
X
)
=
∑
i
=
1
n
p
i
H
(
Y
∣
X
=
x
i
)
H(Y \mid X)=\sum_{i=1}^{n} p_{i}H(Y \mid X=x_{i})
H(Y∣X)=i=1∑npiH(Y∣X=xi)
其中,
p
i
=
P
(
X
=
x
i
)
,
i
=
1
,
2
,
⋯
,
n
其中,p_{i}=P(X=x_{i}),i=1,2,\cdots,n
其中,pi=P(X=xi),i=1,2,⋯,n
当熵和条件熵中的概率由数据估计得到时(如极大似然估计),所对应的熵与条件熵分别称为经验熵和经验条件熵。
信息增益
信息增益表示,由于得知特征A的信息后,数据集D的分类不确定性减少的程度,定义为:
G
a
i
n
(
D
,
A
)
=
H
(
D
)
−
H
(
D
∣
A
)
Gain(D,A)=H(D)-H(D \mid A)
Gain(D,A)=H(D)−H(D∣A)
即集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(H|A)之差。
划分时,信息增益大的作为划分特征,说明使用该特征后划分得到的子集纯度越高,即不确定性越小。因此我们总是选择当前使得信息增益最大的特征来划分数据集。
缺点:信息增益偏向取值较多的特征(原因:当特征的取值较多时,根据此特征划分更容易得到纯度更高的子集,因此划分后的熵更低,即不确定性更低,因此信息增益更大)
https://zhuanlan.zhihu.com/p/484546632
C4.5
上面已经说了ID3的缺点,信息增益准则对可取值数目较多的属性有所偏好,为减少这种偏好带来的不利影响,C4.5不直接使用信息增益,而是使用“增益率”来选择最优划分属性。同时,C4.5对连续值也进行了处理。
CART(Classification And Regression Tree)
CART,又名分类回归树,CART既能是分类树,又能是回归树;分裂的目的是为了能够让数据变纯,当CART是分类树时,采用GINI值作为节点分裂的依据;当CART是回归树时,采用样本的最小方差作为节点分裂的依据,节点越不纯,节点分类或者预测的效果就越差;CART是一棵二叉树。
分类
GINI值的计算公式:
G
I
N
I
=
1
−
∑
i
ϵ
I
n
p
i
(
1
−
p
i
)
=
1
−
∑
i
ϵ
I
n
p
i
2
GINI=1-\sum_{i \epsilon I} ^{n}p_{i}(1-p_{i})=1-\sum_{i \epsilon I} ^{n}p_{i}^{2}
GINI=1−iϵI∑npi(1−pi)=1−iϵI∑npi2
其中,n表示类别数,p表示不同类别的概率。节点越不纯,GINI值越大。以二分类为例,如果节点的所有数据只有一个类别,则GINI=0,如果两类数量相同,则GINI=1/2。
那么,样本集合根据某特征被分割成多部分,CART是二叉树,所以是两部分,GINI信息增益:
G
a
i
n
=
∑
i
ϵ
I
p
i
∗
G
I
N
I
i
Gain=\sum_{i \epsilon I}p_{i}*GINI_{i}
Gain=iϵI∑pi∗GINIi
回归
回归方差计算公式:
σ
=
∑
i
ϵ
I
(
x
i
−
u
)
2
=
∑
i
ϵ
I
x
i
2
−
n
u
2
\sigma = \sqrt{\sum_{i\epsilon I}(x_{i}-u)^{2}}=\sqrt{\sum_{i\epsilon I}x_{i}^{2}-nu^{2}}
σ=iϵI∑(xi−u)2=iϵI∑xi2−nu2
方差越大,表示该节点的数据越分散,预测的效果就越差。如果一个节点的所有数据都相同,那么方差就为0,此时可以很肯定得认为该节点的输出值;如果节点的数据相差很大,那么输出的值有很大的可能与实际值相差较大。
回归信息增益:
G
a
i
n
=
∑
i
ϵ
I
σ
i
Gain=\sum_{i \epsilon I}\sigma_{i}
Gain=iϵI∑σi
CART如何分裂成一棵二叉树?
节点的分裂分为两种情况,连续型的数据和离散型的数据。
CART对连续型属性的处理与C4.5差不多,通过最小化分裂后的GINI值或者样本方差寻找最优分割点,将节点一分为二,在这里不再叙述,详细请看C4.5。(????)
对于离散型属性,理论上有多少个离散值就应该分裂成多少个节点。但CART是一棵二叉树,每一次分裂只会产生两个节点,怎么办呢?很简单,只要将其中一个离散值独立作为一个节点,其他的离散值生成另外一个节点即可。这种分裂方案有多少个离散值就有多少种划分的方法,举一个简单的例子:如果某离散属性有三个离散值X,Y,Z,则该属性的分裂方法有{X}、{Y,Z},{Y}、{X,Z},{Z}、{X,Y},分别计算每种划分方法的基尼值或者样本方差确定最优的分裂方法。
例子
以属性“职业”为例,一共有三个离散值,“学生”、“老师”、“上班族”。该属性有三种划分的方案,分别为{“学生”}、{“老师”、“上班族”},{“老师”}、{“学生”、“上班族”},{“上班族”}、{“学生”、“老师”},分别计算三种划分方案的子节点GINI值或者样本方差,选择最优的划分方法,如下图所示:
第一种划分方法:{“学生”}、{“老师”、“上班族”}
预测是否已婚(分类):
G
a
i
n
=
∑
i
ϵ
I
p
i
∗
G
I
N
I
i
=
3
/
7
(
1
−
(
(
2
/
3
)
2
+
(
1
/
3
)
2
)
)
+
4
/
7
(
1
−
(
(
3
/
4
)
2
+
(
1
/
4
)
2
)
)
=
0.4
Gain=\sum_{i \epsilon I}p_{i}*GINI_{i}=3/7(1-((2/3)^{2}+(1/3)^{2}))+4/7(1-((3/4)^{2}+(1/4)^{2}))=0.4
Gain=iϵI∑pi∗GINIi=3/7(1−((2/3)2+(1/3)2))+4/7(1−((3/4)2+(1/4)2))=0.4
预测年龄(回归):
G
a
i
n
=
∑
i
ϵ
I
σ
i
=
1
2
2
+
1
8
2
+
2
1
2
−
3
∗
1
7
2
+
2
6
2
+
4
7
2
+
3
6
2
+
2
9
2
−
4
∗
32.
5
2
=
34.71
Gain=\sum_{i \epsilon I}\sigma_{i}=\sqrt{12^{2}+18^{2}+21^{2}-3*17^{2}}+\sqrt{26^{2}+47^{2}+36^{2}+29^{2}-4*32.5^{2}}=34.71
Gain=iϵI∑σi=122+182+212−3∗172+262+472+362+292−4∗32.52=34.71
第二种划分方法:{“老师”}、{“学生”、“上班族”}
预测是否已婚(分类):
G
a
i
n
=
∑
i
ϵ
I
p
i
∗
G
I
N
I
i
=
2
/
7
(
1
−
(
(
1
/
2
)
2
+
(
1
/
2
)
2
)
)
+
5
/
7
(
1
−
(
(
3
/
5
)
2
+
(
2
/
5
)
2
)
)
=
0.49
Gain=\sum_{i \epsilon I}p_{i}*GINI_{i}=2/7(1-((1/2)^{2}+(1/2)^{2}))+5/7(1-((3/5)^{2}+(2/5)^{2}))=0.49
Gain=iϵI∑pi∗GINIi=2/7(1−((1/2)2+(1/2)2))+5/7(1−((3/5)2+(2/5)2))=0.49
预测年龄(回归):
G
a
i
n
=
∑
i
ϵ
I
σ
i
=
2
6
2
+
2
9
2
−
2
∗
27.
5
2
+
1
2
2
+
1
8
2
+
4
7
2
+
3
6
2
+
2
1
2
−
5
∗
26.
8
2
=
16.36
Gain=\sum_{i \epsilon I}\sigma_{i}=\sqrt{26^{2}+29^{2}-2*27.5^{2}}+\sqrt{12^{2}+18^{2}+47^{2}+36^{2}+21^{2}-5*26.8^{2}}=16.36
Gain=iϵI∑σi=262+292−2∗27.52+122+182+472+362+212−5∗26.82=16.36
预测是否已婚(分类):
G
a
i
n
=
∑
i
ϵ
I
p
i
∗
G
I
N
I
i
=
2
/
7
(
1
−
1
)
+
5
/
7
(
1
−
(
(
3
/
5
)
2
+
(
2
/
5
)
2
)
)
=
0.34
Gain=\sum_{i \epsilon I}p_{i}*GINI_{i}=2/7(1-1)+5/7(1-((3/5)^{2}+(2/5)^{2}))=0.34
Gain=iϵI∑pi∗GINIi=2/7(1−1)+5/7(1−((3/5)2+(2/5)2))=0.34
预测年龄(回归):
G
a
i
n
=
∑
i
ϵ
I
σ
i
=
4
7
2
+
3
6
2
−
2
∗
41.
5
2
+
1
2
2
+
1
8
2
+
2
6
2
+
2
9
2
+
2
1
2
−
5
∗
21.
2
2
=
21.14
Gain=\sum_{i \epsilon I}\sigma_{i}=\sqrt{47^{2}+36^{2}-2*41.5^{2}}+\sqrt{12^{2}+18^{2}+26^{2}+29^{2}+21^{2}-5*21.2^{2}}=21.14
Gain=iϵI∑σi=472+362−2∗41.52+122+182+262+292+212−5∗21.22=21.14
综上,如果想预测是否已婚,则选择第三种划分,{“上班族”}、{“学生”、“老师”}的划分方法;如果想预测年龄,则选择第二种划分,{“老师”}、{“学生”、“上班族”}的划分方法。
三种决策树算法总结如下:
ID3 | C4.5 | CART | |
---|---|---|---|
是否是二叉树 | NO | NO | YES |
特征 | 离散 | 离散+连续 | 离散+连续 |
是否可以分类 | YES | YES | YES |
是否可以回归 | NO | YES | |
指标趋向 | 越大越好 | 越小越好 | |
分类指标 | 信息增益 | 信息增益率 | 基尼系数/方差 |
决策树停止的条件
- 大于决策树最大深度,max_depth。
- 小于内部节点再划分所需最小样本数,min_samples_split。
设min_samples_split=3,一个叶子节点a中剩余的样本数位5,则停止划分。 - 小于叶节点最少样本数,min_samples_leaf。
设min_samples_leaf=3,如果划分出的新叶子节点剩余样本数小于3,那么撤销这步划分。 - 大于最大叶节点数,max_leaf_nodes。
设max_leaf_nodes=5,当划分出超过五个叶子节点时,撤销这步划分操作。 - 小于节点划分不纯度,min_impurity_split。
当Gini系数、熵(Entropy)、错误率,小于 min_impurity_split时,不再生成新的叶子节点。样本集的基尼指数大于阈值,信息增益/信息增益比小于阈值。一般不会设置这个参数,依靠上面4个停止条件即可。
决策树的优缺点
- 优点
1)具有可读性,如果给定一个模型,那么依据所产生的决策树很容易推理出相应的逻辑表达。
2)分类速度快,能在相对短的时间内能够对大型数据源做出可行且效果良好的结果。 - 缺点
对未知的测试数据未必有好的分类、泛化能力差,即可能发生过拟合现象,此时可采用剪枝或随机森林。
剪枝处理
剪枝(pruning)是决策树学习算法对付“过拟合”的主要手段。在决策树学习中,为了尽可能正确分类训练样本,节点划分过程将不断重复,有时会造成决策树分支过多,这时就可能因训练样本学得“太好了” 了,以至于把训练集自身的特点当做所有数据都具有的一般性质而导致过拟合。因此,可通过主动减掉一些分支来降低过拟合的风险。
决策树剪枝的基本策略有“预剪枝”和“后剪枝”。
预剪枝
预剪枝是指在决策树生成过程中,对每个节点在划分前进行预估,若当前节点的划分不能带来决策树泛化性的提升,则停止划分,并将当前节点标记为叶节点。
后剪枝
后剪枝是先从训练集生成一颗完整的决策树,然后自底向上地对非叶节点进行考察,若将该节点对应的子树替换为叶节点能带来决策树泛化性的提升,则将该子树替换为叶节点。
决策树
code
DecisionTreeClassifier()创建一个决策树模型,其函数的参数含义如下所示:
- criterion:gini或者entropy,前者是基尼系数,后者是信息熵。
- splitter: best or random 前者是在所有特征中找最好的切分点,后者是在部分特征中,默认的”best”适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐”random” 。
- max_features:None(所有),log2,sqrt,N特征小于50的时候一般使用所有的
- max_depth:int or None, optional (default=None) 设置决策随机森林中的决策树的最大深度,深度越大,越容易过拟合,推荐树的深度为:5-20之间。
- min_samples_split:设置结点的最小样本数量,当样本数量可能小于此值时,结点将不会在划分。
- min_samples_leaf: 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。
- min_weight_fraction_leaf: 这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝默认是0,就是不考虑权重问题。
- max_leaf_nodes: 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。
- class_weight: 指定样本各类别的的权重,主要是为了防止训练集某些类别的样本过多导致训练的决策树过于偏向这些类别。这里可以自己指定各个样本的权重,如果使用“balanced”,则算法会自己计算权重,样本量少的类别所对应的样本权重会高。
- min_impurity_split: 这个值限制了决策树的增长,如果某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值则该节点不再生成子节点。即为叶子节点 。
基于决策树的特征重要性:加权不纯度的减少
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.externals.six import StringIO
from sklearn import tree
import pydotplus
clf = DecisionTreeClassifier()
x = [[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3],
[1,1,2,2,1,1,1,2,1,1,1,1,2,2,1],
[1,1,1,2,1,1,1,2,2,2,2,2,1,1,1],
[1,2,2,1,1,1,2,2,3,3,3,2,2,3,1]
]
y = [1,1,2,2,1,1,1,2,2,2,2,2,2,2,1]
x = np.array(x)
x = np.transpose(x)
clf.fit(x,y)
print(clf.feature_importances_)
feature_name = ['A1','A2','A3','A4']
target_name = ['1','2']
dot_data = StringIO()
tree.export_graphviz(clf,out_file = dot_data,feature_names=feature_name,
class_names=target_name,filled=True,rounded=True,
special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_pdf("WineTree.pdf")
print('Visible tree plot saved as pdf.')
随机森林
RandomForestClassifier(labelCol=“label_new”, featuresCol=“features”, seed = 8464,
numTrees=200, cacheNodeIds = True, subsamplingRate = 0.7)
XGBoost
决策树试题总结
下面关于ID3算法中说法错误的是()
A. ID3算法要求特征必须离散化
B. 信息增益可以用熵,而不是GINI系数来计算
C. 选取信息增益最大的特征,作为树的根节点
D. ID3算法是一个二叉树模型
注:ID3(Iterative Dichotomiser 3)生成树的时候,是选择具有最大信息增益的那个特征作为树的根节点,其子节点分别是根节点特征的不同取值。显然,特征的取值可以是两个,也可以是多个,所以可以知道ID3产生的树不一定是二叉树。
参考
https://www.cnblogs.com/yonghao/p/5135386.html
https://blog.csdn.net/tinkle181129/article/details/80231871
gbdt全称梯度下降树,在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一,在前几年深度学习还没有大火之前,gbdt在各种竞赛是大放异彩。原因大概有几个,一是效果好。二是即可以用于分类也可以用于回归。三是可以筛选特征。
首先gbdt 是通过采用加法模型(即基函数的线性组合),以及不断减小训练过程产生的残差来达到将数据分类或者回归的算法。
待解决问题:
gbdt 的算法的流程?
gbdt 如何选择特征 ?
gbdt 如何构建特征 ?
gbdt 如何用于分类?
gbdt 通过什么方式减少误差 ?
gbdt的效果相比于传统的LR,SVM效果为什么好一些 ?
gbdt 如何加速训练?
gbdt的参数有哪些,如何调参 ?
gbdt 实战当中遇到的一些问题 ?
gbdt的优缺点 ?
- 决策树学习的本质:从训练集中归纳出一组分类规则,或者说是由训练数据集估计条件概率模型。
- 决策树学习的损失函数:正则化的极大似然函数
- 决策树学习的测试:最小化损失函数
- 决策树学习的目标:在损失函数的意义下,选择最优决策树的问题。
决策树怎么训练模型,需要训练吗,一次性构建。
增加训练轮数能改善欠拟合
code
prediction_df = bestModel.transform(test_set)
prediction_df.columns
'''
['search_times_1',
'search_times_3',
'label',
'features',
'rawPrediction',
'probability',
'prediction']
'''
#features
prediction_df.select('features').show()
'''
+--------------------+
| features|
+--------------------+
|(77,[0,1,19,22,25...|
|(77,[0,1,19,22,25...|
|(77,[0,1,19,22,24...|
|(77,[0,1,18,19,21...|
|(77,[0,1,18,19,21...|
|(77,[0,1,18,19,21...|
'''
prediction_df.select('rawPrediction').show(3,False)
'''
+----------------------------------------+
|rawPrediction |
+----------------------------------------+
|[1.6730001626845854,-1.6730001626845854]|
|[1.6812937422652734,-1.6812937422652734]|
|[1.6730001626845854,-1.6730001626845854]|
+----------------------------------------+
only showing top 3 rows
'''
#probability
prediction_df.select('probability').show(3,False)
'''
+-----------------------------------------+
|probability |
+-----------------------------------------+
|[0.9659736169151563,0.034026383084843737]|
|[0.9665146195117272,0.033485380488272765]|
|[0.9659736169151563,0.034026383084843737]|
+-----------------------------------------+
only showing top 3 rows
'''
#prediction
prediction_df.select('prediction').show()
'''
+----------+
|prediction|
+----------+
| 0.0|
| 1.0|
| 0.0|
'''