理論だけではなくて、実装まで解説されている記事はないかな…。
この記事では、上記のような悩みを解決していきます。
この記事の想定読者
想定している読者は、次のとおりです。
- 機械学習を勉強している人
- Adaboostが分からない人
- Adaboostの概要だけではなく、実装も知りたい人
この記事では「Adaboostの理論と実装」について紹介していきます。
Adaboostって聞いたことがあるけど、イマイチどんな学習手法なのか分からないですよね。
でも本記事を読み終えれば、Adaboostについて分かるだけでなく、Pythonを使った実装も紹介しています。
この記事を書いている僕は、大学時代にディープラーニングを学んで、現在データサイエンティストとして働いています。
参考になる情報を提供できているはずなので、ぜひ最後まで読んでいただけたらと思います(`・ω・´)!
Contents
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の決定木になりますのでご注意を。笑
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
を使ってモデルの予測精度を計算できるようになる感じです。
出力される結果は、以下のようになるかと思います。

F1値で97%の精度が出ました。なかなか正確な予測ができていることが分かりますね。
まとめ : Adaboost以外にも、データサイエンスを勉強しよう
というわけで、Adaboostの理論と実装について紹介してきました。
Adaboostは最近まで最有力候補のアルゴリズムだったので、十分に学習する価値アリです。
なお、今回のAdaboostの理論面は、通称「はじパタ」を参考にしています。
若干難しいですが、データサイエンスをやっている人の中では有名な本なので、持っておいて損ないですね。
他にも、データサイエンスでおすすめの書籍は、以下の記事にてまとめています。

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