ランダムフォレストと他の機械学習(or統計)を組み合わせて使う

もしかしたら、プロにとっては当たり前のテクニックかもしれませんが、自分は初めて見たので書きたいと思います。また、おそらく大きい効果を出すのが難しいテクニックだと思われるので、まずは基本的なことを先にやったあとに試したほうがいいでしょう。

追記 3/13 このテクニックは「stacking」と呼ばれるそうです。Twitterで教えていただきました。ありがとうございます!
Stacking, Blending and Stacked Generalization | Garbled Notes
Ensemble learning - Wikipedia, the free encyclopedia



ここから本題です。

前々回のTopCoder機械学習マラソンマッチTripSafetyは、飛行機のフライトデータから、違反フライトを予測するという問題でした。問題やデータはこちら

f:id:shindannin:20150313095715p:plain

予測精度をよくするために特徴量を追加したりするのですが、自分を含めて多くの人がやった手法は、特徴量(x24,x25,x26,x27,x28)だけを使って、新たな特徴量(x29)を追加するものでした。x24-x28は重混雑・中混雑・軽混雑と似たような指標なので、重み付けをして1つの特徴量にまとめるという発想は自然にでてくると思います。自分はx29 = 32*x25 + 8*x26 + 2*x27 + x28としました。
f:id:shindannin:20150313095726p:plain

しかし、優勝したPsyhoさんは、元の特徴量(x24,x25,x26,x27,x28)と目的変数yに対してを使って、ここで正則化つきの線形回帰を使って、その結果を新たな特徴量(x29)として追加しています。新たな特徴量を追加するのにxだけではなくyも使っているのが最大のポイントです。*1
f:id:shindannin:20150313095739p:plain

全体の流れは以下のようになります。

  1. 上記のように、訓練データのx24~x28とyを入力して、線形回帰して、x29=α24x24+...+α28x28+βの、α,βを求める。*2
  2. 訓練データのx1~x29(x29はx24~x28,α24~α28,βから求める)とyを入力して、ランダムフォレストで学習させる
  3. テストデータのx1~x29(同じくx29はx24~x28,α24~α28,βから求める)を学習させたランダムフォレストに入力して、yを予測する

線形回帰での予測結果x29を、y=x29としてそのまま答えにすることもできるのですが、線形回帰とランダムフォレストの2段構えになっています。

なぜ、これがうまいのかというと、

  • 線形回帰の予想精度が良ければ、その結果をほぼそのまま返すことができる。
  • 線形回帰の予想精度が悪かったとしても、ムダな特徴量が1つランダムフォレストに追加されただけなので、全体としての予想精度の低下はほとんどない。(ランダムフォレストでの寄与度がとても低い変数が増えただけ)
  • 線形回帰自体は表現力が高くないけど、その弱点をランダムフォレストでカバーできる。今回の場合でいうと、x29とyの値は近くないけど(特にy=1のとき)、この後にまだランダムフォレストがあるので、そこで精度を上げられる可能性がある。

参考までに、実際に100ケースで、自分のPCでテストしたところ、得点は285363点→288294点と約3000点増えています。あまり大きくはないですが、本番で2位だった112atn323さんとの点差も約3000点差と僅差だったなので、他の部分も十分詰めたあとなら試す価値はあると思います。*3

今回の問題では線形回帰でしたが、簡単にいえば機械学習(or統計)の手法の多くは、2つ組み合わせることができるということです。Psyhoさんのコードを見る限りでは、ロジスティック回帰+ランダムフォレストも試そうとしていたようです。

もちろん、複数の機械学習手法を試す人は多くいると思いますが、以下のどちらかが多いです。

  • 複数の手法を試して、その中で一番良かった手法を使う
  • 問題をいくつかのケースに分けて、ケースごとに一番良いものを使う(例:データが大きいケースはランダムフォレスト、小さいケースはニューラルネット)

でも、今回のPsyhoさんの解のように、2つの機械学習をあわせて使うのは、自分は初めて見ました。

ただ、まだ分かっていないのが、「どの特徴量に対して使うのが効果的か?」。これは難しいです。今回の問題だと、混雑度が大きければ大きいほど、違反フライトは単調増加しそうなので、線形回帰のように表現力低めの手法でも合いそうな気がしますが…。今のところは色々試す、そしてそれを自動化するぐらいしかないですね…。今後の課題です。

*1:yを使わずxだけを使って、線形回帰してxを追加するというのは、以前の記事で少しだけ述べたように普通に使われるテクニックです

*2:実際にはx1~x23を使って、さらにいろんな特徴量を追加してますが、ここでは説明を簡単にするために省きました。

*3:ただ、得点の評価については、本当はもっともっと試さないと正しく評価できないので、これより効果がもっと大きい可能性も小さい可能性もあります。