本文参考了知乎很多大佬的文章,自己用自己的语言整理的一下,相信通过这篇文章,你会对树模型有深刻的认识
本文持续更新
前置知识:
泰勒公式
- 带皮亚诺余项的泰勒公式
若f(x)在 x 0 x_0 x0处有n阶导数,那么他的n阶泰勒展开是
当n=0时,即为拉格朗日中值定理;当时,称为麦克劳林公式
R n ( x ) R_n(x) Rn(x)是皮亚诺余项
皮亚诺余项只是泰勒展开中的余项,只是说原来的方程不完全等于展开项,还有加上一个修正,它是展开最后一项的无穷小,只是一个修正 所以不用在这上面太纠结。
泰勒公式的作用
- 我们都知道,导数是描述函数的变化率,在泰勒公式中出现了各阶导数,也就描述了函数各阶的变化率
举个例子, 1.2345 = 1 + 0.2 + 0.3 + 0.4 + 0.5 1.2345=1+0.2+0.3+0.4+0.5 1.2345=1+0.2+0.3+0.4+0.5,我们可以说这个数在1上面的变化率是多少多少,在0.2上的变化率是多少多少 - 泰勒公式还可以由已知量估算未知量,例如我们知道 l n 2 ln2 ln2的值,利用泰勒公式可以估算 l n 2.1 ln2.1 ln2.1的值
1. 决策树
1.1. 决策树的定义
决策树,顾名思义是用来做决策的,当我们决定一件事情要不要做的时候,会有很多条件。举个例子,我们决定明天要不要去打高尔夫,那么我们会考虑到明天的天气,温度等情况。这里的天气和温度就是特征,是否去打高尔夫就是类别标签。我简单画个图
决策树的学习过程包括:特征选择、决策树生成、决策树剪枝。
下面我将围绕这些过程讲解
1.2. ID3算法
这里要引入一些概念
- 数据集的信息熵,信息熵反映了一个数据集的纯度,信息熵越大,样本纯度越低,不确定性越大。信息熵的计算公式
- 条件熵,在一个条件满足后,样本的信息熵。条件熵的计算公式
- 信息增益
信 息 增 益 = 信 息 熵 − 条 件 熵 信息增益 = 信息熵 - 条件熵 信息增益=信息熵−条件熵
1.2.1. ID3的生成方法
D3使用信息增益作为特征选择的度量,使用自顶向下的贪心算法遍历决策树空间。具体的:
- 计算数据集合的信息熵,以及各个特征的条件熵。选择信息增益最大的作为本次划分节点。
- 删除上一步使用的特征,更新各个分支的数据集和特征集。
- 重复1,2步,知道子集包含单一特征,则为分支叶结点。
1.2.2. ID3的优缺点
- ID3算法没有进行决策树剪枝,容易发生过拟合
- ID3算法没有给出处理连续数据的方法,只能处理离散特征(这个很好理解,ID3根据信息增益来生成树,而信息增益只能针对离散数特征)
- ID3算法不能处理带有缺失值的数据集,需对数据集中的缺失值进行预处理
- 信息增益准则对可取值数目较多的特征有所偏好(信息增益反映的给定一个条件以后不确定性减少的程度,必然是分得越细的数据集确定性更高,取值越多,分的越细,分的越细,条件熵就越小,也就是条件熵越小,信息增益越大)
1.3. C4.5算法
C4.5主要是克服ID3使用信息增益进行特征划分对取值数据较多特征有偏好的缺点。使用信息增益率进行特征划分。
最后一点不太好理解,我在这里举个例子
数据类型:ID3仅能处理离散值,C4.5可以处理连续值。eg:以工资为特征来划分数据集,工资是一个连续的变量,可能会有无限个取值。如果将连续特征的每一个值当成单独的值来看待,产生的决策树会很纯,但没有用。但C4.5使用二分法将连续数据离散化,在某个特征上基于某个划分点将数据集分为两个子集。
1.3.1. C4.5的生成方法
以增益率为标准,增益率越大特征的被先选择
信息增益率对可取值较少的特征有所偏好(分母越小,整体越大),因此 C4.5 并不是直接用增益率最大的特征进行划分,而是使用一个启发式方法:先从候选划分特征中找到信息增益高于平均值的特征,再从中选择增益率最高的。
1.3.2. 剪枝方式
决策树剪枝的目的是为了防止过拟合。
C4.5采用后剪枝对决策树进行剪枝。具体方法为:
在决策树构造完成后,自底向上对非叶节点进行评估,如果将其换成叶节点能提升泛化性能,则将该子树换成叶节点。后剪枝决策树欠拟合风险很小,泛化性能往往优于预剪枝决策树。但训练时间会大很多。
1.3.3. C4.5的优缺点
- C4.5只能用于分类
- C4.5 在构造树的过程中,对数值属性值需要按照其大小进行排序,从中选择一个分割点,所以只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时,程序无法运行。
在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,算法低效。
1.4. CART算法
1.4.1. 思想
相比ID3和C4.5算法,CART算法使用二叉树简化决策树规模,提高生成决策树效率。
CART 包含的基本过程有分裂,剪枝和树选择。
- 分裂:分裂过程是一个二叉递归划分过程,其输入和预测特征既可以是连续型的也可以是离散型的,CART 没有停止准则,会一直生长下去;
- 剪枝:采用代价复杂度剪枝,从最大树开始,每次选择训练数据熵对整体性能贡献最小的那个分裂节点作为下一个剪枝对象,直到只剩下根节点。CART 会产生一系列嵌套的剪枝树,需要从中选出一颗最优的决策树;
- 树选择:用单独的测试集评估每棵剪枝树的预测性能(也可以用交叉验证)。
2. 集成学习
2.1. 集成学习的定义
- 弱学习器:精确率仅高于0.5的学习器。(随机判断一个二分类的精确率为0.5,精确率高于0.5的学习器才有意义,因为这样才有信息获取)
- 集成学习:结合多个个体学习器(弱学习器)从而获得精确率很高的学习器(强学习器)。
集成学习的方法
- bagging:bagging的思想是多个弱学习器相互独立,预测出来的值取平均数或者过半,比如我有一半以上的模型认为这个样本是正类,那么输出的结果正类,例如随机森林。
- boosting(提升):Boosting是集成学习中的一种方法,意为“提升”。提升是一个逐步优化集成学习器的过程,即每个个体学习器都在弥补集成学习器的欠缺,从而达到整体的优化。下面介绍Boosting的经典算法AdaBoost。
集成学习的形式
G
n
x
G_nx
Gnx是基学习器,也就是弱学习器
α
n
α_n
αn是每个基学习器的权重(
α
1
+
α
2
+
.
.
.
+
α
n
=
1
α_1+α_2+...+α_n=1
α1+α2+...+αn=1)
s
i
g
n
(
x
)
sign(x)
sign(x)是符号函数;在数学和计算机运算中,其功能是取某个数的符号(正或负):
当x>0,sign(x)=1;
当x=0,sign(x)=0;
当x<0, sign(x)=-1;
2.2. adaboost
参考文章:adaboost
给定如下表所示训练数据。假设个体学习器由x(输入)和y(输出)产生,其阈值v(判定正反例的分界线)使该分类器在训练数据集上分类误差率最低。(y=1为正例,y=-1为反例)
- 我们来训练第一个基学习器,首先我们刚开始认为所有样本权重是一样的,并且权重之和等于1,权重可以用来计算误差
阈值v取2.5(红线)时分类误差率最低(此时x=6,7,8的数据被错分为反例,误差为它们的权重之和e1=0.1+0.1+0.1=0.3,误差率小于0.5才有意义),故这个基学习器的假设函数为
那么我们是如何断定v取2.4呢?
答:每一个分割点都试一下,取误差最小的。
接下来,根据误差计算这个基学习器的权重, α 1 = 0.4236 α_1=0.4236 α1=0.4236,计算公式
我们想象一下 l o g x logx logx的图像,当x=1, l o g x = 0 logx=0 logx=0,且 l o g x logx logx是单调递增的,所以当 e i < = 0.5 e_i<=0.5 ei<=0.5的时候,也就是x<1的时候, α i < = 0 α_i<=0 αi<=0,那么这个基学习器就没意义了。
最后我们要更新权重,根据adaboost的思想,要把错误分类的样本的权重提高,正确分类的样本的权重降低,根据这个公式
- 我们来训练第二个基学习器
首先我们得到了新的权重,可以看到x=6,7,8的数据的权重变大了,而其他数据的权重降低了,这是希望能把之前经常分类错误(经常分类错误会出现权重不断变大)的数据能在下一个个体学习器分类正确(记住:权重是用来计算误差的,为了降低误差,选择阈值时会倾向把权重大的分类正确)
阈值v取8.5时分类误差率最低(此时x=3,4,5的数据被错分为正例,误差为它们的权重之和
e 2 = 0.07143 + 0.07143 + 0.07143 = 0.2143 e_2=0.07143+0.07143+0.07143=0.2143 e2=0.07143+0.07143+0.07143=0.2143,误差率降低了!)
第二个基学习器的假设函数是这样的
根据误差 e 2 e_2 e2计算系数 α 2 = 0.6496 α_2=0.6496 α2=0.6496
到这里,我们得到了两个基学习器
f 2 ( x ) = α 1 G 1 ( x ) + α 2 G 2 ( x ) = 0.4236 G 1 ( x ) + 0.6496 G 2 ( x ) f_2(x)=α_1G_1(x) + α_2G_2(x)=0.4236G_1(x)+0.6496G_2(x) f2(x)=α1G1(x)+α2G2(x)=0.4236G1(x)+0.6496G2(x)
分类 s i g n [ f 2 ( x ) ] sign[f_2(x)] sign[f2(x)]在训练数据集上有3个误分类点 - 现在来训练第三个基学习器
阈值v取5.5时分类误差率最低( e 3 = 0.1820 e_3=0.1820 e3=0.1820,误差率又降低了!x=0,1,2,9被分类错误)
第三个基学习器的假设函数是这样的
根据 e 3 e_3 e3计算 α 3 = 0.7514 α_3=0.7514 α3=0.7514
这样的话,我们就能写出这个adaboost模型了
s i g n ( f 3 ( x ) ) sign(f_3(x)) sign(f3(x))分类效果是这样的
全部分类正确
为什么adaboost会如此神奇?
对比三个个体学习器我们可以发现,权值很低的数据从侧面说明,它们在前面的学习器经常被分类正确,也就是说它们被分类正确的票数就比较多([公式]相当于每个分类器的票数),那么之后的个体学习器把它们分类错也没所谓啦,反正总票数是分类正确的票数多就可以了。例如x=1,前面两次分类对了,获得正确票数0.4236+0.6496=1.0732,第三次错了,获得错误票数0.7514,正确票数多,最终还是分类正确了。为了想办法让分类错误的数据变为分类正确的,后面的个体学习器也在努力。如x=6,第一次分类错误的票数为0.4236,第二次分类正确的票数0.6496,可以看到为了让前面分类错误的数据变为分类正确的,后面个体学习器的重要性([公式])需要比前面的大。
2.3. xgboost
这里是参考这篇文章xgboost
xgb的原理是下一个基学习器训练上一个基学习器遗留的残差,具体可以用这几张图表示
上面三张图,我们训练出了三个基学习器,他们加在一起构成了xgb,那么我们的最终预测值是这样的,可以发现,误差已经很小了
假设已经训练了
k
k
k颗树,则对于第
i
i
i个样本的最终预测值是这样的
x
i
x_i
xi是第
i
i
i个样本的特征
K
K
K是第
k
k
k个基学习器
f
k
(
x
i
)
f_k(x_i)
fk(xi)是第k个基学习器对于第
i
i
i个样本预测的值
y
^
i
\hat{y}_i
y^i是整个xgboost模型对于第
i
i
i个样本的预测结果
这样我们就可以得到目标函数了,这是对于整个xgboost的目标函数
其中
l
l
l是损失函数,可以是 MSE、Cross Entropy 等等
假设给定样本
x
i
x_i
xi,且
y
^
0
=
0
\hat{y}_0=0
y^0=0,经过下面的推导
这样我们可以得出一个结论,对于
x
i
x_i
xi,到第k个基学习器累加的结果等于第
k
−
1
k-1
k−1个基学习器的预测值加上第k个基学习器的预测值,公式可以写成这样
y
^
i
<
k
−
1
>
=
y
k
−
1
(
x
i
)
+
f
k
(
x
i
)
\hat{y}_i^{<k-1>}=y_{k-1}(x_i)+f_k(x_i)
y^i<k−1>=yk−1(xi)+fk(xi)
这样,我们可以再推一下我们的目标函数
上面画红叉的那一项可以去掉,因为这一个正则项是对每一个基学习器的权重进行一个惩罚,因为训练第
K
K
K 颗树时,该项为常数项,因为在训练第
K
K
K颗树的时候,前
K
−
1
K-1
K−1 颗树的复杂度是已知的,不需要关注前面这些树了。到此为止,我们得出了目标函数是这样的
用泰勒级数近似目标函数
泰勒公式在上方前置知识部分有讲解,这里大佬写的很清晰,我没太多要补充的。
这个目标函数是非常复杂的,我们可以用泰勒级数来近似这个目标函数。
这个目标函数是训练训练第k个基学习器的目标函数
总结一下我们简化目标函数的流程
最初的目标函数
第一次简化
紧接着,我们根据刚刚定义的参数:
W
W
W是叶节点的值
q
(
x
i
)
q(x_i)
q(xi)是样本
x
i
x_i
xi落在哪个叶节点上
f
i
(
x
)
f_i(x)
fi(x)的预测值就可以用
W
(
q
x
i
)
W_{(qx_i)}
W(qxi)表示
写出来是这样的
紧接着,看下图,假设第一个叶节点上(即 15 的地方)有样本[1, 3]落在这里 ,第二个节点有样本[2]落在这个地方,样本[4,5]落在了第三个叶子结点处这里
所以
因为样本[4,5]落在了第三个叶子结点处,所以最后两项可以这样变幻一下,连续的都可以这样变幻
我们可以进一步构造目标函数
后面的这部分大佬讲的很清楚,大家可以看原文