Walmart2015については、CrowdFlowerのSolutionを参考にしながら、いろいろと考えながらやってました。 結局xgboostとneural netのstackingくらいしかできませんでしたが。。(38th/1047)
その中で、kaggleの問題に対して”解”を出すのにあたって、どういうポイントがあり、どのように進めていくべきかの”構造”を考えてみました。
kaggle masterだけど機械学習は素人なので、突っ込みどころはいっぱいあると思います。ご指摘やこんな資料があるなど、教えていただければ助かります。
1 – 特徴量作成・管理
何だかんだいっても特徴量作成は重要で、重要な特徴量を逃すと勝ち目はないでしょう。
逆に適切な特徴量が作れれば、xgboostだけで勝てることもあるようです。(cf. Rossmann)
- 特徴量はN * M(N:ID, M:要素数)の数値の2次元配列として表現されます。
- 最初からIDに対して各列の要素があるDataFrameになっていれば簡単ですが(Prudentialとか)、IDに対してレコードが複数あるようなデータの場合、集計する必要があります。
- xgboostでは木なので何も考えなくて良い(しかもnanも受け入れてくれる)のですが、neural netやlinear regressionではカテゴリカル変数をダミー変数に直したり、logをとったり、標準化する必要があるようです。
汎用的に行うには、各foldごとに、train data – validation dataをまとめて、特徴量を作成することが必要ではないかと思っています。
(3foldの場合、各foldごとに同じように3回特徴量の作成を行う。また、submission用にはtrain data全体・test dataで同様に特徴量の作成を行う)
(cf. CrowdFlower1stのドキュメント 4.1.2 Following the Same Logic)- TF-IDFなどを行う場合には、validation dataもまとめて処理しないと、変なことになってしまいそうです。
- 教師ありで特徴量を作るときには、各foldのvalidation dataのlabelを使うとleakしてしまいそうです。
特徴量をどんどん作っていくとだんだんわけが分からなくなってくるのですが、どうやって管理したらいいのでしょう?
2 – モデリング
モデルは特徴量やパラメータを変えたりして試行錯誤する必要があります。
ここで、モデルを(特徴量の組・モデルの種類・モデルパラメータ)を引数とし、 (モデル, validation dataの予測値, validation score)を返すようなインターフェイスで表現することで、
特徴量選択やパラメータチューニングの自動化に進めるのではないかと思っています。
2-1. 特徴量選択
特徴量をいっぱい作ると、その選択に悩まされることになります。理想的には、特徴量をどんどん作って、後はmodelに選んでもらうのだと思いますが、以下の手法などがあるようです。
untuned modelling
xgboostやERTなどの分類器のパラメータを固定し、特徴量の組を変えて試し、scoreが良い特徴量の組を選択する。
このようにして選択した特徴量を、複数の分類器に展開していくこともできる。
(cf. Microsoft Malware 2nd)
greedy forward selection
以下のような手順で行います。
- 要素がN個ある場合に、それぞれの要素を試す
- 最もスコアの上がるものを選び、採用する要素に加える。
- 1-2を繰り返す。
(cf.smlyさんの講演資料)
ただ、N^2のオーダーで時間がかかるので、ちょっと時間がかかりすぎな気がしますが、どうやってfeature selectionに適用するのでしょう?
特徴量が大量にある場合
以下の方法があるようです。
- xgboostやrandom forestのimportanceの上位から選ぶ
(cf. tksさん-walmart2015) - chi2やinformation gainで選ぶ
(cf. Abhishek-walmart2015) - 出現数が一定以下の特徴量を落とす、まとめる
結局、当面の自分の方法は、特徴量の組のリストを手動で作成し、後はuntuned modellingで選ぶくらいになってしまいそうです。もっと汎用的な方法はあるのでしょうか?
また、分類器によって必要な特徴量が異なるので、全部の分類器を同じ特徴量で計算するわけにはいかず、なかなか難しいところです。
2-2. モデル選択
強そうなモデルから順に試していくしかない気がします。
私はとりあえずxgboost, neural net(keras), linear regression(vowpal wabbit)をある程度しっかり使えるようにしたいと思っています。
その次はscikit-learnのSVMやERT(Extremely Randomized Tree)でしょうか。
2-3 パラメータ選択
ハイパーパラメータによって大きく精度が変わる場合、どうしても多くの試行をする必要があります。
人の手で1つ1つ回してもしょうがないので、やはりこれも自動化したいところです。
pythonではhyperoptが人気のようです。(他には、baysien optimizationなどの方法もあるようですが)
hypetopt
Tree of Parzen Estimatorsという手法により良さげなパラメータを選んでくれます。
使ってみた感じだと、最低25-50回くらいは回さないと、使う意味がなさそうです。
CrowdFlowerの1stの解法では、hyperoptがふんだんに使われています。
てれかさんの記事も参考になります。
3 – アンサンブル
diverseなモデルを複数組み合わせると精度が上がるようです。その方法としては、stackingが基本のようです。
stacking
以下の流れになります。
- あるモデルで、k-foldで各foldのvalidation dataの予測値を作成する
- あるモデルで、train data 全体 – test dataでtest dataの予測値を作成する
- 1-2を組み合わせると、あるモデルの予測値でできた特徴量ができる
- 1-3を色んなモデルで組み合わせると、モデル数分の特徴量が作れる
- 元の特徴量と生成した特徴量を組み合わせたものを新たな特徴量として、ensemble用のモデルを用いて最終的な予測値を作成する。
- ensemble用のモデルはとりあえずxgboostで良いような気がするのですが、NNやERTなどを使うメリットもあるのでしょうか?
- kaggle ensemble guideではblendingという手法も紹介されています。ただ、例えば1/10をhold out setとして取っておくという方法なので、データ量が十分大きくないと、submissionはともかく手元のvalidation scoreの評価が難しいように思います。
(cf. kaggle ensemble guide、puyokwさんの記事)
4. その他
技術の優れた常連kaggle masterに対抗するには、データをちゃんと理解することが必要な気がします。
そのために、プロット、モデルから出力される変数重要度を見る、誤差の分析、泥臭さ などいろいろありそうですが、今回は割愛します。