Gradient Boosting と XGBoost
Gradient Boosting や XGBoostについて調べたことをまとめました。Gradient Descent や Newton 法と絡めて説明していきたいと思います。
Boosting
Boosting とは、ランダムより少し良い程度の"弱い"学習アルゴリズムを使って、そのアルゴリズムよりも"強い"学習アルゴリズムをつくることです。イメージとしては、弱い学習アルゴリズムを "boost" してあげる感じでしょうか。
そもそもそんなことって理論的に可能なの?という問いから Boosting の歴史が始まったわけですが、Boosting が可能であることは、1989年に Robert E. Schapire 大先生によって PAC Learning という枠組みで実際に Boosting を行うアルゴリズムを示す形で証明されました[1]。
Boosting のアルゴリズムで大きな成功を収めたもののひとつが、[2]で提案された AdaBoost で以降の Boosting アルゴリズムは AdaBoost に大きな影響を受けています。なんとなく Boosting と言えば逐次的に学習器を構築して、その和をとる、というようなイメージがありますが、それも AdaBoost 由来だと思います。たぶん。
ここで
Gradient Descent (Steepest Descent)
Gradiet Boosting の説明をする前に Gradiet Boosting 非常に関連の強い Gradient descent (勾配降下法)に触れておきます。Steepest Descent (最急降下法) とも呼ばれているアレです。
Gradient Descent は関数
と解の更新を行います。ここで
ニューラルネットの学習などの文脈で Gradient Descnet が使われる場合には、N個のデータ
を最小化するパラメータ
パラメータ空間における Gradient Descent で、
なんとなく Boosting の式と似てませんか?
Boosting では、すでに学習した弱学習器のパラメータを変化させるのではなく、新しい弱学習器を加えることにより全体の出力を変化させることができます。そこで、目的関数を
[3]
Gradient Boosting関数区間で Gradient Descent をする場合には目的関数は次のように書けます。
しかし各データの損失の和を最小化する方向を求めるのは一般には難しいので、各データ
従って、
となるように弱学習器
データ
が最小になるように弱学習器
これが最もベーシックな Gradient Boosting になります。初期値については元論文[3:1]では目的関数を最小化するような定数にしています (XGBBoost の実装は確認してない)。
疑似コードにすると次のようになります。
Regression Tree
これまでは弱学習器に何を用いるか特に決めずに解説しましたが、Gradient Boosting では回帰木 (Regression Trees) が使われることが多いため、回帰木のCART[4]による構築について触れておきます。Gradient Boostingの話からは少しずれるので興味ない場合は飛ばしても大丈夫だと思います。
回帰木では葉に値が紐づいています (その値を葉の重みと呼びます)。葉が
今回は Gradient Boosting に使う弱学習器という文脈なので、N個のデータ
この式は、木の構造が決まっているとき、すなわち関数
と変形できます。さらにガチャガチャ変形すると
となり
この最小値をその木の評価値(一般的には不純度と呼ばれます)として扱い、この評価値が低くなるように木の構築を行います。木の構築では、ルートノード1つしかない状態から始めて、一定の深さになるか損失が下がらなくなるまでノードの分割を繰り返します。
分割対象になったノードに対して、そのノードに到達するデータの集合を
Gain = (
これを
この厳密に全ての候補について試すという方法は XGBoost の論文では "Exact" Greedy Algorithm と呼ばれています。
[3:2]
Gradient Tree Boosting回帰木を使う場合にはGradient Boostingをさらに効率的に行うことができます。Gradient Boosting で最小化したい目的関数は、木の構造が決まると、
と変形することができます。この式が解析的に解ける場合には、
でもその式が解析的に解けるのであれば、最初から
を最小化するように木を構築すればいいじゃないかと思うわけですが、二乗誤差和を損失に使うほうが断然早いので良いという感じらしいです。
[3:3]
Learning rateGradient Boosting の正則化として、更新を行う際に次のように Learning Rate (学習率)
学習率を低くするとパフォーマンスが良くなるということが経験的に知られていて、学習率を低くするとその分最適な反復回数は大きくなることも言われています。(ここで言う最適は leave-out test sample で損失が最小になる回数)
(XGBoost を)実際に使ってみている感覚としては学習率は確かに小さいほうが良くて、0.01とか0.005くらいで十分に小さいという印象があります。それ以上は小さくしても遅くなるだけであまり精度に違いはでない感じがします。0.1とかだとやや大きいけどやや大きいけどデータによっては十分精度が出て、1.0だとかなり過学習しやすいような感じです(個人の感想です)。
Newton Boosting
さて、これまで説明した Gradient Boosting は関数空間で Gradient Descent を用いて目的関数を最小化しているのでした。
次はこの最小化を Gradient Descent でなく Newton 法で行う場合について考えてみます。(ここでいう Newton 法は根を見つける手法のことではありません)
Newton 法では目的関数をテイラー展開で二次の項まで近似して、高校数学で習った二次関数の最小化と同じノリで最小化を行います。
弱学習器
この式を二次近似して次式を得ます。
ここで
(ちなみに
Newton法では、目的関数が二次でない場合は適当に定めた
[6]
XGBoostXGBoostではこのNewton Boostingが採用されています。さらに、木の正則化を行うための項を最小化する目的関数
具体的には次のような目的関数を設定しています。
ここで、
XGBoostを実際に使うときの指定としてはそのまま gamma
、lambda
というパラメータがあります。デフォルトの値はそれぞれ alpha
というパラメータで葉の重みのL1ノルムでの正則化も行えるようです。
また、高速化のための工夫として、データの数や次元数が大きくなった場合、木の構築に Exact Greedy Algorithm を使うと時間がかかりすぎてしまうのを改善するため、分割に使う候補を絞る Weighted Quantile Sketch という手法も提案されています。
データが沢山あって、ここから分割の候補を
Weighted Quantile Sketchはその名の通り、このQuantile Sketchを重み付きに拡張したものです。
Newton Boosting の項で説明した通り、XGBoostの目的関数は二乗誤差が
既存研究では無かった理論保証付きのアルゴリズムを提案したそうで、論文でめっちゃ推されてます。詳しい内容については XGBoost 論文の Supplementary Material に載っています。
Sketching を使用するように明示的に指定するにはパラメータの tree_method
を 'approx'
にすれば良いです。また sketch_eps
で候補点がどれくらい離れるかを指定できます。
この他にも、スパースなデータに対して高速に分割を見つけるアルゴリズムが実装されていたり、データをブロック化して効率的に扱う機能がついていたりなど、大規模な環境で高速に動作するために様々な工夫が行われています。
Generalization Error
理論的な汎化誤差についてはまだわかっていることは少ないようです(たぶん)。
ここが私が一番気になっているところで、Gradient Boostingでは加えた後の経験損失が小さくなるように弱学習器を足しているわけですが、なんで弱学習器をより複雑にして損失をさげるよりも、複雑でない弱学習器でこの手続きを繰り返すほうがうまくいくのでしょうか。また、なんで
AdaBoost については元々統計的機械学習というより学習理論の分野で出てきたこともあって、古くから汎化誤差について研究が進められています。ここら辺は正直ちゃんと理解できておらずうまく説明できる気がしないので、詳しくは AdaBoost に関する survey 論文[8]の章とか、margin の話の論文[9]とかを読んでくださいという感じです。参照している論文が結構古いのでもしかしたらそこらへんの研究はもう少し進んでいるかもしません。
また、Gradient Boosting の汎化誤差については調べてみたものの見つからなかったので、これらについて何か情報があったら教えてもらえると非常に助かります。もしかしたら Gradient Descent のほうから調べていったほうが良いのかもしれません。よくわからんという感じです。強い人教えてください。
-
Robert E. Schapire. The strength of weak learnability. Machine Learning, 5(2):197–227, 1990. ↩︎
-
Yoav Freund and Robert E. Schapire. A decision-theoretic generalization of on-line learning and an application to boosting. Journal of Computer and System Sciences, 55(1):119–139, 1997. ↩︎
-
Jerome H. Friedman. Greedy function approximation: A gradient boosting machine. The Annals of Statistics, 29(5), 2001. ↩︎ ↩︎ ↩︎ ↩︎
-
Leo Breiman, Jerome H. Friedman, Richard A. Olshen, and Charles J. Stone. Classification and regression trees. The Wadsworth and Brooks-Cole statistics-probability series, Taylor & Francis. ↩︎
-
Didrik Nielsen. Tree Boosting With XGBoost - Why Does XGBoost Win “Every" Machine Learning Competition? Master thesis, Norwegian University of Science and Technology, 2016. ↩︎
-
Tianqi Chen and Carlos Guestrin. Xgboost: A scalable tree boosting system. Proceedings of the 22Nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining, 785-794, 2016. ↩︎
-
Michael Greenwald and Sanjeev Khanna. Space-Efficient Online Computation of Quantile Summaries. Proceedings of the 2001 ACM SIGMOD international conference on Management of data, 58-66, 2001 ↩︎
-
Robert E. Schapire. The boosting approach to machine learning: An overview. Nonlinear estimation and classification. 149-171, 2003. ↩︎
-
Robert E. Schapire, Yoav Freund, Peter Bartlett, and Wee Sun Lee. Boosting the margin: A new explanation for the effectiveness of voting methods. The Annals of Statistics, 26(5):1651–1686, 1998. ↩︎
Discussion