MachineLearning

Adaboostとは?Pythonを使ったハンズオンで解説【機械学習】

Adaboost Python
機械学習を勉強中の人
機械学習を勉強中の人
Adaboostってなんだろう…。

理論だけではなくて、実装まで解説されている記事はないかな…。

この記事では、上記のような悩みを解決していきます。

 

この記事の想定読者

想定している読者は、次のとおりです。

  • 機械学習を勉強している人
  • Adaboostが分からない人
  • Adaboostの概要だけではなく、実装も知りたい人

 

この記事では「Adaboostの理論と実装」について紹介していきます。

Adaboostって聞いたことがあるけど、イマイチどんな学習手法なのか分からないですよね。

 

でも本記事を読み終えれば、Adaboostについて分かるだけでなく、Pythonを使った実装も紹介しています。

この記事を書いている僕は、大学時代にディープラーニングを学んで、現在データサイエンティストとして働いています。

参考になる情報を提供できているはずなので、ぜひ最後まで読んでいただけたらと思います(`・ω・´)!

 

Adaboostとは?

 

Adaboost(Adaptive boosting)は、名前の一部にもある通りで、ブースティングを用いた機械学習手法になります。

ブースティングとは、複数の弱学習器を「直列に」学習する方法で、前の学習結果を参考にしながら逐次学習していきます。

前の学習結果を参考にするというのは、それぞれの弱学習器のアウトプットに従って学習データに「重み」を付与することで実現します。

 

識別を誤った学習データであれば重みを大きくするし、正しく識別された学習データであれあば重みを小さくしていきます。

つまり、ただ直列で弱学習気が繋がっているだけではなくて、間違えた学習データを重点的に学習していく感じです。

 

Adaboostのアルゴリズム

 

Adaboostの学習アルゴリズムは、以下のようになります。

①学習データの重み \({w_i}^m\) を \({w_i}^1 = \displaystyle \frac{1}{N}\) に初期化する。(\(i = 1, 2, …, N\), \(m = 1, 2, …, M\))

②\(m = 1, 2, …, M\)について、以下を繰り返す。

⑴識別器\(y_m(x)\)を、以下の重み付き誤差関数 \(E_m\) が最小になるように学習する。

$$E_m = \frac{\displaystyle \sum_{i=1}^{N} {w_i}^m I(y_m(x_i) \neq t_i)}{\displaystyle \sum_{i=1}^{N} {w_i}^m}$$

※\(I(y_m(x_i) \neq t_i)\) : 識別関数の出力が教師データと一致した場合⇒0、一致しなかったとき⇒1

(2)識別器\(y_m(x)\)に対する重み\(\alpha_m\)を計算する。

$$\alpha_m = log(\frac{1-E_m}{E_m})$$

(3)学習データの重み\({w_i}^m\)を以下の式で更新する。

$${w_i}^{m+1} = {w_i}^m e^{\alpha_m I(y_m(x_i) \neq t_i)}$$

③以上を繰り返して、入力\(x\)に対する識別結果\(Y_M(x)\)を出力する。

$$Y_M(x) = sign(\sum_{m=1}^{M} \alpha_m y_m(x))$$

※\(sign(a)\) : 符号関数(\(a > 0⇒+1\)、\(a = 0⇒0\)、\(a < 0⇒-1\))

以上のアルゴリズムで、Adaboostは計算されます。なお、途中で出てきた\(M\)は弱学習器の数で、\(N\)は学習データ数になります。

Adaboostは識別を誤った学習データの重みを大きくすることで、苦手を克服することに挑戦するわけですが、そのロジックが(3)の学習データの重みを更新する式に隠されています。

$${w_i}^{m+1} = {w_i}^m e^{\alpha_m I(y_m(x_i) \neq t_i)}$$

上式を見ると、識別関数の定義より、学習を誤ったときに \(e^{\alpha_m}\) 倍されるようになっています。

 

これにより、誤ったデータだけ重みを大きくして、重点的に学習することを可能にしているんですね。

 

【具体例】Adaboostを、Pythonを使ったハンズオンで解説

 

それでは、Pythonを使ったAdaboostの実装をおこなっていきましょう。

ぶっちゃけ、一生懸命アルゴリズムを紹介したものの、Pythonのライブラリが充実しているので、アルゴリズムは全く登場しないです、、、。笑

 

この記事で使うコード

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 AdaBoostClassifier
from sklearn.metrics import classification_report


cancer = load_breast_cancer()
X = pd.DataFrame(cancer.data, columns=cancer.feature_names)
y = cancer.target
print(X)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

base_model = DecisionTreeClassifier(max_depth=3)
adaboost = AdaBoostClassifier(base_estimator=base_model, n_estimators=50)

adaboost.fit(X_train, y_train)
pred = adaboost.predict(X_test)

result = classification_report(y_test, pred)
print(result)

※①Pythonファイルで書いています。notebookが良い方は、このファイルをimportして使ってください。

※②転記OKです。その場合、この記事のURLを「参考URL」として付けてください。

 

STEP① : 学習データとテストデータの用意をする

 

まずは、機械学習するためのデータを用意していきましょう。

使うデータは、scikit-learnに用意されているガンの診断結果が入ったデータセットです。

`from sklearn.datasets import load_breast_cancer`を使えば、ガンの診断結果を使える感じですね。

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 AdaBoostClassifier
from sklearn.metrics import classification_report


cancer = load_breast_cancer()
X = pd.DataFrame(cancer.data, columns=cancer.feature_names)
y = cancer.target
print(X)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

なお、中身を確認しやすいように、学習データだけはデータフレームにしてあります。

これを使うと、どんな特徴量があるのかも分かるので、print()で出力されるデータフレームを見て「こういった特徴量を使っていくのか〜。」と確認しておきましょう。

 

最後に、学習データとテストデータに分割しています。

STEP② : Adaboostのモデルを構築する

 

データの用意ができたので、Adaboostのモデルを準備していきます。

Adaboostは、弱学習器を直列に繋いだアンサンブル学習になるので、元になるモデルが必要です。

今回は、決定木をベースのモデルにして、Adaboostを使っていきます。

base_model = DecisionTreeClassifier(max_depth=3)
adaboost = AdaBoostClassifier(base_estimator=base_model, n_estimators=50)

決定木の深さは、適当にmax_depth=3にしてあります。直列につながっている弱学習器の数は、デフォルトの50です。

 

なお、ベースになるモデルを指定しなかった場合には、深さ=1の決定木になりますのでご注意を。笑

≫scikit-learn公式

STEP③ : 構築したAdaboostを学習して、予測までおこなう

 

ここまで完了したら、STEP①で作成した学習データとテストデータを使って、構築したAdaboostに学習してもらいます。

adaboost.fit(X_train, y_train)
pred = adaboost.predict(X_test)

result = classification_report(y_test, pred)
print(result)

他のモデルでも同じですが、学習させるときは`モデル名.fit(X_train, y_train)`ですね。

さらに、未知のデータに対して予測をおこないたいので、モデル名.predict(X_test)を使って予測をおこなっていきます。

そうすると最終的に、別で用意しておいたy_testを使ってモデルの予測精度を計算できるようになる感じです。

 

出力される結果は、以下のようになるかと思います。

Adaboost 結果

F1値で97%の精度が出ました。なかなか正確な予測ができていることが分かりますね。

 

まとめ : Adaboost以外にも、データサイエンスを勉強しよう

 

というわけで、Adaboostの理論と実装について紹介してきました。

Adaboostは最近まで最有力候補のアルゴリズムだったので、十分に学習する価値アリです。

 

なお、今回のAdaboostの理論面は、通称「はじパタ」を参考にしています。

若干難しいですが、データサイエンスをやっている人の中では有名な本なので、持っておいて損ないですね。

他にも、データサイエンスでおすすめの書籍は、以下の記事にてまとめています。

データサイエンス 本 おすすめ
【2020年最新】データサイエンスでおすすめの本10冊【現役が紹介】 【2020年最新】データサイエンスでおすすめの本10冊【現役が紹介】 2020年最新版にて、データサイエン...

 

この調子で、さらに学習を進めていきましょう(`・ω・´)!

 

おすすめの記事