学生による学生のためのデータサイエンス勉強会

【さきどりPython#6】ランダムフォレストで学ぶアンサンブル学習

複数の学習モデルの結果を利用する学習手法をアンサンブル学習といい、正解率や精度の向上に有効であると考えられています。

初学者にとってアンサンブル学習は難しいかもしれません。

なぜなら、基本となる学習モデルを理解することがアンサンブル学習のスタート地点であるためです。

そこで今回は、ランダムフォレストを例にしてアンサンブル学習の基本を学んでいきましょう。

アンサンブル学習は3つに大別される。

アンサンブルメソッドとは、複数の弱学習器を結合し、強学習器を作る手法です。

強学習器は、複数の弱学習器からなるモデルであり、その組み合わせの方法でバギング、ブースティング、スタッキングに大別されます。

バギング

バギング bagging とは、弱学習器を並列に並べるアンサンブルメソッドです。

「並列」というのは、それぞれの弱学習器が独立しているという意味です。お互いがそれぞれの標本をもとに学習を進めます。

バギングの由来

baggingは、bootstrap aggregatingの略であり、1つの単語ではありません。直訳すると「ブートストラップのかたまり」くらいの意味です。

bootstrapとはブーツのストラップ、つまり靴の足首部分にある輪っかのことです。靴を履くときに引っ張り上げる部分ですね。

bootstrap

ブートストラップはもともと、「思い切り引っ張っても、体が浮き上がることはない」つまり「無駄な頑張り」を指す言葉として使われていました。

しかし次第に「引っ張り上げる」ことがフォーカスされ、機械学習や統計学の文脈では「手元にあるデータをうまく使って、予測精度を向上させる」という意味で使われるようになりました。

ブートストラップ法

では具体的にブートストラップ法を見ていきましょう。

ブートストラップ法は復元抽出法の1つです。

例えば、標本数が1000個ある場合、ランダムに1つの標本を取り出します(標本抽出)。そして取り出した標本を戻し、またランダムに標本を1つ取り出す……ということを繰り返し、合計1000回標本抽出を行います。

当然、何度かは同じ標本を引き当てることでしょう。しかしそれで良いのです。

同じ標本を引き当てたら標本集団に偏りが出るんじゃないの?」と思うかもしれません。確かにそうかもしれません。

しかしそもそも標本集団自体が、母集団から偏りなく抽出されたものかは分からないのです。

そのためブートストラップ法では、復元抽出で作った標本集団をいくつか作ることで母集団の性質を明らかにしようとしているわけです。

この復元抽出(bootstrap)で作った標本集団をいくつか作って、結果をまとめる(aggregating)手法こそbaggingというわけです。

ブースティング

ブースティングの数理的な解説は別の機会に行います。今回は概念的に理解してください。

バギングでは、ブースティングにより新しい標本集団を作成し、複数のモデルを学習させました。これが「バギングは弱学習器が並列に並ぶ」というイメージにつながっています。

これに対し、ブースティングは「直列」のイメージです。

1つ目の弱学習器の結果を利用して、2つ目の弱学習器を学習させるのです。

AdaBoost

ブースティングの1つであるAdaBoostは、Adaptive Boostingの略です。

Adaptiveとは「適応的」という意味ですが、具体的には「自分より前の弱学習器の間違いに適応した」ということです。

言い換えると、1つ前の弱学習器の出力のうち、観測値(Grand Truthともいいます)と異なっている推測値を修正するように現在の弱学習器は学習を勧めます。

このように弱学習器が直列に並んで、順次学習していくのがブースティングです。

スタッキング

スタッキングは、弱学習器が独立しているという点ではバギングと似ているかもしれません。

しかしそれぞれの弱学習器は最終的な推測値を出力するわけではありません

弱学習器の出力を特徴量として最終的なモデルに入力する手法がスタッキングです。

kaggleなどのコンペでハイスコアを出しているのは、ほとんどこのスタッキングによるものです。

スタッキングは、アンサンブルの仕方によって結果が大きく変わってくるので、ある意味で技術というよりも芸に近いかもしれません。

しかし様々な機械学習モデルを複合させるという考え方は、非常に自然で難しいことではありません。難しいのは実際にどう組み合わせれば、良い結果を出せるのかという試行錯誤です。

scikit-learnによるランダムフォレストの実装

では実際に実装を見てみましょう。irisデータを用いた分類モデルです。

from sklearn.ensemble import RandomForestClassifier
from sklearn import datasets

# データをロード
iris = datasets.load_iris()
features = iris.data
target = iris.target

# ランダムフォレスト分類器を作成
randomforest = RandomForestClassifier(random_state=0, n_jobs=-1)

# ランダムフォレストクラス分類器を訓練
model = randomforest.fit(features, target)

これで学習は終了しています。

このモデルを使用するには以下のようにします。

# 新しい観測値を作成
observation = [[5, 4, 3, 2]]

# 観測値のクラスを予測
model.predict(observation)

上記のようにリストで標本データを渡すと、推測クラスが返ってきます。

array([1])

これはクラスが1という結果でした。

ランダムフォレストはバギングの一種

ここでおさらいです。

ランダムフォレストはアンサンブル学習の1つです。そしてアンサンブル学習は、バギング、ブースティング、スタッキングに大別されることも説明しました。

ランダムフォレストは、バギングに大別されます。

複数の決定木が「並列に」並んでいます。それぞれの決定木に渡される標本は、ブートストラップ法で作られた集団です。

ランダムフォレストはいくつの決定木から構成されるか

scikit-learnのアルゴリズムでは、デフォルトで100個の決定木が作られます。

もし決定木の数を変えたいときは、引数n_estimatorsで指定しましょう(整数)。

不純度の指標

デフォルトではジニ不純度が設定されています。

変更したい場合は、criterion="entropy"としましょう。教科書ではこれに設定してあります。

ランダムフォレストの出力

複数の弱学習器(今回は決定木)の出力は最終的に1つにまとめられます。

ランダムフォレストの場合、弱学習器のそれぞれの出力の平均値が全体の出力になります。

バギングでは複数の弱学習器が独立しています。したがって、学習器の数だけ出力があります。

そのためランダムフォレスト以外では、最も正解率の高いモデルの出力を全体の出力とする場合もあります。


まとめ

以上、ランダムフォレストの基本についてまとめてみました。

今回はランダムフォレストの構成について解説しましたので、次の機会ではランダムフォレストで行う工夫についても話したいと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です