Np-Urのデータ分析教室

オーブンソースデータなどWeb上から入手できるデータを用いて、RとPython両方使って分析した結果を書いていきます

【アンサンブル学習】多様性が大事? バギング・ランダムフォレスト編

前回・前々回は、決定木と木の剪定方法について学習しました。
www.randpy.tokyo
www.randpy.tokyo

決定木は、可読性が高いという点で実際に今働いている職場でもよく使われる手法ですが、問題点としては学習データに依存しすぎる点にあり、汎用的なモデルを作ることが難しいです。

今回は、そのような問題に克服するためのバギング・ランダムフォレストの手法についてやっていきます!
また関連する手法で、kaggleなどでよく使われるブースティングについては、また別途まとめたいと思います。

今回も「はじめてのパターン認識」を参考にさせていただきながら、なるべくわかりやすく説明していきたいと思いますー!

はじめてのパターン認識

はじめてのパターン認識

バギング

バギングは、ブートストラップサンプリングで得られた学習データを使って、識別器を複数作り、それらの識別器の多数決をとることによって、一つの識別器よりも性能の高いモデルを作ることができます。

ブートストラップサンプリングは、学習データを元に復元抽出して別のデータセットを作る、という操作を繰り返し行うことで、新しいデータセットを複数作るというものです。

復元抽出とは、例えばボールがN個が入った袋から、一個ボールを取り出して、また袋に戻してから一個とりだすという作業をN回繰り返すといったイメージです。
そうすると、元の学習データとは少し異なるデータが手に入ります。これを仮に1000回行うと、1000個の新しいデータが手に入ります。

このようにして作られた複数の学習データセットを使って識別器をたくさん作り、総合的に判断を下すというところがバギングのミソになります。

なぜ、複数の識別器を作ったほうが良いのか?

例えば、数学で分からない問題があったとしましょう。そんなあなたは、1つ学年が上のクラスの先輩方に、問題の答えを聞きに行きました。

ある一人の先輩の回答を聞いて、「なるほど!それが正解か!」と信じられるでしょうか?
超優秀な先輩だった場合なら信じていいかもしれませんが、誰にだって間違いはあるので、正直なところ他の先輩方の回答も聞いてみたいですよね?

つまり、一人の生徒の回答結果を信じるよりも、複数の生徒の回答を聞いて一番多かった回答を正解とする方が「当たってる確率は高そうだし安心だ!」というわけです。

バギングも、色々な識別器の結果を集めて多数決を取ることで、性能をあげ安定したモデルを構築することができます。
イメージにすると以下のような図です。(はじめてのパターン認識より参照)
f:id:gl2000-sans:20170916102007p:plain

さて、バギングなるほどな!と思って頂いた所で、この手法にも少し問題があります。
複数の識別器の違いは、ブートストラップサンプリングのばらつきによるものなので、似たような識別器が多く作られてしまう可能性が高く、性能の良いモデルにならないことがあります。

先ほどの学校の例を振り返ります。ある特定のクラスの生徒を複数人集めて多数決をとっても、同じクラスに所属している生徒は皆同じ教育を受けているため、似たような人材が多いと考えられます。

つまり、多数決をとっても皆同じ意見しか出さないので、あまり意味がありません。仮に、多様な生徒を集めることができたら、より多様な意見が集まり、有用な意見をくれるでしょう。

さて多様性をもった生徒を集めるにはどうしたらいいもんか?……というところで、ランダムフォレストという手法に繋がります!

ランダムフォレスト

ランダムフォレストはバギングを改良して、多様な識別器をいっぱい作る手法になります。

先ほどのバギングでは、識別器の違いがブートストラップサンプリングのばらつきによることだけだったのに対して、ランダムフォレストでは、それに加えて、各識別器で使用する特徴量を、あらかじめ決められた数だけランダムに選択するようにしてあげます。
ここがバギングとの大きな違いになります。

f:id:gl2000-sans:20170916102102p:plain
ランダムフォレストは、識別器によって使用する特徴量を変えるだけという、とてもシンプルなアイデアですが、性能が非常に良いということでよく使われる手法の一つです。

さて先ほどの例を改めて見てみましょう。あるクラスから生徒を集めて多数決をとる部分は先ほどのバギングと同じ考えです。今回違う部分は、生徒はそれぞれ受けている授業のカリキュラムが違うという点です。

同じクラスでも、生徒Aはカリキュラム1を受け、生徒Bはカリキュラム2を受けて…と生徒それぞれが別々の授業を受けているとします。
こうすることで、生徒間(=識別器間)に多様性が生まれ、様々な問題に対して多様な答えを出すようになります。

こんな多様的なクラスがあれば、質問しに行っても安心ですね!
社会もそうですが、やはり多様性というのが大事なんですかねー。(ゆとり世代の小言…)

ちなみに、ランダムに使用する特徴量の数ですが、特徴量が全体でX個あった場合、\(\sqrt{X}\)個が推奨されていますが、問題によっては最適な数というのは変わるので、パラメータとしてチューニングする必要はあります。

ランダムフォレストの特徴

ランダムフォレストの特徴は以下のようなものが挙げられます。

  • 森のサイズ(識別器の数)を大きくしても過学習が生じにくい
  • 特徴量の重要度を計算できる
  • 学習データ間の近さを計算することができる

実務で使っていて便利だと思うのは、やはり特徴量で何が効いているのか出せる所だったりします。

特徴量の重要度は、各特徴がノードで使われた時の不純度の減少量を識別器全体で平均して算出します。用途にもよりますが、変数作成の際の指標としても使えますし、レポートする場合などにも便利ですね。

この辺りは、実際に分析をしてみないとよくイメージがつかないと思うので、実践記事で一緒にやっていきましょう!

終わりに

さて、決定木・剪定・ランダムフォレストと一区切りついたので、
次回はいよいよRとPythonによる実践編に移りたいと思います!

決定木とバギング、ランダムフォレストによってモデルの精度がどれくらい変わるのかといった部分に注目して頂けるとよりランダムフォレストの精度の高さがお分かり頂けるかと思います。(まだ分析してないので、結果がどうなるか分かりませんが笑)

また、機械学習における一つのテーマでもあるハイパーパラメータのチューニングについても触れていきたいと思いますのでご期待くださいませ!