LoginSignup
20
20

More than 5 years have passed since last update.

scikit-learnでバギングとブースティングをやってみる

Posted at

はじめに

複数のモデルを組み合わせて学習する方法をアンサンブル学習といいます。様々な分類器を組み合わせることで汎化性能を上げることが出来ます。

ここではバギングとブースティング(Adaboost)について見ていきます。

参考

環境

  • MacOS Mojave 10.14.2
  • scikit-learn==0.19.1

手順

バギング

元の訓練データからランダムにn個のデータを重複を許して抽出する、ということを繰り返してデータセットをn_estimators個作ります。これをブートストラップといいます。作成した各データそれぞれに対してモデルを作成します。予測はこの多数のモデルを集約して予測します。結果の集約は分類であれば多数決、回帰であれば平均値を取るなどします。

それぞれのモデルが学習の際に使用するデータは少しづつ異なるため、汎化性能を向上させられる可能性があります。

分類問題であればBaggingClassifierを、回帰問題であればBaggingRegressorを使用します。n_estimatorsが作成するデータセットの数=モデルの数で、max_samplesは抽出する際のデータ数の上限、max_featuresは抽出する際の特徴量の数の上限を指定できます。

import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier

loaded_data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    loaded_data.data, loaded_data.target, random_state=0)

models = {
    'not bagging': DecisionTreeClassifier(random_state=0),
    'bagging': BaggingClassifier(DecisionTreeClassifier(random_state=0), n_estimators=100, random_state=0) 
}

scores = {}
for model_name, model in models.items():
    model.fit(X_train, y_train)
    scores[(model_name, 'train_score')] = model.score(X_train, y_train)
    scores[(model_name, 'test_score')] = model.score(X_test, y_test)

pd.Series(scores).unstack()
test_score train_score
bagging 0.986014 1.0
not bagging 0.881119 1.0

ブースティング

訓練データに対しモデルを作成し、学習します。学習後、予測と正解を比較し、誤ったデータに重み付けをして、重み付けしたデータを用いて新たなモデルで学習します。そして誤ったデータに、、、と繰り返し逐次的にモデルを作成していきます。最後はバギング同様に、多数のモデルを集約して予測します。

import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import AdaBoostRegressor

loaded_data = load_boston()
X_train, X_test, y_train, y_test = train_test_split(
    loaded_data.data, loaded_data.target, random_state=0)

models = {
    'tree': DecisionTreeRegressor(random_state=0),
    'AdaBoost': AdaBoostRegressor(DecisionTreeRegressor(random_state=0), n_estimators=100, random_state=0) 
}

scores = {}
for model_name, model in models.items():
    model.fit(X_train, y_train)
    scores[(model_name, 'train_score')] = model.score(X_train, y_train)
    scores[(model_name, 'test_score')] = model.score(X_test, y_test)

pd.Series(scores).unstack()
test_score train_score
AdaBoost 0.741108 0.99971
tree 0.605167 1.00000

バギング&ブースティング

バギングとブースティングの代表的なモデルとしてランダムフォレストと勾配ブースティングが存在します。これらと、上記の決定木のバギング&ブースティングを比較してみます。モデルのチューンをしていないので、下記がモデルの優劣を表すわけではありませんが、大体の目安になります。

# バギング&ブースト
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import AdaBoostRegressor
from sklearn.ensemble import BaggingRegressor
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor

loaded_data = load_boston()
X_train, X_test, y_train, y_test = train_test_split(
    loaded_data.data, loaded_data.target, random_state=0)

models = {
    'tree': DecisionTreeRegressor(random_state=0),
    'AdaBoost': AdaBoostRegressor(DecisionTreeRegressor(random_state=0), random_state=0),
    'Bagging': BaggingRegressor(DecisionTreeRegressor(random_state=0), n_estimators=100, random_state=0),
    'Bagging & AdaBoost': AdaBoostRegressor(BaggingRegressor(DecisionTreeRegressor(random_state=0),
                                                   n_estimators=100,
                                                   random_state=0
                                                  ),
                                  random_state=0
                                 ),
    'RandomForest': RandomForestRegressor(random_state=0),
    'GradientBoost': GradientBoostingRegressor(random_state=0)
}

scores = {}
for model_name, model in models.items():
    model.fit(X_train, y_train)
    scores[(model_name, 'train_score')] = model.score(X_train, y_train)
    scores[(model_name, 'test_score')] = model.score(X_test, y_test)

pd.Series(scores).unstack()
test_score train_score
AdaBoost 0.740901 0.999597
Bagging 0.786746 0.982702
Bagging & AdaBoost 0.763452 0.994583
GradientBoost 0.816288 0.983166
RandomForest 0.757792 0.972705
tree 0.605167 1.000000

おわりに

scikit-learnでバギングとブースティングを試してみました。お手軽に試せて、精度も良いモデルとして、ランダムフォレストと勾配ブースティングが人気です。とりあえず使ってみるというのであれば、これらのモデルがおすすめです。

20
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
20