XGBoostやパラメータチューニングの仕方に関する調査

【目次】
・XGBoostとは
・XGBoostで用いるパラメータ一覧
・XGBoostのパラメータチューニング
・参考文献

XGBoostとは

XGBoost (eXtreme Gradient Boosting) は勾配ブースティングアルゴリズムの先進的な実装例で、データサイエンスのコンペであるKaggleで話題となっていた手法です。

ブースティングアルゴリズムとは、弱識別器(weak learners)の集団を直列的に結合することで、予測における正確性を高めようとするアルゴリズムです。任意のt時点において、モデルの予測は以前のt-1時点での結果に基づき重み付けがなされます。正しく予測されたデータに対しては、重みを小さくし、誤って予測されたデータに対しては重みを大きくします。後で学習する識別器ほど、誤ったデータに集中して学習を進めることになります。

以下はブースティングのイメージ図です。
スクリーンショット 2016-04-24 18.40.38

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

最終的にはこのような決定境界を引くことができるような識別器を求めていきます。
スクリーンショット 2016-04-24 18.55.53

勾配ブースティングの勾配とは、ブースティングアルゴリズムにおけるパラメータ推定での最適化手法が勾配降下法に従っているという意味での勾配です。以上が勾配ブースティングモデルの簡素な説明です。

XGBoostで用いるパラメータ一覧

XGBoostで用いるパラメータに関して、大きく分けて3つあります。

    1.全体パラメータ・・・XGBoost全体を司る。
    2.ブースターパラメータ・・・各ステップでツリーなどのブースティングを司る。
    3.学習タスクパラメータ・・・最適化タスクを司る。

以下、3つのパラメータについて、「パラメータ名」・「デフォルトの値」・「役割」・「引数」を表にしています。

1.全体パラメータ

パラメータ名 デフォルトの値 役割 引数
booster gbtree 実行するモデルのタイプをツリーモデルか線形モデルのどちらかを指定できる。 gbtree: ツリーモデル
gblinear: 線形モデル
silent 0 モデルの実行結果を出力するかどうかを決めることができる。モデルを理解する上で、0のままにしておく方が良いとされている。 0:出力結果を表示する。
1:出力結果を表示しない。
nthread not set 並列処理のためのコア数などを指定できる。フルコアで実行したい場合は何も指定しなければ自動的にフルコアになる。

2.ブースターパラメータ

パラメータ名 デフォルトの値 役割 引数
eta 0.3 学習率を調整できる。
小さくすることで、モデルの頑健性を高めることができる。
0.01〜0.2の値になることが多いらしい。
min_child_weigh 1 子ノードにおいて観察されるデータの重み付けの合計値の最小の値で、過学習を避けるために用いられる。
高い値にすることで特定のサンプルに観察されるような傾向を学習することを避けられる。ただし、高くし過ぎるとフィッティングが悪くなる。
max_depth 6 木の深さの最大値
過学習を制御するために用いられる。
高いと過学習しやすくなる。
3〜10の値になることが多いらしい。
max_leaf_nodes 木の終端ノードの最大値
max_depthの代わりに用いる
n本を指定したら、n^2個の枝を生み出す。これが指定された場合は、max_depthは無効化される。
gamma 0 分割が、損失関数の減少に繋がる場合にのみノードの分割を行う。
モデルをより保守的にする。
値は損失関数に応じて大きく変わり、チューニングが必要である。
max_delta_step 0 各木のウェイトの推定に制約をかけることができる。
0の場合は制約なしで、正数値を取るとモデルがより保守的になる。
通常は必要とされないが、不均衡データの分類の際に用いる。
subsample 1 各木においてランダムに抽出される標本の割合
小さくすることで、過学習を避けることができるが保守的なモデルとなる。
0.5〜1の値になることが多いらしい。
colsample_bytree 1 各木においてランダムに抽出される列の割合 0.5〜1の値になることが多いらしい。
colsample_bylevel 1 各レベル単位での、分割における列のsubsample比率
subsampleとcolsample_bytreeで十分なので、あまり使わないが、探索してみるのも良いかもしれない。
lambda 1 重みに関するL2正則化項
多くのデータサイエンティストは使わないが、過学習を避けるためには用いられるべき。
alpha 0 重みに関するL1正則化項
高次元の場合に用いるらしい。
scale_pos_weight 1 不均衡データの際に、0以上の値を取ることで、収束を早めることができる。

