【機械学習】ハイパーパラメータチューニングの仕方

##はじめに

最近Kaggleで人気のLightGBMとXGBoostやCatBoost、RandomForest、ニューラルネットワーク、線形モデルのハイパーパラメータのチューニング方法についてのメモです。
ハイパーパラメータをチューニングする際に重要なことを紹介していきます。

参照元は、以下のCOURSERAのコースです。
[How to Win a Data Science Competition: Learn from Top Kagglers](https://www.coursera.org/learn/competitive-data-science/lecture/wzi5a/hyperparameter-tuning-ii)
※このコースではCatBoostについては触れていない為、以下を参照しました。
[CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)

###Hyperopt等の最適化ソフトウェアのについて
hyperoptなどの最適化ソフトウェアがあるが、手動で変えていく方が早いとのこと。

###Gradient Boosting Decision Tree(勾配ブースティング)

| XGBoost          |    LightGBM          |    備考            |
|:----------------:|:-----------------------:|:----------------:|
| max_depth         |    max_dapth<br>num_leaves          |    7程度から始めるのがお勧め。<br>深さを増やすと学習率が上がるが、学習に時間がかかる。 |
| subsample       |    bagging_fraction        |    使用するオブジェクトの割合を制御するパラメータ。0と1の間の値。 |
| colsample_bytree,colsample_bylevel          |    feature_fraction         |    過学習している場合はこの値を下げる。 |
|  min_child_weight,<br>lambda,alpha          |    min_data_in_leaf, lambda_l1,lambda_l2        |    min_child_weightが一番重要。過最小値である0に設定すると、モデルの制約が緩和され、学習しやすくなる。増加することで過学習を減らす。最適な値は0,5,15,300あたり。 |
|    eta, <br>num_round     |    learning_rate,<br> num_iteration    |    勾配降下のような学習重み。num_roundは、実行する学習ステップの数、つまり構築するツリーの数。<br>高いと学習率が上がるが過学習しやすくなる。ラウンド数を２倍し、etaを２で割る。学習に２倍時間がかかるが、モデルは良くなる。 |
|    seed     |    *_seed    |    Kaggleのコンペでrandom_seedを変えるだけで、順位が大きく変わらない程良い。 |

###CatBoost

One-hot-encoding
前処理の段階ではやるなというのが公式の指示。何よりも先に説明するあたり重要そうである。
categorical featuresについては、ちゃんと設定しないとよいスコアがでない。

一意の値が”one_hot_max_size”で設定したint以下の特徴量についてone-hot-encodingを適用する。
デフォルト値は2。

####Number of trees
　他のパラメータを調整する前に優先して設定する。反復回数を大きな値に設定しつつ、オーバーフィット検出器パラメータを使用し、最良のモデルオプションをオンにして検証する。

- iterations : まず大きな数を設定しておく。
- use_best_model : Trueにしておく。評価用のeval_setがfitのパラメータとして必要になる。
- eval_metric : overfitting detection と use_bset_modelで使用する評価指標。４１種
- od_type : IncToDecIter または　Iterを設定
- od_pval : IncToDeclterの場合に使用するしきい値。10^-10～10^-2が推奨されている。値が大きいほど、過学習が早期に予防される。デフォルトは0
- od_wait : 最適な指標値に達した後、iterationを続ける数。IncToDeclterの場合、しきい値を無視して指定回数を続ける。fitしたあと、model.tree_count_で最適な木の数がわかる。
たとえば以下のようになるか。

- learning_rate (float)
デフォルトは自動または0.03となる。
    - 最後のiterationに過学習がない → Learning rateを上げる。
    - 過学習している → Learning rate を下げる。


####色々試す必要があるもの
- depth (int)
４～１０が最適になることが多い。おすすめは６～１０

- l2_leaf_reg (int)
正則化係数。正の値のみ。これを使用するとlearning_rateが自動設定ではなくなる。

- random_strength (float)
木構造を構築する際、どのような分割したらコスト関数をより改善するかスコアを計算することになるが、そのスコアに加える正規分布確率変数（平均0）の標準偏差乗数。過学習対策に利用できる。（アンサンブルされる木構造のランダム性があがるため？）。デフォルトは１

- bagging_temperature (float)
ベイジアンブートストラップを使用すると（デフォルト）、訓練データをサンプリングする際にランダムな重みを割り当てることができる。bagging_temperatureのパラメータの値が「1」に設定されている場合、重みは指数分布からサンプリングされる。このパラメータの値が "0"に設定されている場合、すべての重みは1に等しくなる。パラメータは０～infの範囲で設定する。大きいほどbaggingが積極的になる。

- has_time　（bool）
時系列など、データセットに順序がある場合に使用する。

####オーバーフィット検出器
オーバーフィットが発生した場合、CatBoostはトレーニングパラメータよりも早くトレーニングを停止することができる。IncToDecとIterの２つのタイプがある。

- IncToDec
改善率CurrentPValueが設定した閾値を下回ったとき、トレーニングを停止する。
CurrentPValuenの計算式はよくわからない……。

- Iter
指標最大値を得た後、更新までのイテレーション回数の猶予

- ###Random Forest/Extra Trees
    - RandomForestの木はXGBoost等と異なり、独立している。
    - N_estimators : 木の深さ。高ければ高い方が良い。10から始めるのがおすすめ。XGBoostのmax_depthと同じ。
    - max_depth : 7からがおすすめ。10,20などと上げてみること。
    - max_features : XGBoostのcolsample_bytreeに相当する。高い方が学習しやすくなる。
    - min_samples_leaf : XGBoostのmin_child_weight、LightGBMのmin_data_in_leafに相当する。
    - criterion : GiniかEntropyを選択できる。通常Giniが良いが、たまにEntropyのパフォーマンスが良い時もある。
    - random_state : ランダムシードに相当する。
    - n_jobs : コアの数。デフォルトでは１が設定されているため、要指定。

- ###Neural Nets

    - Number of neurons per layer(1層毎のニューロンの数)：始めは1つまたは2つのレイヤーにするのがお勧め。
    - Number of layers(レイヤーの数)：1つのレイヤーあたり64のユニットから始めるのがお勧め。
    - Optimizer（Adam/Adadelta/Adagrad）
    - Batch size：お勧めは32または64の周りの値。多い程過学習しやすい。
    - Learning rate : 高すぎず、低すぎない値に設定する。他のパラメタと合わせて調整する。はじめは0.1などの高い値から始め、徐々に減らしていく。
    - ***-------------------------以下、増加することで過学習を減らす------------------------***
    - Optimizer（SGD + momentum）
    - Regularization(正則化)(L2/L1, Dropout/Dropconnect, Static dropconnect )：過学習した時は、まずドロップアウト層を試す。通常、ネットワークの終わり近くにドロップアウトレイヤーを追加するが、すべてのレイヤーにドロップアウトを追加しても問題なし。

- ###Linear Models
- Scikit-learn
 - SVC/SVR : libLinearとlibSVMがSklearnにはある。Sklearnでマルチコアを使うには手動でコンパイルが必要。
 - LogisticRegression/LinearRegression : 正則化したものがSklearnにはある。
 - SGDClassifier/SGDRegessor
- Vowpal Wabbit(データが膨大でメモリーをオーバーする場合に使う)
    - FTRL(Flow the Regularized leader) : HDDからデータを行ごとに読みこむ為、膨大なデータも扱える。Pythonにも実装されている。
- Regularization Parameter(C, alpha, lambda, ...) : 小さい値から始め、上げていく。Cが上がるにつれ、学習に時間がかかる。
- Regularization Type : L1/L2/L1+L2のどれも試してみること。L1は特徴を選択するのに用いることができる。

##Tips
####チューニングには時間をかけすぎないようにする。
特に、コンペが始まって間もない時は避け、特徴量エンジニアリングなど、他にやるアイデアがなくなった時にやること。

####忍耐強くやる
学習には時間がかかるが、精度が上げるには時間をかけることが大事な時もある。

####全ての平均をとる
５つのモデルを異なるランダムシードで学習させ、予測結果の平均をとる。
ランダムシード以外のパラメタでも有効である。
例えば、XGBoostの深さを最適な５に対して、３、５、６と分けて学習させ、予測の平均を出す。