ザックリとした『Xgboostとは』& 主要なパラメータについてのメモ

# はじめに
Signateという機械学習コンペティションサイトのJリーグ観客動員数予想コンペに挑戦しているのですが、
そこでXgboostという機械学習アルゴリズムを使用しました。

その際にパラメータを色々いじったのですが、何がどういうパラメータなのかをまた次にXgboost使うときには忘れていそうなので纏めておきます。

# Xgboostとは
勾配ブースティングとも呼ばれる手法で、**弱学習学習器を逐次的に構築**する手法です。

ランダムフォレストは決定木を複数個構築し、その結果をアンサンブルします。
それに対してXgboostは弱学習器を構築する際に
**前に構築された弱学習器の結果を使用し弱学習器を構築する**のです。
前に構築された学習器によって正しく分類されたデータに対して重みを小さくし、
正しく分類されなかったデータに対して重みを大きくした学習器を作ります。
これにより、新しく構築された学習器ほど誤ったデータに集中して学習することができます。

詳しくはこちらのサイトにてとてもわかりやすい図と共に丁寧に説明されています。
こちらの図を少し引用させていただきたいと思います。
[XGBoostやパラメータチューニングの仕方に関する調査 | かものはしの分析ブログ](http://kamonohashiperry.com/archives/209)


>Xgboostのイメージ図
![alt](http://kamonohashiperry.com/wordpress/wp-content/uploads/2016/04/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2016-04-24-18.40.38.png)

>STEP1では全ての学習データに対して、等しい重み付けで学習を行い、決定境界を引きます。これを弱学習器による学習と言います。このケースでは毒キノコを2つ当てており、キノコを５つ当てています。
STEP2ではSTEP1で正しく識別されたデータの重みが下げられ、誤って識別されたデータの重みが上げられています。高く重み付けがなされたデータは決定境界で正しく識別されていますが、他のデータは誤って分類されています。
STEP3においてもSTEP2と同様の傾向があります。このような弱学習器による処理を繰り返すことで識別性能を高めていきます。

>最終的にはこのような決定境界を引くことができるような識別器を求めていきます。


>![alt](http://kamonohashiperry.com/wordpress/wp-content/uploads/2016/04/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2016-04-24-18.55.53.png)

>勾配ブースティングの勾配とは、ブースティングアルゴリズムにおけるパラメータ推定での最適化手法が勾配降下法に従っているという意味での勾配です。以上が勾配ブースティングモデルの簡素な説明です。
[XGBoostやパラメータチューニングの仕方に関する調査 | かものはしの分析ブログ](http://kamonohashiperry.com/archives/209)より引用

メチャクチャわかりやすいですね、下手に「猿でもわかる」とか書いてあるサイトよりもわかりやすいです。
~~あの謳い文句は「猿ですらわかるのに解らない俺は・・・」って傷つくので軽率に使うべきではないと思います。~~

パラメータもこちらにとても詳しく乗っているので、今回は私が特に注視して弄ったパラメータにのみ説明します。

# パラメータ紹介
私が重要視したパラメータのみ簡単に説明したいと思います。
今回はツリーモデルを使用したので、そちらに考慮したパラメータとなります。
線形モデルでは使用できないパラメータ、線形モデルでしか使用できないパラメータもあるので詳しくは[xgboostのリファレンス](https://xgboost.readthedocs.io/en/latest/parameter.html)をご覧ください。

独断と偏見、というか自分の使用感で重要度を記載しました。
ですがなにぶん当アルゴリズムの使用回数が低い人間の感覚なので話半分に程度にどうぞ。

## eta
default: 0.3
受容度: けっこう
pythonで使用する場合は"learning_rate"
各ステップごとの学習率を司るパラメータです。
高いと過学習しやすくなります。

## min_child_weigh
default: 1
重要: けっこう重要
子ノードから引き継ぐデータに付けられる重みの合計値の最小の値です。
値を大きくすると外れ値に強くなりますが汎用性が低くなります。


## max_delta_step
default: 0
重要度： 場合によりけり
正の値に設定した場合、ステップの更新でより強く引き継ぎます。
通常はあまり使用しませんが、不均衡データを扱うときには有効らしいです。

## subsample
default: 1
重要度： そこそこ
各木においてランダムに抽出される標本の割合。
0.5~1ぐらい？

## colsample_bytree
default: 1
重要度： まあまあ
各レベル単位での、分割における列のsubsample比率


## max_depth
default: 6
重要度:けっこう重要
生やす木の長さの最大値。4~10が多いっぽい。
長くしすぎると学習にかかる時間が跳ね上がるし過学習しやすいのでこわいです。
ちなみになんだかんだdefaultの値が汎用性が高いのかなあなんて思いました。

## lambda
default: 1
重要度: それなり
pythonで使用する場合は"reg_lambda"
重みに関するL2正規化をこのパラメータを編集することにより使用することができる。
L2正規化とは*データの大きさに応じて0に近づけて、滑らかなモデルとする*ものであり、
先ほどキノコを引用させて頂いたサイトにも「調整するべきパラメータとして紹介されています。

## alpha
default: 0
重要度: 場合によりけり
重みに関するL1正規化を行うことができます。
L1正規化とは*特定のデータの重みを0にする事で、不要なデータを削除する*ものです。
高次元のデータに対して特に有効であり、それ以外のケースではそこまで重要視するものではないかも。

## gamma
default：０
重要度: けっこう重要
損失還元の最小値で木の葉ノードをさらに分割するのに必要な値です。



# 参考文献
[過学習を防ぐ正則化 | TechCrowd](https://www.techcrowd.jp/machinelearning/regularization/)

[貪欲アプローチによるxgboostハイパーパラメータのサーチ - Qiita ](https://qiita.com/sugiyamath/items/065b1d3ad352fad0ad54)

[グリーディ法によるxgboostハイパーパラメータのサーチ - ナード戦隊データマン ](http://datanerd.hateblo.jp/entry/2018/02/09/190408)

ちなみにMarkdownで参考文献を引用する時などのUrl操作はこれが楽でオススメですよ
[MarkdownでUrl引用するときにちょっと簡単にするハック【小ネタ】 - Qiita](https://qiita.com/2357gi/items/155a03080ef2cf2936f4)