1 E X: G( C, p* x8 `5 j9 V$ H* c: G& s$ [: }6 E% o' K
对求偏导,并使其导函数等于0,则有:# {! D. [; v. H. k9 G; X
) E' `3 v1 U$ y9 c3 t8 O% g8 _' t c% L) O1 X
+ L( B! ?) b: e, G j2 c2 w0 K' b+ n' C8 O- ?
6 ?" W F2 M; t7 L! n到此,损失函数的推导完成。( p3 u, _& D' ^* o c; h
- E8 p5 M3 a. \: ^* [9 C
3)树结构的打分函数 7 K' r1 G8 [5 h. G* u 6 f0 W+ I; N3 `$ x8 b+ Y5 P Obj代表了当指定一个树的结构的时候,在目标上面最多减少多少。结构分数(structure score)4 T0 R2 I: o% B& M0 F9 N* f
* N6 G' g; U2 U5 s' M
) R* X7 I3 h/ {$ c2 l n( G/ c ?% V
( H6 e {5 D0 M# V4 j p0 [ xgboost算法的步骤和GB基本相同,都是首先初始化为一个常数,gb是根据一阶导数ri,xgboost是根据一阶导数gi和二阶导数hi,迭代生成基学习器,相加更新学习器。 / t3 V+ @# s, C9 z5 r ( | W0 J9 H( G# d# o4 X对于每一次尝试去对已有的叶子加入一个分割2 [5 ~$ u/ j# z. M
. ]# ~# C7 U6 | k: U3 N3 ]. N8 d/ }5 E, g- ?4 z$ `
* H/ P' h7 v0 e
这样就可以在建树的过程中动态的选择是否要添加一个结点。 联想决策树中信息增益,这里的原理类似。这一步实质上是为了寻找分裂结点的候选集。" o+ w( E) N5 C' [" s$ G
0 z" E* o3 n# x! k f/ @! |
如何高效地枚举所有的分割呢?我假设我们要枚举所有x < a 这样的条件,对于某个特定的分割a我们要计算a左边和右边的导数和。 $ o" z. X% N1 ~; Q a- r, o+ j m4 P5 `5 V4 N
6 }4 R. x% l6 [% Z0 |* d0 O0 e# v% o4 P1 g! s
我们可以发现对于所有的a,我们只要做一遍从左到右的扫描就可以枚举出所有分割的梯度和和。然后用上面的公式计算每个分割方案的分数就可以了。 5 `% Y4 e4 A6 ]* [3 g2 n- { s6 [% q6 p
xgboost算法伪代码如下:; I4 T( g/ W+ m. G# ^4 J" U
/ p: _- H" G& s3 K9 j
* T; j: M `' U t/ r8 N* @3 D D% H. a- Y+ Y* w; K
3、Xgboost算法参数5 s: Y" n" E9 F! y
XGBoost的作者把所有的参数分成了三类:6 D( o7 z$ E( h$ }6 a8 e
/ H' u0 k4 M- I
通用参数:宏观函数控制。5 V5 e( [1 `/ X: ?0 h' x
Booster参数:控制每一步的booster(tree/regression)。3 u/ t" {4 u* h1 x# [' p
学习目标参数:控制训练目标的表现。 ( B D$ z. G0 l7 K& P0 K3.1通用参数8 y! J" \. C& { u
这些参数用来控制XGBoost的宏观功能。' T( G6 R+ l8 w, I. d
4 z8 `2 X: _( g( X- o6 W5 M
1、booster[默认gbtree]* `0 I7 ]8 Z7 r7 [
0 F: ^6 y @* O/ o" ?6 Q选择每次迭代的模型,有两种选择: # P0 N& h5 v$ N+ ^! x* K6 w
gbtree:基于树的模型 ; B, C' [/ q% J: o# zgbliner:线性模型6 K% |( ~4 |% X* F7 {8 l( F( v
2、silent[默认0] 1 k. D& x$ Z0 l) s3 C. x# W: C, w; |+ w
当这个参数值为1时,静默模式开启,不会输出任何信息。, A3 Q. t+ ^) y% m* ^
一般这个参数就保持默认的0,因为这样能帮我们更好地理解模型。 1 L: c+ w: b) p& o+ s) p9 z, L3、nthread[默认值为最大可能的线程数]; M/ X9 S0 r! D$ e+ C
8 e2 n9 [" n* W7 u- I2 G
这个参数用来进行多线程控制,应当输入系统的核数。 4 b& q5 m3 Z8 j, M6 c如果你希望使用CPU全部的核,那就不要输入这个参数,算法会自动检测它。 # w6 H! G- i& X$ ?1 ?# ~/ a7 C还有两个参数,XGBoost会自动设置,目前你不用管它。接下来咱们一起看booster参数。 & O; R3 j J, f r0 w/ V 5 Z o8 W) K+ W1 I3.2 booster参数 8 ~ j: @" ~: t3 B尽管有两种booster可供选择,我这里只介绍tree booster,因为它的表现远远胜过linear booster,所以linear booster很少用到。9 f" J: q ^" P; C' C
5 T$ o+ w0 z+ X4 M: K
1、eta[默认0.3] : e+ n& e% p8 O; i* m1 A8 w( B 1 ?. ^5 j0 `3 @# c和GBM中的 learning rate 参数类似。 k2 i( B0 S/ |) ]通过减少每一步的权重,可以提高模型的鲁棒性。 2 u2 I' c+ T/ i" d典型值为0.01-0.2。8 q+ F9 k( A/ s4 x
2、min_child_weight[默认1]) M% {8 k! D3 Q% d* M- S* W8 `0 S
4 C9 S) T: H6 j& |% N9 r6 Z4 I
决定最小叶子节点样本权重和。 " X- \* \9 u" a1 {# I0 O和GBM的 min_child_leaf 参数类似,但不完全一样。XGBoost的这个参数是最小样本权重的和,而GBM参数是最小样本总数。 + g6 f3 E, Z: i$ ]6 j这个参数用于避免过拟合。当它的值较大时,可以避免模型学习到局部的特殊样本。 ' Q% a* Y3 J2 k但是如果这个值过高,会导致欠拟合。这个参数需要使用CV来调整。5 t b) @1 H/ L7 `+ U1 `
3、max_depth[默认6]7 {4 x8 J+ e1 U0 o9 o
+ {% @9 r, \/ _和GBM中的参数相同,这个值为树的最大深度。5 F3 w5 e! p! U6 a" Z" l0 i
这个值也是用来避免过拟合的。max_depth越大,模型会学到更具体更局部的样本。 / B d6 M) M+ E# V需要使用CV函数来进行调优。 % E: {' b8 w8 W6 b典型值:3-10 4 Y) N; ^9 W0 G* J* E4、max_leaf_nodes ' y- A$ Y7 m+ K7 P$ S5 { 7 y e5 L9 t# j, k) M6 s7 M* e! K树上最大的节点或叶子的数量。5 [, F) r5 N" x$ z" m
可以替代max_depth的作用。因为如果生成的是二叉树,一个深度为n的树最多生成n2n2个叶子。. Z* N3 J: O$ w- n6 i q
如果定义了这个参数,GBM会忽略max_depth参数。8 u2 q- N* K n" y& p" e
5、gamma[默认0]$ m1 a1 T. ]+ `4 r% K) c. q b
; B( e3 `' h- f0 s: w$ g在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。Gamma指定了节点分裂所需的最小损失函数下降值。 ' a. l) K1 B& G6 o' y4 C这个参数的值越大,算法越保守。这个参数的值和损失函数息息相关,所以是需要调整的。. c6 t; Z9 v- f1 c8 t
6、max_delta_step[默认0]3 e( A- c3 L. z
; j) `, f+ O; w$ G6 ~这参数限制每棵树权重改变的最大步长。如果这个参数的值为0,那就意味着没有约束。如果它被赋予了某个正值,那么它会让这个算法更加保守。- ` N, T4 x0 U, v" S+ M
通常,这个参数不需要设置。但是当各类别的样本十分不平衡时,它对逻辑回归是很有帮助的。" u4 F1 h7 e* G% O/ F
这个参数一般用不到,但是你可以挖掘出来它更多的用处。 D8 i3 O* [% ], |- [0 k* w7、subsample[默认1] & P/ r) m1 t; b, M9 ^& ^ 7 T( H% e% t. s+ W, m% W& K和GBM中的subsample参数一模一样。这个参数控制对于每棵树,随机采样的比例。 # G4 {( o j4 |0 Y3 g$ a( Q. d* U; `减小这个参数的值,算法会更加保守,避免过拟合。但是,如果这个值设置得过小,它可能会导致欠拟合。5 r+ Z' h, J" ?3 L; F. z" a6 B% k% g
典型值:0.5-1 / e0 g7 v! T, |# _0 Y8、colsample_bytree[默认1] 0 ~$ b, g+ E: s3 @6 V6 C + n4 U% q) x3 t$ K0 Z和GBM里面的max_features参数类似。用来控制每棵随机采样的列数的占比(每一列是一个特征)。 $ t; B' Q- P. ~! I# N9 C9 X$ T典型值:0.5-1 5 k" A) x* N( C' l: ^% B5 D8 q9、colsample_bylevel[默认1]- R$ C& v# {) F- O$ D/ o2 c8 G
! R) F- a! h* p; N2 A用来控制树的每一级的每一次分裂,对列数的采样的占比。 ( o+ S8 J& |" W) J" A8 _我个人一般不太用这个参数,因为subsample参数和colsample_bytree参数可以起到相同的作用。但是如果感兴趣,可以挖掘这个参数更多的用处。: ]% k( F8 s, E; B) a+ A% W3 q& ~
10、lambda[默认1] 1 {* \/ l# A! F9 d0 n 3 w" ~# c; N7 L% t7 o( ?0 Z( h权重的L2正则化项。(和Ridge regression类似)。 $ N5 b" E* [" ~2 ~( O. h8 @' `" h这个参数是用来控制XGBoost的正则化部分的。虽然大部分数据科学家很少用到这个参数,但是这个参数在减少过拟合上还是可以挖掘出更多用处的。( F% t3 Y5 F" |
11、alpha[默认1] : E F) b0 a) \( ?& `- Y; a. \" c: x, P
权重的L1正则化项。(和Lasso regression类似)。! q; }& K/ T' x& {
可以应用在很高维度的情况下,使得算法的速度更快。 0 k! D2 O$ z+ m" J12、scale_pos_weight[默认1]7 y8 L8 X6 i& }+ E, f! |
6 E; ?9 q! F1 S* j) x1 V: ?, C
在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。; n. b) C- M9 L% e" _# A
3.3学习目标参数9 t: z, k- V: {" K
这个参数用来控制理想的优化目标和每一步结果的度量方法。+ @' A, j4 y' g, u6 w
2 X* B2 m( B9 I$ n
1、objective[默认reg:linear]. T) q# n4 L3 H& n