勾配ブースティング決定木の原理とPythonによる実装

一、概要

勾配ブースティング決定木(Gradient Boosting Decision Tree、GBDT)はアンサンブル学習におけるブースティング手法の一種です。このアルゴリズムは、CART(分類回帰木)のような決定木を基本学習器として使用し、反復的なプロセスを通じて、回帰タスクでは残差を、分類タスクでは負勾配を繰り返し適合させていきます。これにより、一連の決定木を段階的に構築し、最終的にこれらの木の予測結果を累加することで最終的な予測値を得ます。

二、アルゴリズムの原理

1. 勾配降下法の思想

勾配降下法は関数の最小値を探すための一般的な最適化アルゴリズムです。GBDTにおいて、この思想は極めて重要な役割を果たします。損失関数 L(y, ŷ) を考えると、ここで y は真値、ŷ は予測値です。勾配降下法の目的は、モデルのパラメータを調整し続けることで損失関数の値を最小化することです。具体的には、各反復において損失関数のパラメータに関する負勾配の方向に沿ってパラメータを更新し、最適解に近づいていきます。GBDTでは、パラメータを明示的に更新するのではなく(代わりに複数の決定木を構築して目標を適合させる)、損失関数の負勾配を適合させる目標とすることで、本質的に勾配降下法の思想を利用しています。

2. 決定木の構築

GBDTは決定木を基本学習器として使用します。決定木は木構造に基づく予測モデルで、データ特徴の継続的な分割を通じてデータを異なるサブセットに分割し、各サブセットが木の一つのノードに対応します。各ノードでは、回帰タスクでは二乗誤差の最小化、分類タスクではジニ指数の最小化などの基準によって最適な特徴量と分割点を選択し、分割後のサブセットが目的変数に対してより「純粋」またはより良い区別度を持つようにします。特徴分割を再帰的に行い、最大木の深さに達する、ノードのサンプル数が閾値以下になるなどの停止条件を満たすまで続けることで、完全な決定木を構築します。

3. 反復的な適合プロセス

(1) モデルの初期化

まず、単純なモデルとして通常は定数モデルを初期化します。これを f₀(X) と表し、その予測値は全サンプルの真値の平均(回帰タスク)または多数派クラス(分類タスク)で表され、ŷ₀ と記述されます。この時点では、モデルの予測結果と真値の間に誤差が存在します。

(2) 残差または負勾配の計算

回帰タスクでは、各サンプルの残差、つまり真値 yᵢ と現在のモデルの予測値 ŷᵢ,ₜ₋₁ の差値 rᵢ,ₜ = yᵢ - ŷᵢ,ₜ₋₁ を計算します。ここで t は反復回数を表します。分類タスクでは、損失関数の現在のモデルの予測値に関する負勾配 gᵢ,ₜ = -∂L(yᵢ, ŷᵢ,ₜ₋₁)/∂ŷᵢ,ₜ₋₁ を計算します。

(3) 決定木の適合

計算された残差(回帰タスク)または負勾配(分類タスク)を新しい目標値として、新しい決定木 fₜ(X) を学習させます。この木は現在のモデルの誤差を適合させることで、現在のモデルの不足を補うことを目的とします。

(4) モデルの更新

新しく学習させた決定木に基づき、現在のモデルを更新します。更新式は ŷᵢ,ₜ = ŷᵢ,ₜ₋₁ + α·fₜ(xᵢ) で表されます。ここで α は学習率(ステップサイズとも呼ばれ)、各木がモデル更新に対して寄与する程度を制御します。学習率が小さいとモデル学習はより安定しますが、より多くの反復回数が必要になります。学習率が大きいとモデルの収束が速すぎる場合があり、収束しない可能性もあります。

(5) 反復の繰り返し

ステップ (2)–(4) を繰り返し、新しい決定木を学習させモデルを更新し続け、設定された反復回数に達するか、損失関数が十分に収束するか、その他の停止条件を満たすまで続けます。最終的に、GBDTモデルは複数の決定木から構成され、その予測結果はすべての決定木の予測結果の累加となります。

アルゴリズムプロセスの図示

GBDTアルゴリズムは勾配降下法の思想と決定木を組み合わせ、残差または負勾配を反復的に適合させることで、強力なアンサンブルモデルを段階的に構築します。この手法は複雑なデータや非線形な関係を扱う際に優れた性能を発揮し、データマイニングや機械学習の分野で広く応用されています。しかし、GBDTには学習時間が長い、外れ値に対して比較的敏感であるなどの欠点も存在し、実際の応用では状況に応じて最適化や調整が必要です。

三、Pythonによる実装

(環境:Python 3.11、scikit-learn 1.5.1)

分類タスクの場合

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn import metrics

# サンプルデータの生成
sample_data, labels = make_classification(n_samples=1000, n_features=50, n_informative=10, n_redundant=5, random_state=1)

# 訓練セットとテストセットへの分割
train_features, test_features, train_labels, test_labels = train_test_split(sample_data, labels, test_size=0.2, random_state=1)

# GBDT分類モデルの作成
classifier = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0, max_depth=1, random_state=1)

# モデルの学習
classifier.fit(train_features, train_labels)

# 予測の実行
predictions = classifier.predict(test_features)

# 正確率の計算
accuracy = metrics.accuracy_score(test_labels, predictions)
print(f'正確率: {accuracy:.2f}')

回帰タスクの場合

from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error

# サンプルデータの生成
features, target = make_regression(n_samples=1000, n_features=10, n_informative=5, noise=0.1, random_state=42)

# 訓練セットとテストセットへの分割
train_features, test_features, train_target, test_target = train_test_split(features, target, test_size=0.2, random_state=42)

# GBDT回帰モデルの作成
regressor = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, random_state=42)

# モデルの学習
regressor.fit(train_features, train_target)

# テストセットでの予測
predicted_values = regressor.predict(test_features)

# 平均二乗誤差の計算
mse = mean_squared_error(test_target, predicted_values)
print(f"平均二乗誤差: {mse:.4f}")

タグ: 勾配ブースティング 決定木 アンサンブル学習 Scikit-learn Python機械学習

5月19日 09:53 投稿