1、目标函数
首先说一下目标函数,机器学习常见的目标函数主要由两部分组成:损失函数和正则化项。
Obj(Θ)=L(Θ)+Ω(Θ)
其中 L(Θ)=∑ni=1l(yi^,yi) 的形式主要有两种:
平方损失函数: l(yi^,y)=(yi^−yi)2
逻辑损失函数: l(yi^,y)=yiln(1+e−yi^)+(1−yi)ln(1+eyi^)
正则化函数主要有两种:
L1正则化: Ω(Θ)=λ||ω||
L2正则化: Ω(Θ)=λ||ω||2
其中损失函数的主要作用是衡量模型拟合训练数据的能力;正则化项的主要作用是使得模型更加简单一些。
2、Regression tree(CAST)和Regression Tree Ensemble
2.1. Regression tree (also known as classification and regression tree):
Decision rules same as in decision tree
Contains one score in each leaf value
2.2 Regression Tree Ensemble
2.3 集成方法(Tree Ensemble methods)的优点:
(1)被广泛的应用,如GBDT,随机森林等;
(2)对于输入的范围不是很明感,因而你不必需要细致的去做特征的归一化;
(3)可以学得特征间的相互关系;
(4)可以规模化,广泛应用于工业界。
3、模型和参数
3.1 模型
假定我们有K棵树:
yi=∑Kk=1fk(xi)
其中 fk∈F , F 表示所有回归树的函数空间。
Think: regression tree is a function that maps the attributes to the score
3.2 参数
(1)每棵树的的结构,树上叶子的分数;
(2)或者使用树的函数作为参数:
我们该如何学得一棵树呢?
定义一个目标函数,并且去优化它!!
3.3 集成方法的目标函数
模型:
yi=∑Kk=1fk(xi)
目标函数:
Obj=∑ni=1l((̂ yi),yi)+∑Kk=1Ω(fk)
4、Gradient Boosting
目标函数:
Obj=∑ni=1l(yi,yi^)+∑Kk=1Ω(fk)
其中 fk∈F .
在这里我们不能通过SGD(随机梯度下降)来最优化这个目标函数,从而
找到
f
,因为
解决方案:加法模型(Boosting)
通过每次在原函数上添加一个新的函数来进行迭代:
yi^(0)=0
yi^(1)=f1(xi)=yi^(0)+f1(xi)
yi^(2)=f1(xi)+f2(xi)=yi^(1)+f2(xi)
yi^(t)=∑t−1k=1fk(xi)=yi^(t−1)+ft(xi)
那现在的问题是我们该怎么得到每次迭代中所添加的 f 呢?
答案就是最优化目标函数。
在第t轮时,模型函数变为
Obj=∑ni=1l(yi,yi^t−1+ft(xi))+∑tk=1Ω(fk)+constant
对于平方损失函数:
Obj=∑ni=1[2(yi^t−1−yi)+ft(xi)2]+∑tk=1Ω(fk)+constant
对于平方损失函数,目标函数的形式并不是很复杂,但是对于其它形式的损失函数,我们该怎么办呢?
在这里我们通过泰勒展开式来近似目标函数。
函数的泰勒展开式:
f(x+Δx)≈f(x)+f′(x)Δ(x)+12f″(x)Δ(x)2
令 gi=∂l(yi,ŷ t−1)∂ŷ t−1 ,
hi=∂2l(yi,ŷ t−1)∂2ŷ t−1
则目标函数的近似为:
Obj≈∑ni=1[l(yi,yi^t−1)+gifi(xi)+12hif2(xi)]+∑tk=1Ω(fk)+constant
我们把固定值移除,则目标函数近似为:
∑ni=1[l(yi,yi^t−1)+gifi(xi)+12hif2(xi)]+Ω(fk)
然后我们来重新定义一下需要学习的树,我们使用一系列的叶子分数来表示树的结构:
ft(x)=ωq(x)
其中 ω 表示树上叶子的权重, q(x) 表示树的结构。
树的结构复杂度表示为:
Ω(ft)=γT+12λω2
其中
T
表示树上叶子的个数,
定义: Ij={i|q(xi)=j}
则目标函数可以表示为:
Obj(t)≈∑ni=1[gifi(xi)+12hif2(xi)]+∑tk=1Ω(fk)=∑ni=1[giωq(xi)+12hiω2q(x)]+γT+12λ∑Tj=1ω2j=∑Tj=1[(∑i∈Ijgi)ωj+12(∑i∈Ijhi+λ)ω2j]+γT
定义: Gj=∑i∈Ijgi , Hj=∑i∈Ijhi .
目标函数变为:
Obj(t)≈∑Tj=1[Gjωj+12(Hj+λ)ω2j]+γT
则可求得
ω∗j=−GjHj+λ
Obj=−12∑Tj=1G2jHj+λ+γT
上式第一项可以用来衡量模型的好坏。
枚举所有不同树结构的贪心法
通过上面的推论我们可以得出寻找最佳树的方法。
(1)列举可能的树结构q;
(2)通过公式 Obj=−12∑Tj=1G2jHj+λ+γT 计算得到q的分数;
(3)找到最佳的树的结构(分数最小的那个树结构),并计算得到叶子的权重 ω∗j=−GjHj+λ 。
年轻人,想法是好的,但是树的结构空间是无穷大的,因而这种方法果断不行。。
通常,我们可以通过贪心算法来得到比较好的树结构。
(1)从一颗深度为0的树开始操作。
(2)对于树上的每个叶子节点,试图来添加一个分裂点将原来的叶子节点进行细分。通过添加分裂点,原来的目标函数变化为:
现在的最优问题变为:如何找到最好的分裂点?对于每次扩展,我们
还是要枚举所有可能的分割方案,如何高效地枚举所有的分割呢?我
假设我们要枚举所有 x<a 这样的条件,对于某个特定的分割a我
们要计算a左边和右边的导数和。
我们可以发现对于所有的a,我们只要做一遍从左到右的扫描就可以
枚举出所有分割的梯度和
GL
和
GR
。然后用上面的公式计算每个分割方案的分数就可以了。
找最优分裂点的方法:
(1)对于每个叶子节点,枚举在其上的所有特征;
(2)对于每个特征,根据特征值来对样本进行排序;
(3)线性扫描每个分裂点,找到该特征的最优分裂点;
(4)从所有特征中找到最优的分裂点作为该叶子节点的分裂点。
时间复杂度(树的深度为K):
时间复杂度为
O(ndKlog(n))
,对于每一层,我们需要
O(nlog(n))
的时间来进行排序,其中特征维度为
d
,树的深度为
从添加分裂点之后的增益可以看出,添加分裂点之后,增益可能为负,这说明添加分裂点不一定使得模型变好。我们需要在模型的复杂度和预测效果上做一个权衡。
在计算模型时,可以通过预剪枝或后剪枝来使得模型变得越来越好。
预剪枝:
如果某个叶子节点的最好的特征增益为负时则停止分裂,但是这可能有一些坏处:也许当前的这个分裂点对于当前是不好的,但是对于未来的一些分裂是有好处的。
后剪枝:
将树长到最大深度,依次减掉所有获得负增益的叶子分裂点。