本文へスキップ
ひもとくAI

アンサンブル学習:バギング・ランダムフォレスト・ブースティング

レッスン 3/7

アンサンブル学習:たくさんのモデルで多数決をとる

1人より、みんなで決めた方が当たることがある

クイズ番組で、1人の答えより、会場の多くの人の多数決の方がよく当たる、という話を聞いたことがあるかもしれません。機械学習でも、たくさんのモデルの予測を組み合わせると、1つのモデルより正確になることがよくあります。これを アンサンブル学習 と呼びます。

計算してみる:正解率0.7のモデルを集めて、多数決をとる

正解率0.7のモデルがいくつかあり、それぞれのモデルの間違いが、互いに関係なく(独立に)起こる とします。多数決が正解になる確率は、第10章の二項分布で計算できます(半分より多くのモデルが正解すれば、多数決は正解)。

モデルの数1351151101
多数決の正解率(各モデル0.7)0.7000.7840.8370.9220.9991.000
多数決の正解率(各モデル0.45)0.4500.4250.4070.3670.2360.156

各モデルが0.7なら、数を増やすほど多数決の正解率は1に近づきます。一方、各モデルが0.45(当て推量の0.5より悪い)だと、数を増やすほど多数決は 悪く なります。多数決で強くなるには、次の2つが必要です。

  1. 1つ1つのモデルが、当て推量よりは当たる
  2. モデルどうしの間違い方が、ばらばら(同じところで同じように間違えるなら、何個集めても1個と同じ)

実際のモデルは、同じデータで学習すると同じような間違い方をしやすいので、表のようにはうまくいきません。そこで、わざとモデルごとに違いを作る 工夫をします。

バギング:データを少しずつ変えて、たくさん学習させる

訓練データから、重複を許して データをでたらめに選び、元と同じ数の「少し違う訓練データ」をたくさん作ります(1つのデータが2回選ばれたり、1回も選ばれなかったりする)。この選び方を ブートストラップ と呼びます。それぞれの訓練データでモデルを1つずつ学習させ、予測は多数決(回帰なら平均)で決めます。この方法を バギング と呼びます。

ランダムフォレスト:決定木のバギング + 特徴量もでたらめに

ランダムフォレスト は、決定木(第5章)をバギングで集めたものです。さらに、木が分かれ道の質問を選ぶときに、すべての特徴量ではなく、でたらめに選んだ一部の特徴量の中から 選びます。こうすると、木どうしがさらに違った形になり、間違い方がばらばらになります。

決定木は、訓練データの小さな違いで形が大きく変わる(バリアンスが大きい、第8章)モデルです。この「不安定さ」が、アンサンブルでは、ばらばらな間違い方として役に立ちます。

実験:ランダムフォレストと、ブースティング

弱い木を集めると、強い森になる

手書き数字のデータ(テストデータ3割)で、決定木1本とランダムフォレストを比べました。

モデルテストデータの正解率
決定木1本(すべてのデータ・すべての特徴量で学習)0.857
ランダムフォレストの中の木を1本ずつ(100本の平均)0.743(一番悪い木0.683、一番よい木0.798)
ランダムフォレスト(100本の多数決)0.978

森の中の木は、ブートストラップで選んだデータと、でたらめに選んだ特徴量だけで作られるので、1本ずつではふつうの決定木(0.857)より 弱く、平均0.743しかありません。それでも、100本の多数決では0.978になりました。1本ずつの強さより、「間違い方がばらばら」であることが効いているのです。

データの分け方を5通りに変えても、決定木1本は0.839〜0.859、ランダムフォレストは0.957〜0.978で、いつも森の方が大きく上回りました。

ブースティング:前のモデルの間違いを、次のモデルが直す

バギングは、たくさんのモデルを それぞれ独立に 作りました。ブースティング は、モデルを 1つずつ順番に 作り、新しいモデルに「それまでのモデルが間違えたところ」を重点的に学習させます。

  • AdaBoost: 間違えたデータの重みを大きくして、次のモデルがそのデータを重視するようにする
  • 勾配ブースティング: それまでのモデルの予測と正解との「ずれ」(損失の勾配)を、次の木が予測するように学習させ、少しずつ足していく。第4章の勾配降下法を、「木を1本ずつ足す」形で行っているとも言える
木の数正解率0204060801000.70.80.91
  • ランダムフォレスト
  • 勾配ブースティング
  • 決定木1本(0.857)
木の数(横軸、1〜100本)と、手書き数字のテストデータの正解率(縦軸)。ランダムフォレストは、1本で0.741、10本で0.943、100本で0.978と、木を増やすほど上がる。勾配ブースティングは、1本で0.778、10本で0.874、50本で0.941、100本で0.950と、ゆっくり上がる。どちらも10本前後で、決定木1本(0.857、水平な線)を上回る

ランダムフォレストは、木を増やしても過学習しにくく(300本で0.980)、増やすほど安定します。勾配ブースティングは、順番に間違いを直していくので、木を増やすほど訓練データに合わせていきます。このデータでは100本で0.950でしたが、ほかのハイパーパラメータ(1本の木の深さ、1本ずつ足す量を決める学習率など)の調整で、大きく変わります。

勾配ブースティングは、表の形のデータ(売り上げ、顧客の情報など)で特に強く、データ分析のコンテストで上位を占めることが多い手法です。高速に学習できるように工夫したライブラリ(XGBoost、LightGBM など)が広く使われています。

Pythonでアンサンブルを使う、よくある誤解と振り返り

from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier

forest = RandomForestClassifier(n_estimators=100, random_state=0)   # 木の数100本
forest.fit(X_train, y_train)
print(forest.score(X_test, y_test))           # 手書き数字 → 0.978

boost = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=0)
boost.fit(X_train, y_train)
print(boost.score(X_test, y_test))            # 手書き数字 → 0.950
  • n_estimators は木の数です。ランダムフォレストは、多いほど安定します(時間はかかります)
  • ブートストラップや特徴量の選び方に乱数を使うので、第9章のとおり random_state を決めておきます
  • 決定木を使うので、標準化は必要ありません(「いくつ以上か」で分けるだけなので、値の大きさの違いに左右されない)
  • ランダムフォレストの feature_importances_ で、どの特徴量が分かれ道によく使われたか(不純度をどれだけ減らしたか)が分かります。第9章の並べ替えによる重要度と同じく、似た特徴量があると重要度が分かれることに注意します

よくある誤解

  • 「モデルをたくさん集めれば、必ず強くなる」: 当て推量より悪いモデルを集めると、多数決はかえって悪くなります(0.45のモデル101個で0.156)。また、同じ間違い方をするモデルをいくら集めても、よくなりません
  • 「ランダムフォレストの木は、1本ずつでも強い」: 1本ずつの正解率は平均0.743で、ふつうの決定木(0.857)より弱いのです。強さは、多数決から生まれます
  • 「バギングとブースティングは同じ」: バギングはモデルを独立に作って、主にばらつき(バリアンス)を減らします。ブースティングは順番に作って前の間違いを直し、主に大まかすぎる誤り(バイアス)を減らします

振り返り

  • アンサンブル学習は、複数のモデルの予測を多数決(回帰なら平均)でまとめる。1つ1つが当て推量より当たり、間違い方がばらばらなほど効く
  • バギングは、ブートストラップで作った少し違う訓練データで、モデルを独立に学習させる。ランダムフォレストは、決定木のバギングに、特徴量のでたらめな選択を加えたもの
  • ブースティングは、前のモデルの間違いを次のモデルが直すように、順番にモデルを足していく(AdaBoost、勾配ブースティング)

演習

演習を読み込んでいます…