勾配ブースティング木(Gradient Boosted Trees)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】勾配ブースティング木は、機械学習の分野で非常に強力な予測モデルの一つです。この記事では、その仕組みとPythonによる具体的な実装方法を、初心者にも分かりやすく解説します。実際にコードを動かしながら、この強力なアルゴリズムを体験してみましょう。
はじめに
勾配ブースティング木(Gradient Boosted Trees、以下GBTと略します)は、機械学習のコンペティションなどで常に上位に食い込む、非常に強力な予測モデル構築手法の一つです。一見難しそうに聞こえるかもしれませんが、その基本的な考え方は「小さな間違いを少しずつ修正していく」という、とても直感的なものです。
この記事では、GBTがどのようにして高い精度を実現するのか、そしてPythonを使って実際にどのように実装するのかを、ステップバイステップで丁寧に解説していきます。理論よりも実践を重視し、コードを動かしながら理解を深めていくことを目指します。
記事の最後に、環境構築なしでスマホからでも即実行可能なGoogle Colabノートブックをご用意しています。 ぜひ、実際に手を動かしてGBTの強力さを体験してみてください。
勾配ブースティング木(GBT)とは?
GBTを理解するために、まずは「決定木」という基本的なモデルから考えてみましょう。決定木は、質問を繰り返すことでデータを分類したり、値を予測したりする、木の形をしたモデルです。例えば、「天気は晴れですか?」「気温は25度以上ですか?」といった質問に答えていくことで、最終的な予測に至ります。
ただ、1本の決定木だけでは、複雑なデータやパターンを捉えきれないことがあります。そこで登場するのが「アンサンブル学習」という考え方です。これは、複数の学習モデル(この場合は決定木)を組み合わせて、より強力な一つのモデルを作り上げる手法です。
GBTは、このアンサンブル学習の一種であり、「ブースティング」というアプローチを取ります。ブースティングの基本的なアイデアは以下の通りです。
- 最初の木を作る: まず、簡単な決定木を1本作ります。この木は、データ全体を大まかに予測しようとしますが、当然ながら完璧ではありません。いくつかの予測は当たり、いくつかは外れるでしょう。
- 間違いに注目する: 次に、1本目の木が予測を間違えたデータに注目します。特に大きく間違えたデータを「重点的に学習すべきデータ」としてマークします。
- 2本目の木を作る: 2本目の決定木は、1本目の木が間違えたデータを正しく予測できるように学習します。つまり、1本目の木の「弱点」を補うように作られます。
- これを繰り返す: この「木を作り、間違いに注目し、間違いを修正する新しい木を作る」というプロセスを、決められた回数だけ繰り返します。
- みんなで協力して予測: 最終的な予測は、これまでに作られた全ての木々の予測を組み合わせて行います。それぞれの木は少しずつ異なる側面からデータを学習しており、それらを統合することで、単独の木よりもはるかに精度の高い予測が可能になるのです。
「勾配」という言葉は、この「間違いを修正する」方向を数学的に効率よく見つけるための手法(勾配降下法)に由来していますが、ここでは「前の木の予測のズレ(専門的には残差や勾配)を次の木が学習する」とイメージしていただければ十分です。
このように、GBTは一つ一つの木はそれほど複雑でなくても(「弱い学習器」と呼ばれます)、それらを順番に、前のモデルの誤りを修正するように学習させていくことで、全体として非常に強力な予測モデルを構築するのです。
なぜ勾配ブースティング木(GBT)が強力なのか?
GBTが多くのデータサイエンティストや機械学習エンジニアに支持されるのには、いくつかの明確な理由があります。
-
高い予測精度: GBTは、分類問題(例:スパムメールか否か、顧客が購入するか否か)でも回帰問題(例:株価の予測、不動産価格の予測)でも、非常に高い予測精度を出すことが知られています。これは、上述したように、逐次的に誤りを修正していく学習プロセスにより、データ内の複雑なパターンを効果的に捉えることができるためです。
-
柔軟性: GBTは、様々な種類のデータ(数値データ、カテゴリデータなど)に対応できます。また、目的関数(何を最適化するか)を柔軟に設定できるため、特定の課題に合わせたカスタマイズが比較的容易です。
-
過学習への耐性: 機械学習モデルの大きな課題の一つに「過学習」があります。これは、訓練データに対しては非常に高い精度を出すものの、未知の新しいデータに対してはうまく予測できない状態を指します。GBTは、学習率(learning rate)や木の数(n_estimators)、木の深さ(max_depth)といったパラメータを調整することで、この過学習を抑制しやすいという特徴があります。例えば、学習率を小さく設定すると、一つ一つの木がモデル全体に与える影響が小さくなり、より慎重に学習を進めることができます。
-
特徴量の重要度がわかる: モデルが予測を行う際に、どの特徴量(データの項目)が重要だったのかを評価する機能が多くのGBTライブラリに備わっています。これにより、単に予測するだけでなく、なぜそのような予測になったのか、どの情報が予測に大きく貢献しているのか、といった洞察を得ることができます。これは、ビジネス上の意思決定などにも役立つ重要な情報となります。
これらの理由から、GBTは学術的なコンペティションだけでなく、金融、医療、マーケティングなど、実世界の多様な分野で活用されています。
Pythonで勾配ブースティング木を実装してみよう
それでは、実際にPythonを使ってGBTを実装してみましょう。ここでは、非常にポピュラーな機械学習ライブラリであるscikit-learn
を使用します。scikit-learn
には、GBTの実装であるGradientBoostingClassifier
(分類用)とGradientBoostingRegressor
(回帰用)が含まれています。
今回は、アヤメの花の種類を分類する有名なデータセットを使って、GradientBoostingClassifier
を試してみましょう。
1. 必要なライブラリの準備
まず、必要なライブラリをインポートします。
# データセットの読み込みや基本的な操作に使うライブラリ
import numpy as np
import pandas as pd
# scikit-learnから必要なモジュールをインポート
from sklearn.datasets import load_iris # アヤメのデータセット
from sklearn.model_selection import train_test_split # データを訓練用とテスト用に分割する
from sklearn.ensemble import GradientBoostingClassifier # GBTの分類器
from sklearn.metrics import accuracy_score # 精度評価用
2. データの準備
次に、アヤメのデータセットを読み込み、訓練データとテストデータに分割します。 アヤメのデータセットには、がくの長さ(sepal length)、がくの幅(sepal width)、花びらの長さ(petal length)、花びらの幅(petal width)という4つの特徴量と、アヤメの種類(setosa, versicolor, virginicaの3種類)の正解ラベルが含まれています。
# アヤメのデータセットを読み込む
iris = load_iris()
X = iris.data # 特徴量 (がくの長さ、幅、花びらの長さ、幅)
y = iris.target # 正解ラベル (アヤメの種類)
# 特徴量の名前とターゲットの名前も確認しておきましょう
print("特徴量の名前:", iris.feature_names)
print("ターゲットの名前:", iris.target_names)
print("データXの形状:", X.shape) # (サンプル数, 特徴量数)
print("データyの形状:", y.shape) # (サンプル数,)
# データを訓練用とテスト用に分割する
# test_size=0.3 は、全体の30%をテストデータとして使用するという意味
# random_stateは、毎回同じように分割するための乱数シード(再現性のため)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print("訓練データXの形状:", X_train.shape)
print("テストデータXの形状:", X_test.shape)
print("訓練データyの形状:", y_train.shape)
print("テストデータyの形状:", y_test.shape)
3. モデルの学習
いよいよGBTモデルを学習させます。GradientBoostingClassifier
のインスタンスを作成し、訓練データを使って学習(fit
メソッドを実行)します。
GradientBoostingClassifier
にはいくつかの重要なパラメータがありますが、ここでは代表的なものをいくつか設定してみます。
n_estimators
: 作成する決定木の数。デフォルトは100。多いほど複雑なモデルになりますが、計算時間も増え、過学習のリスクも高まります。learning_rate
: 学習率。各木の寄与度を調整するパラメータ。デフォルトは0.1。小さいほど、一つ一つの木の影響が小さくなり、より多くの木が必要になりますが、頑健なモデルになりやすいです。max_depth
: 各決定木の最大の深さ。デフォルトは3。木が深くなると、より複雑なパターンを捉えられますが、過学習しやすくなります。
# GBTモデルのインスタンスを作成
# ここでは代表的なパラメータをいくつか設定してみます
gbt_model = GradientBoostingClassifier(
n_estimators=100, # 木の数
learning_rate=0.1, # 学習率
max_depth=3, # 各木の最大深さ
random_state=42 # 結果の再現性のための乱数シード
)
# 訓練データを使ってモデルを学習させる
print("モデルの学習を開始します...")
gbt_model.fit(X_train, y_train)
print("モデルの学習が完了しました。")
4. 予測と評価
学習が完了したモデルを使って、テストデータに対する予測を行い、その精度を評価します。
# テストデータを使って予測を行う
y_pred = gbt_model.predict(X_test)
# 予測結果の一部を表示してみる
print("実際の種類 (最初の10件):", y_test[:10])
print("予測された種類 (最初の10件):", y_pred[:10])
# 精度(正解率)を計算する
accuracy = accuracy_score(y_test, y_pred)
print(f"モデルの正解率: {accuracy:.4f}") # 小数点以下4桁まで表示
このコードを実行すると、テストデータに対するモデルの正解率が表示されます。アヤメのデータセットは比較的簡単な問題なので、GBTを使うと非常に高い精度(多くの場合100%またはそれに近い値)が得られるはずです。
もし正解率が期待通りでなかったり、他のデータセットで試す場合は、次に説明するパラメータ調整が重要になってきます。
パラメータ調整のヒント(より実践的な使い方)
GBTモデルの性能を最大限に引き出すためには、ハイパーパラメータの調整が非常に重要です。GradientBoostingClassifier
には多くのパラメータがありますが、特に影響が大きいものをいくつか紹介します。
-
n_estimators
(木の数):- 意味: アンサンブルに含める決定木の総数です。
- 影響: 一般的に、この値を大きくするとモデルの性能は向上する傾向がありますが、ある点を超えると過学習のリスクが高まり、計算時間も増加します。
- 調整のヒント:
learning_rate
とのバランスが重要です。learning_rate
が小さい場合は、n_estimators
を大きくする必要があります。まずは大きめの値で試し、学習曲線(訓練データと検証データのスコアの推移)を見ながら調整します。
-
learning_rate
(学習率):- 意味: 各木がモデルの予測にどれだけ貢献するかを制御する縮小係数です。0から1の間の値をとり、小さいほど各木の貢献は小さくなります。
- 影響: 小さい学習率(例: 0.01, 0.05, 0.1)は、より多くの木(
n_estimators
)を必要としますが、モデルの頑健性を高め、過学習を抑制する効果があります。大きすぎると学習が不安定になることがあります。 - 調整のヒント: 一般的には0.1から始めて、必要に応じて小さくしていきます。
n_estimators
とのトレードオフを考慮して調整します。
-
max_depth
(各木の最大の深さ):- 意味: 個々の決定木の最大の深さを制限します。
- 影響: 木が深いほど、より複雑な特徴量の相互作用を捉えることができますが、過学習しやすくなります。浅い木(例: 3〜5程度)は、個々の木が捉えるパターンを単純にし、モデル全体の汎化性能を高めるのに役立つことが多いです。
- 調整のヒント: データセットの複雑さや特徴量の数によりますが、通常は3から8程度の範囲で試されることが多いです。
-
subsample
(サブサンプリング率):- 意味: 各木を学習させる際に使用する訓練サンプルの割合です。例えば0.8なら、ランダムに選ばれた80%のデータで木を学習します。
- 影響: 1.0未満の値を設定すると、バギングのようにランダム性を取り入れ、過学習を抑制する効果があります。計算時間の削減にも繋がります。
- 調整のヒント: 一般的には0.5から1.0の間で設定されます。0.8あたりが良い結果をもたらすことが多いとされています。
-
min_samples_split
(ノード分割のための最小サンプル数):- 意味: 木のノードを分割するために必要な最小のサンプル数。
- 影響: 大きくすると、より一般的な分割となり、過学習を抑制します。
-
min_samples_leaf
(葉ノードの最小サンプル数):- 意味: 葉ノード(木の末端)に存在しなければならない最小のサンプル数。
- 影響: これも過学習を抑制する効果があります。特に不均衡なデータセットで役立つことがあります。
これらのパラメータは互いに影響し合うため、一つだけを最適化するのではなく、複数のパラメータを組み合わせて調整することが一般的です。GridSearchCV
やRandomizedSearchCV
といったscikit-learn
のツールを使うと、効率的に最適なパラメータの組み合わせを見つけることができます。
例えば、GridSearchCV
を使ったパラメータ探索の簡単な例は以下のようになります。
from sklearn.model_selection import GridSearchCV
# 探索するパラメータの範囲を設定
param_grid = {
'n_estimators': [50, 100, 150],
'learning_rate': [0.05, 0.1, 0.2],
'max_depth': [3, 4, 5]
}
# グリッドサーチのインスタンスを作成
# cv=5 は5分割交差検証を行うという意味
grid_search = GridSearchCV(
estimator=GradientBoostingClassifier(random_state=42),
param_grid=param_grid,
cv=5, # クロスバリデーションの分割数
scoring='accuracy', # 評価指標
n_jobs=-1 # 利用可能なCPUコアを全て使用
)
# グリッドサーチを実行(最適なパラメータを探す)
print("グリッドサーチによるパラメータ探索を開始します...")
grid_search.fit(X_train, y_train)
print("グリッドサーチが完了しました。")
# 最適なパラメータとスコアを表示
print("最適なパラメータ:", grid_search.best_params_)
print("最適なスコア (交差検証):", grid_search.best_score_)
# 最適なパラメータで学習したモデルを取得
best_gbt_model = grid_search.best_estimator_
# テストデータで最終評価
y_pred_best = best_gbt_model.predict(X_test)
accuracy_best = accuracy_score(y_test, y_pred_best)
print(f"最適なモデルのテストデータでの正解率: {accuracy_best:.4f}")
このグリッドサーチは計算に時間がかかる場合がありますが、より高性能なモデルを得るためには重要なステップです。
まとめ
今回は、強力な機械学習アルゴリズムである勾配ブースティング木(GBT)について、その基本的な考え方からPython (scikit-learn
) を用いた具体的な実装方法、さらには性能向上のためのパラメータ調整のヒントまでを解説しました。
GBTは、個々の単純な決定木を逐次的に改良していくことで、複雑なデータパターンを捉え、高い予測精度を実現します。その強力さから、様々な分野で応用されています。
この記事を通じて、GBTの魅力と実践的な使い方の一端を感じていただけたなら幸いです。ぜひ、お手持ちのデータや興味のある問題に対して、GBTを試してみてください。そして、様々なパラメータを調整しながら、モデルの性能がどのように変化するかを観察するのも、理解を深める良い方法です。
ゲームで学ぶ探索アルゴリズム実践入門~木探索とメタヒューリスティクス
探索技術とそれを支えるアルゴリズムにフォーカスを当て、ゲームAIを題材にその重要性と魅力を楽しく学ぶための入門書です。
▶ Amazonで見る環境構築なしで
実行できるファイルはこちら!
このボタンからGoogle Colabを開き、すぐにコードをお試しいただけます。
関連する記事
エクストラツリー(ExtraTrees)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】この記事では、機械学習のアルゴリズムであるエクストラツリー(ExtraTrees)について、その仕組みからPythonによる実装方法までを丁寧に解説します。ランダムフォレストとの違いも理解しながら、実践的なスキルを身につけましょう。
ランダムフォレストを実装してみよう!わかりやすく解説
【スマホからでも実行可能】ランダムフォレストの実装方法をPythonコード付きで丁寧に解説。機械学習のアンサンブル学習を実際に動かして理解を深めましょう。初心者にもわかりやすい実践ガイドです。
決定木(Decision Tree)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】決定木の実装方法をPythonコード付きでステップバイステップ解説。データの準備からモデル構築、可視化、評価、チューニングまで、実践的なスキルが身につきます。機械学習の基本である決定木をマスターしましょう。
粒子群最適化(PSO)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】粒子群最適化(PSO)のアルゴリズムをPythonで実装し、その仕組みを初心者にもわかりやすく解説します。最適化問題や機械学習に興味がある方におすすめです。パラメータ設定のコツや応用例も紹介し、実践的な理解を深めます。
サポートベクターマシン(SVM)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】サポートベクターマシン(SVM)の実装方法を初心者にもわかりやすく解説。Pythonコード付きで、実際に手を動かしながらSVMの仕組みと使い方を学べます。機械学習の基礎を固めたい方、SVMを実践で使ってみたい方におすすめです。