CatBoost原文:
《CatBoost:gradient boosting with categorical features support》-2018
俄罗斯人写的文章,真的是…唉…
用词习惯和英美作者风格不太一致.
###################################################
先说下文章结构吧:
原
文
结
构
=
{
1.
I
n
t
r
o
d
u
c
t
i
o
n
2.
C
a
t
e
g
o
r
i
c
a
l
f
e
a
t
u
r
e
s
3.
F
i
g
h
t
i
n
g
G
r
a
d
i
e
n
t
B
i
a
s
4.
F
a
s
t
S
c
o
c
e
r
5.
F
a
s
t
t
r
a
i
n
i
n
g
o
n
G
P
U
6.
E
x
p
e
r
i
m
e
n
t
s
原文结构=\left\{ \begin{aligned} 1.Introduction \\ 2.Categorical\ features \\ 3.Fighting\ Gradient\ Bias\\ 4.Fast\ Scocer\\ 5.Fast\ training\ on\ GPU\\ 6.Experiments\\ \end{aligned} \right.
原文结构=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧1.Introduction2.Categorical features3.Fighting Gradient Bias4.Fast Scocer5.Fast training on GPU6.Experiments
所以文章第2、3部分是重点,其他是讲怎么在速度上优化的,即使你去读博士,你不搞这个研究方向,那就没必要看.
下面这个博客解读了catboost在youtube中的讲解内容
https://blog.csdn.net/friyal/article/details/82758532
先说说问题:
上面的这个博客中提到CatBoost使用的是完全对称树来解决过拟合问题,关于这个,
我个人…不是太看好…
因为,过拟合问题,不能纯粹的使用对称树来解决,对称树不可能解决所有的过拟合的情况,而应该具体问题具体对待.
##################################
注意,这篇文章中说的GBDT和百度上的GBDT不是一个意思.
过往的算法先回顾下:
GBDT:每一颗树的建立都使用残差
XGBOOST:每棵树之间地位是等同的,使用特征列采样来建立树.
这篇文章把GBDT和XGBOOST都称为是GBDTS,意即:
G
B
D
T
S
=
{
1.
G
B
D
T
2.
X
G
B
O
O
S
T
GBDTS=\left\{ \begin{aligned} 1.GBDT \\ 2.XGBOOST \\ \end{aligned} \right.
GBDTS={1.GBDT2.XGBOOST
这个算法的优点就是提供了GPU版本,并且能够独热一些离散特征.
#########################################
下面详解文章的2、3部分,分别讲了啥.
注意哈,论文原文中对算法细节的讲解不如上面那篇博客那么详细.
2.Categorical features
这个标题的意思就是离散特征.
为啥取了这么个奇怪的名字呢?
因为这个部分是讲解怎么把离散特征的处理过程与标签(也就是y,你懂的)给关联起来,所以在标签中没有使用discrete features的说法,也就是说,底层依然是Cart,我们知道,Cart是不能接收离散特征值为字符串的情况的.
文章这一部分的主要贡献是:
根据过往的:
∑
j
=
1
n
[
x
j
,
k
=
x
i
,
k
]
⋅
Y
j
∑
j
=
1
n
[
x
j
,
k
=
x
i
,
k
]
\frac{\sum_{j=1}^n[x_{j,k}=x_{i,k}]·Y_j}{\sum_{j=1}^n[x_{j,k}=x_{i,k}]}
∑j=1n[xj,k=xi,k]∑j=1n[xj,k=xi,k]⋅Yj
改成:
∑
j
=
1
p
−
1
[
x
σ
j
,
k
=
x
σ
p
,
k
]
Y
σ
,
j
+
a
⋅
P
∑
j
=
1
p
−
1
[
x
σ
j
,
k
=
x
σ
p
,
k
]
\frac{\sum_{j=1}^{p-1}[x_{\sigma_{j},k}=x_{\sigma_{p},k}]Y_{\sigma,j}+a·P}{\sum_{j=1}^{p-1}[x_{\sigma_{j},k}=x_{\sigma_{p},k}]}
∑j=1p−1[xσj,k=xσp,k]∑j=1p−1[xσj,k=xσp,k]Yσ,j+a⋅P
好了,打住装逼,讲人话,这个东西到底是干嘛的?
∵Cart决策树无法处理取值为字符串型的离散特征
∴用来把离散特征变成数值型特征的.
上面的
σ
j
\sigma_j
σj表示第j条数据(所以俄罗斯人用符号也很奇怪)
上面的k表示第k列,第k个特征(这个特征是离散特征)
这里的中括号论文中说是Iverson brackets,
你看看,俄罗斯人的用词,真是无力吐槽.
讲人话,这个中括号就是指示函数,符合里面的条件就为1,否则就为0.
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
整个式子的意思是,把
x
σ
j
,
k
x_{\sigma_{j},k}
xσj,k也就是第
σ
j
\sigma_{j}
σj条数据中的第k个特征替换为上面的式子.
上面这个式子的理论依据是啥?☆☆☆☆☆☆
根据我的理解,是李航的<统计学习方法>中的P51的式(4.10)贝叶斯估计.
然后这一部分还提了特征整合,但是论文中没有细讲,参考上面的那个链接就好了.
接下来第3部分:
3.Fighting Gradient Bias:
先上算法:
这部分开头说要解决一个biased pointwise gradient estimates
这个是什么意思呢?就是下面这个图,说人话就是噪声点问题.
所以作者提出了一个设想,为了避免使用异常点,训练时不使用这个点.
但是这样的话,岂不是一开始的训练也进行不下去了?
于是作者提出了一些技巧:
一开始对整个数据集进行s次随机排序.
文中写道:
For each permutation
σ
\sigma
σ,we train n different models
M
i
M_i
Mi.
所以到这里为止,复杂度已经有
O
(
s
n
)
O(sn)
O(sn)了
对于每次排序:
对于每个模型
M
i
M_i
Mi(指的是去除第i条数据,为了以防异常点的影响)
我们更新
M
i
(
X
1
)
,
⋅
⋅
⋅
,
M
i
(
X
i
)
M_i(X_1),···,M_i(X_i)
Mi(X1),⋅⋅⋅,Mi(Xi)
所以到这里为止,复杂度就是
O
(
s
n
2
)
O(sn^2)
O(sn2)
这里的 M i ( X 1 ) M_i(X_1) Mi(X1)在论文中没有具体说明,应该是去除第 X i X_i Xi条数据建立的模型对 X 1 X_1 X1这条数据的预测值
##############
也就是说,对于s次排列中的每次排列而言,我们建立n个模型
M
i
M_i
Mi,每个模型都是去除
X
i
X_i
Xi的情况下建立的,对于
M
i
M_i
Mi模型而言,我们需要更新前面i个值的预测值,所以整体复杂度约为
O
(
s
n
2
)
O(sn^2)
O(sn2)
上面的是什么意思呢?
因为CatBoost是类似于GBDT的一种算法,所以也就是说每棵树都是基于上一棵树的残差来建立的.
那么上面的描述是如何解决这个"biased pointwise gradient estimates"的问题呢的?
也就是说,可以修改该问题的描述为:“第i条数据在模型中的梯度如何确立”?
算法大意为:
去掉第i条数据(
X
i
X_i
Xi),建立模型
M
i
M_i
Mi
对于前面的i-1条数据,依次计算
L
o
s
s
Loss
Loss的梯度
g
j
g_j
gj
把i-1个
g
j
g_j
gj和
X
j
X_j
Xj传入函数LearnOneTree建立一棵残差树M
修改最初的
M
i
M_i
Mi为
M
i
+
M
M_i+M
Mi+M
通俗地讲,就是利用前面i-1条数据的情况来预测第i条数据在模型中的对应的预测值.
最后总结下就是:
利用所有训练集(除第i条)建立模型
M
i
M_i
Mi,然后使用第1条到第i-1条数据来建一个修正树M,累加到原来模型
M
i
M_i
Mi上,以回避上面的"biased pointwise gradient estimates"问题.
好了,最后呢,上面这个算法被进行了修正.我们可以看到,上面这个算法是3重for循环
第二重是i,循环范围是(1,n)
好了,优化办法是每次处理
2
i
2^i
2i条数据,所以循环次数变成
l
o
g
2
n
log_2n
log2n次
M
i
′
(
X
j
)
M_i'(X_j)
Mi′(Xj)是根据
2
i
2^i
2i次条数据进行建模,然后对与
X
j
X_j
Xj的预测值
我们需要的
M
i
′
(
X
j
)
M_i'(X_j)
Mi′(Xj)的数量是
∑
0
≤
i
≤
l
o
g
2
(
n
)
2
i
+
1
<
4
n
\sum_{0≤i≤log_2(n)}2^{i+1}<4n
∑0≤i≤log2(n)2i+1<4n个
所以复杂度变为
O
(
s
⋅
4
n
)
=
O
(
s
n
)
O(s·4n)=O(sn)
O(s⋅4n)=O(sn)