XGBoost機械学習体験
【概要】XGBoostによるIrisデータセットの分類。決定木の数を変更して予測精度の変化を観察。機械学習の弱学習器組み合わせ概念を体験する。


目次
概要
機械学習基礎概念:機械学習では、過学習(モデルが訓練データに過度に適合し、新しいデータで性能が低下する現象)を防ぐため、正則化(モデルの複雑さに対するペナルティ)を導入する。アンサンブル学習(複数の学習器を組み合わせる手法)により、単一モデルより高い予測精度を実現する。
主要技術:XGBoost(Extreme Gradient Boosting)は、勾配ブースティング決定木(複数の弱い決定木を順次組み合わせる手法)の拡張アルゴリズムである。従来手法からの主な改良点は、正則化による過学習抑制、二次近似による高速化、列サンプリングによる精度向上である。
論文:Chen, T., & Guestrin, C. (2016). XGBoost: A scalable tree boosting system. In Proceedings of the 22nd ACM SIGKDD international conference on knowledge discovery and data mining (pp. 785-794).
応用例:金融リスク評価、医療診断支援、マーケティング顧客分析、画像認識の後処理分類器
学習目標:決定木の数を変更することで予測精度の変化を観察し、アンサンブル学習の概念を理解する。Irisデータセットの花弁データを用いた3クラス分類により、分類境界の形成過程を体験する。
Python開発環境,ライブラリ類
ここでは、最低限の事前準備について説明する。機械学習や深層学習を行う場合は、NVIDIA CUDA、Visual Studio、Cursorなどを追加でインストールすると便利である。これらについては別ページ https://www.kkaneko.jp/cc/dev/aiassist.htmlで詳しく解説しているので、必要に応じて参照してください。
Python 3.12 のインストール
インストール済みの場合は実行不要。
管理者権限でコマンドプロンプトを起動(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)し、以下を実行する。管理者権限は、wingetの--scope machineオプションでシステム全体にソフトウェアをインストールするために必要である。
REM Python をシステム領域にインストール
winget install --scope machine --id Python.Python.3.12 -e --silent
REM Python のパス設定
set "PYTHON_PATH=C:\Program Files\Python312"
set "PYTHON_SCRIPTS_PATH=C:\Program Files\Python312\Scripts"
echo "%PATH%" | find /i "%PYTHON_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_PATH%" /M >nul
echo "%PATH%" | find /i "%PYTHON_SCRIPTS_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_SCRIPTS_PATH%" /M >nul
【関連する外部ページ】
Python の公式ページ: https://www.python.org/
AI エディタ Windsurf のインストール
Pythonプログラムの編集・実行には、AI エディタの利用を推奨する。ここでは,Windsurfのインストールを説明する。
管理者権限でコマンドプロンプトを起動(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)し、以下を実行して、Windsurfをシステム全体にインストールする。管理者権限は、wingetの--scope machineオプションでシステム全体にソフトウェアをインストールするために必要となる。
winget install --scope machine Codeium.Windsurf -e --silent
【関連する外部ページ】
Windsurf の公式ページ: https://windsurf.com/
必要なライブラリのインストール
コマンドプロンプトを管理者として実行(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」を選択)し、以下を実行する。
pip install xgboost scikit-learn matplotlib japanize-matplotlib numpy
プログラムコード
# プログラム名: XGBoostによるIrisデータセット分類
# 特徴技術名: XGBoost(eXtreme Gradient Boosting)
# 出典: Chen, T., & Guestrin, C. (2016). XGBoost: A scalable tree boosting system. In Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (pp. 785-794). ACM.
# 特徴機能: 勾配ブースティング決定木による高精度分類。前の木の予測誤差を次の木で修正する逐次学習により、単一の決定木より高い予測精度を実現
# 学習済みモデル: なし(プログラム内でIrisデータセットを用いて学習)
# 方式設計:
# - 関連利用技術: scikit-learn(データセット読み込み、データ分割、評価指標)、matplotlib(結果可視化)、japanize-matplotlib(日本語表示)、numpy(数値計算)
# - 入力と出力: 入力: なし(内蔵データセット使用)、出力: 分類結果の可視化グラフとテキスト
# - 処理手順: 1)Irisデータセット読み込み、2)訓練・テストデータ分割、3)XGBoostモデル学習、4)テストデータで予測、5)精度評価、6)結果可視化
# - 前処理、後処理: 前処理: train_test_splitによるデータ分割(過学習防止)、後処理: 花弁長・幅による2次元可視化(理解しやすさ向上)
# - 追加処理: ブースティング木の概念説明表示(教育効果向上)、図の読み方説明表示(結果解釈支援)
# - 調整を必要とする設定値: n_estimators(ブースティング木の数、デフォルト5、範囲1-100推奨)
# 将来方策: グリッドサーチによる最適n_estimators自動探索機能の実装(交差検証による精度最大化)
# その他の重要事項: max_depth=2で浅い木を使用(過学習防止)、random_seed固定で再現性確保
# 前準備: pip install xgboost scikit-learn matplotlib japanize-matplotlib numpy
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier
import time
# 定数定義
RANDOM_SEED = 42
DEFAULT_N_ESTIMATORS = 5
TEST_SIZE = 0.3
MAX_DEPTH = 2
# 可視化用定数
COLORS = ['red', 'green', 'blue']
TARGET_NAMES = ['setosa', 'versicolor', 'virginica']
# プログラム開始時の概要表示
print('=' * 60)
print('XGBoostによるIrisデータセット分類プログラム')
print('=' * 60)
print('概要: XGBoostを使用してアヤメの品種を分類します')
print('特徴: 勾配ブースティング決定木による高精度な分類')
print('入力: Irisデータセット(プログラム内蔵)')
print('出力: 分類結果の可視化と精度評価')
print('=' * 60)
# 結果記録用リスト
results = []
print('\n【ブースティング木とは】')
print('複数の弱い決定木を順次学習し、前の木の誤りを次の木で修正する手法')
print('・各木は前の木の予測誤差に注目して学習')
print('・最終予測は全ての木の予測を重み付き平均で統合')
print('・単一の木より高精度、過学習しにくい特性')
print('=' * 60)
# パラメータ設定
inp = input(f'\nn_estimators(ブースティング木の数、デフォルト{DEFAULT_N_ESTIMATORS})を入力してください: ')
if inp.strip() and inp.strip().isdigit() and int(inp.strip()) > 0:
n_estimators = int(inp.strip())
else:
n_estimators = DEFAULT_N_ESTIMATORS
# 処理開始
start_time = time.time()
results.append(f'処理開始時刻: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}')
results.append(f'設定パラメータ: n_estimators={n_estimators}')
# データ読み込み
print('\nデータ読み込み中...')
X, y = load_iris(return_X_y=True)
results.append(f'データサイズ: {X.shape[0]}サンプル, {X.shape[1]}特徴量')
time.sleep(1)
# データ分割
print('データ分割中...')
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=TEST_SIZE, random_state=RANDOM_SEED)
results.append(f'訓練データ: {X_train.shape[0]}サンプル')
results.append(f'テストデータ: {X_test.shape[0]}サンプル')
time.sleep(1)
# モデル学習
print('モデル学習中...')
model = XGBClassifier(
n_estimators=n_estimators,
max_depth=MAX_DEPTH,
random_state=RANDOM_SEED
)
model.fit(X_train, y_train)
results.append('モデル学習完了')
time.sleep(1)
# 予測と評価
print('予測実行中...')
preds = model.predict(X_test)
accuracy = accuracy_score(y_test, preds)
results.append(f'予測精度: {accuracy:.4f}')
print(f'予測精度: {accuracy:.4f}')
time.sleep(1)
# 処理時間計算
elapsed = time.time() - start_time
results.append(f'処理時間: {elapsed:.2f}秒')
# 結果出力
print('\n' + '=' * 60)
print('【図の読み方・解釈方法】')
print('全データを花弁長・幅で表示、○が実際のクラス、×が予測結果')
print('○と×が重なる箇所は予測成功、離れている箇所は予測失敗')
print('色は分類を表す:赤=setosa、緑=versicolor、青=virginica')
print('=' * 60)
# 可視化
plt.figure(figsize=(10, 8))
# 実際のデータと予測結果を統合して描画
for i, (color, name) in enumerate(zip(COLORS, TARGET_NAMES)):
# 実際のデータ
plt.scatter(X[y == i, 2], X[y == i, 3], c=color, marker='o',
label=f'{name} (実際)', alpha=0.7, s=60)
# 予測結果
test_mask = preds == i
plt.scatter(X_test[test_mask, 2], X_test[test_mask, 3], c=color, marker='x',
s=100, linewidth=3, alpha=0.9)
plt.xlabel('花弁長(Petal Length)')
plt.ylabel('花弁幅(Petal Width)')
plt.title(f'XGBoostによるアヤメ分類 (木の数={n_estimators}, 精度={accuracy:.4f})')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# 最終結果表示
print(f'\n設定パラメータ: n_estimators={n_estimators}')
print(f'予測精度: {accuracy:.4f}')
print('可視化完了')
# result.txtに保存
with open('result.txt', 'w', encoding='utf-8') as f:
for result in results:
f.write(result + '\n')
print('\nresult.txtに保存しました')
使用方法と評価
- プログラム実行
- パラメータ入力:n_estimators(ブースティング木の数)の入力を求められる。数値を入力するか、Enterキーでデフォルト値(5)を使用する。
- 結果確認:予測精度が数値で表示され、続いてグラフが表示される。
- グラフ解釈:花弁長・花弁幅の2次元プロット上で、○印が実際のクラス、×印が予測結果を示す。
評価手法と解釈:訓練データとテストデータを分離することで、モデルの汎化性能(未知データに対する予測精度)を正しく評価する。XGBoostは複雑なモデルであるが、特徴量重要度により各特徴量の予測への寄与度を把握できる。
ハイパーパラメータの調整:n_estimators(木の数)は多いほど複雑なパターンを学習するが、過学習のリスクも増加する。max_depth(木の深さ)は深いほど詳細な分岐を可能にするが、計算コストと過学習リスクが増加する。learning_rate(学習率)は小さいほど安定した学習を行うが、収束に時間を要する。
実験・探求のアイデア
基本実験
- n_estimators:1、5、10、50、100での精度変化の観察
- max_depth:1、2、3、5での分類境界の変化
- learning_rate:0.1、0.3、1.0での学習速度と精度のトレードオフ
モデル比較とデータ処理
- XGBClassifier、RandomForestClassifier(複数の決定木を並列に学習)、DecisionTreeClassifier(単一決定木)の性能比較
- 特徴量の前処理:標準化や正規化による性能への影響観察
- 特徴量重要度分析:model.feature_importances_による4つの特徴量(萼片長・幅、花弁長・幅)の重要度ランキング可視化
発展的探求
- パラメータ効果検証:n_estimatorsを1から100まで段階的に変更し、精度の飽和点を発見する。
- ハイパーパラメータ最適化:格子探索による交差検証を使用して最適なパラメータ組み合わせを自動探索し、手動調整との違いを比較する。