3.学習タスクパラメータ

パラメータ名 デフォルトの値 役割 引数
objective reg:linear 最小化させるべき損失関数を指定する。 binary:logistic→2項分類で確率を返す。
multi:softmax→多項分類でクラスの値を返す。
(num_classでクラス数の指定が必要)
multi:softprob→softmaxと同じだが、確率を返す。
eval_metric according to objective 検証を行うためのデータの評価指標 rmse – root mean square error
mae – mean absolute error
logloss – negative log-likelihood
error – Binary classification error rate (0.5 threshold)
merror – Multiclass classification error rate
mlogloss – Multiclass logloss
auc: Area under the curve
seed 0 ランダムなシード番号。
再現可能なデータを生み出すために、あるいはパラメータチューニングの際に用いる。

 

 

XGBoostのパラメータチューニング

複数のパラメータからなるXGBoostのチューニングは非常に複雑で、理想的なパラメータについてはケースバイケースで何とも言えないそうです。

参考文献のブログにパラメータチューニングの一般的アプローチについて触れられていたので、紹介します。

    1.相対的に高い学習率を選択する。
    一般的な学習率0.1はうまくいくが、ケースによっては0.05から0.3の間でもうまくいく。学習率を求めるために、クロスバリデーションによって最適な木の数を決定する。
    2.木に関するパラメータをチューニングする。
    固定された学習率や木の数のもとで、max_depth, min_child_weight, gamma, subsample, colsample_bytreeをチューニングする。
    3.正則化パラメータをチューニングする。
    lambda, alphaなどのパラメータをチューニングすることで、モデルの複雑さを減らし、パフォーマンスを高める。
    4.学習率を下げ、最適なパラメータを決定する。

具体的な実行に関するPythonスクリプトはこちらのGithubで紹介されています。(iPython)
Analytics_Vidhya/Articles/Parameter_Tuning_XGBoost_with_Example/XGBoost models.ipynb
この方法に従って、自社で抱えているモデルのチューニングにチャレンジしてみようと思います。

参考文献

Quick Introduction to Boosting Algorithms in Machine Learning
Complete Guide to Parameter Tuning in Gradient Boosting (GBM) in Python
Complete Guide to Parameter Tuning in XGBoost (with codes in Python)
勾配ブースティングについてざっくりと説明する
xgboost のパラメータ
OS X で XGBoost & xgboost4j をビルドする手順 2016-03-07 版

GensimのHDP(Hierarchical Dirichlet Process)をクラシック音楽情報に対して試してみる

HDP(Hierarchical Dirichlet Process)いわゆる階層ディリクレ過程を実行できるモデルがPythonのGensimライブラリにあるという情報から、あまり実行例も見当たらないので、チャレンジしてみました。

HDP(Hierarchical Dirichlet Process)

HDP(Hierarchical Dirichlet Process)は文書集合全体のトピック数と文書ごとのトピック数の推定を行うことができる手法で、中華料理店フランチャイズという仕組みを用いています。通常のLDAなどでは、分析者が任意のトピック数を決める必要がありましたが、与えられたデータからその数を推定するため、その必要がないというのがHDPを使うことの利点であると思われます。

実行までの流れ

ざっくりですが、
・コーパスの準備・文書の分かち書き(名詞のみ)
・HDPの実行
という流れです。

ちなみに実行環境は
MacBook Pro
OS X Yosemite 10.10.5
2.6 GHz Intel Core i5
メモリ8GBです。

コーパスの準備

今回は、以前手に入れた某辞典サイトのクラシック音楽情報1800件のテキストデータ(1行に1件分の文字列が入っているデータで16MBくらい)があるので、それをコーパスとして使います。参考情報として挙げているブログの助けを借りて、文書単位でMeCabにより形態素解析で分かち書きした結果から、意味を持ちやすい品詞として、「名詞」に該当するもののみを結果として返す以下のPythonスクリプトを用いました。結果はtmep.txtとして出力されます。もっと良いやり方があると思いますが、目的は達成できると思います。ちなみに、MeCab Neologd(ネオログディー)という、固有名詞などに強いシステム辞書を活用してみたかったので、その利用を前提として書いています。MeCab Neologd(ネオログディー)のインストール関連の情報は参考情報にありますので、チャレンジしてみてください。(OSXかUbuntuの方が進めやすいと思います。)

