LESSON

機械学習ワークフロー

田中VPoE:「機械学習は『モデルを学習させる』だけじゃない。データの準備から評価まで、一連のワークフローがある。特に重要なのがデータの分割だ。ここを間違えると、見かけ上は良い精度が出ているのに、実際にはまったく使えないモデルができてしまう。」

あなた:「データの分割って、そんなに重要なんですか?」

田中VPoE:「カンニングしながらテストを受けたら高得点が出るだろう?でも、それは本当の実力じゃない。機械学習も同じだ。」

機械学習ワークフローの全体像

1. 問題定義 → 2. データ収集 → 3. データ前処理
    → 4. 特徴量エンジニアリング → 5. データ分割
    → 6. モデル学習 → 7. モデル評価 → 8. 改善・再学習

各ステップは反復的に繰り返されます。一度で完璧なモデルができることはほとんどありません。

データ分割の基本

なぜデータを分割するのか

モデルの「本当の実力」を測るためです。学習に使ったデータで評価すると、モデルがそのデータを「暗記」しているだけなのか、本当にパターンを学習しているのかが分かりません。

3つのデータセット

from sklearn.model_selection import train_test_split

# まずテストデータを分離(最終評価用)
X_temp, X_test, y_temp, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 残りを学習データと検証データに分割
X_train, X_val, y_train, y_val = train_test_split(
    X_temp, y_temp, test_size=0.25, random_state=42, stratify=y_temp
)

# 結果: 学習60% / 検証20% / テスト20%
print(f"学習: {len(X_train)}, 検証: {len(X_val)}, テスト: {len(X_test)}")
データセット割合用途
学習データ(Train)60%モデルの学習に使用
検証データ(Validation)20%ハイパーパラメータ調整・モデル選択
テストデータ(Test)20%最終的な性能評価(1回だけ使用)

stratify パラメータの重要性

離反予測のように、クラスの偏りがあるデータでは stratify を指定します。

# 離反率が10%の場合
# stratify=y を指定すると、各分割でも離反率10%が維持される
# 指定しないと、偏った分割になる可能性がある

print(f"全体の離反率: {y.mean():.3f}")
print(f"学習データの離反率: {y_train.mean():.3f}")
print(f"テストデータの離反率: {y_test.mean():.3f}")

過学習(Overfitting)と未学習(Underfitting)

過学習とは

モデルが学習データに過度に適合し、新しいデータに対する予測精度が低下する現象です。

学習データの精度: 99%  → 高すぎる
テストデータの精度: 65% → 大幅に低い
→ 過学習の兆候

未学習とは

モデルが十分にデータのパターンを捉えられていない状態です。

学習データの精度: 60%  → 低い
テストデータの精度: 58% → やはり低い
→ 未学習の兆候

適切な状態

学習データの精度: 85%
テストデータの精度: 82%  → 学習データとの差が小さい
→ 良好な汎化性能

過学習の原因と対策

原因対策
モデルが複雑すぎるシンプルなモデルを使う、正則化
学習データが少ないデータの追加、データ拡張
特徴量が多すぎる特徴量選択、次元削減
学習回数が多すぎるEarly Stopping
# 過学習の検出例
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

train_acc = accuracy_score(y_train, model.predict(X_train))
val_acc = accuracy_score(y_val, model.predict(X_val))

print(f"学習データ精度: {train_acc:.3f}")
print(f"検証データ精度: {val_acc:.3f}")
print(f"差分: {train_acc - val_acc:.3f}")

if train_acc - val_acc > 0.1:
    print("過学習の可能性があります")

学習曲線で過学習を可視化する

from sklearn.model_selection import learning_curve
import matplotlib.pyplot as plt
import numpy as np

train_sizes, train_scores, val_scores = learning_curve(
    model, X_train, y_train,
    train_sizes=np.linspace(0.1, 1.0, 10),
    cv=5, scoring='f1'
)

plt.figure(figsize=(10, 6))
plt.plot(train_sizes, train_scores.mean(axis=1), label='学習データ')
plt.plot(train_sizes, val_scores.mean(axis=1), label='検証データ')
plt.xlabel('学習データサイズ')
plt.ylabel('F1スコア')
plt.title('学習曲線')
plt.legend()
plt.grid(True)
plt.show()

学習曲線の読み方:

  • 2つの曲線が離れている → 過学習
  • 2つの曲線が近いが低い → 未学習
  • 2つの曲線が近くて高い → 良好

まとめ

  • ML ワークフローはデータ準備から評価まで反復的に進む
  • データは学習・検証・テストの3つに分割する
  • テストデータは最終評価にのみ使い、何度も評価に使わない
  • 過学習は学習データへの過度な適合で、汎化性能が低下する現象
  • 学習曲線を使って過学習・未学習を可視化できる

チェックリスト

  • データ分割の3つのデータセットの役割を説明できる
  • stratify の目的を理解した
  • 過学習と未学習の違いを説明できる
  • 学習曲線の読み方を把握した

次のステップへ

次のレッスンでは、モデルの評価指標について詳しく学びます。正解率だけでは不十分な理由と、ビジネス目的に応じた指標の選び方を理解しましょう。


推定読了時間: 30分