こちらのスクリプトをターミナルで実行します。(解析するディレクトリ下で実施しています。)

HDPの実行

以下のPythonスクリプトで実行しています。

HDPの結果について

topic_detail.csvの結果を見たところ、トピックの数が150個もあって、「本当にトピックの数を自動で決めれているのかなぁ」と不安に思ったのですが、実際に各文書に割り当てられているトピックの数は、先ほど出力したtopic_for_corpus.csvで見ると60個でした。そのため、今回、HDPに従って決まったトピック数は60ということになります。さらに不安に思ったので、Stack Over Flowで調べていたんですが、トピックは150個出るけど確率が割り振られていないはずと回答されていました。( Hierarchical Dirichlet Process Gensim topic number independent of corpus size

出現頻度の高い上位10のトピックは以下の通りです。

加えて、トピックごとに文書に割り当てられた数を集計してみましたが、topic0が圧倒的に多く、コーパスの特性上、含まれやすい情報がここに集まっているのではないかと思います。幅広いテーマを抽出できるかと期待していたのですが、やたらと個別具体的な「トゥーランドット」や「ワーグナー」や「カルメン」などがトピックの上位単語に上がってきています。実行方法を間違えているかもしれないし、パラメータチューニングなどをもっと頑張れば、幅広いトピックを得ることができるかもしれないので、今後の課題としたいです。

スクリーンショット 2016-04-10 18.23.37

参考情報

・トピックモデルについて
machine_learning_python/topic.md at master · poiuiop/machine_learning_python · GitHub

・HDP関連
 models.hdpmodel – Hierarchical Dirichlet Process
Online Variational Inference for the Hierarchical Dirichlet Process

・MeCab関連
mecab-ipadic-NEologd : Neologism dictionary for MeCab
形態素解析器 MeCab の新語・固有表現辞書 mecab-ipadic-NEologd のご紹介
テキストマイニングの前処理。名詞抽出、ストップワード除去、珍しい単語の除去

・Python関連
データ分析をやりたいエンジニアにおすすめ!Pythonの入門スライド13選

Word2Vecでクラシックの楽曲情報をコーパスとして類似度を出してみる

あの手この手を使って手に入れた、およそ1800曲に及ぶクラシック音楽の楽曲情報(テキスト)をもとに
、PythonのGensimライブラリーのWord2Vecを使って、任意の単語に関する類似単語を出力してみたいと思います。

まずは、手に入れたコーパスを作業フォルダに置いて、MeCabによる分かち書きを行います。
(最後の引数-bは、処理する文書のサイズが大きい際に調整します。)

後はGensimパッケージを読み込んで、

Word2Vecを計算させるだけです。

(引数のsizeは特徴ベクトルの次元数です。)

早速、トランペットについて、所与のコーパスにおける類似単語を見てみたいと思います。(類似度が最も高い単語の上位10位の結果を返しています。)

惜しいですね。
願わくば、コルネットが一番目に来てほしかったです。オケの編成上、どうしてもトロンボーンが一緒の文書で出やすいのだと思います。

続いては、ピアノです。こちらもオルガン・チェンバロは非常に近い楽器だと思うのですが、一番目がヴァイオリンというのはデータ上仕方がないのかもしれません。

続いて、ヴァイオリンですが、ヴィオラ・チェロは良いと思うのですが、ピアノやチェンバロなどが上位に来ています。

続いて、クレッシェンドですが、似たような意味はあまり観察されていません。ただし、「クライマックス」・「アルペッジョ」などと似たようなシチュエーションで登場しそうな表現な気がします。

最後に、アレグロですが、こちらは速さの序列に関しては守られていないようです。やはりコーパス次第ですかね。
プレスト > アレグレット > モデラート > アンダンテ > アダージョ > ラルゴ
この序列が守られるようなWord2Vecの実践例などがあると面白いですが。

仕事でWord2Vecを使うシーンがあるとしたら、広告文のアイデアを助けたり、語彙力の弱い人の補助的なツールとして使えるかもしれませんが、実用レベルはまだまだ遠い気がします。

おまけ

左手に関しては、最も類似した単語が「右手」という結果になっています。

参考文献

models.word2vec – Deep learning with word2vec

岩波データサイエンス Vol.2 岩波データサイエンス刊行委員会 編