過学習(オーバーフィッティング)とは?原因と対策を徹底解説

訓練では99%の精度なのに本番では使い物にならない——機械学習で最も多い失敗が過学習です。なぜ起きるのか、どう防ぐのか、代表的な対策を優先度順に整理して解説します。

過学習(オーバーフィッティング)とは?原因と対策を徹底解説

AI初心者

AIを知りたい

機械学習のモデルが「過学習している」とよく聞くのですが、どういう状態のことですか?

AIエンジニア

AIエンジニア

過学習とは、訓練データに対しては高い精度を出すのに、未知のデータには全然当たらないという状態です。モデルがデータの本質的なパターンではなく、ノイズや偶然のパターンまで覚えてしまっているんです。

AI初心者

AIを知りたい

テストで満点なのに実力テストで点が取れない、みたいな感じですか?

AIエンジニア

AIエンジニア

まさにその通りです!過去問を丸暗記して模試では高得点だけど、初見の問題が解けないのと同じ状態です。機械学習ではこの「初見の問題に対応できる力」を「汎化性能」と呼びます。

過学習(オーバーフィッティング)とは、モデルが訓練データのノイズや細部まで学習してしまい、未知のデータに対する予測性能が低下する現象です。

訓練誤差は低いのにテスト誤差が高い状態で発生します。適切なモデルの複雑さの制御と正則化が対策の基本です。反対に、モデルが単純すぎて訓練データすら正しく学習できない状態を「未学習(アンダーフィッティング)」と呼びます。

過学習が起きる原因

AI初心者

AIを知りたい

なぜ過学習が起きてしまうのですか?

AIエンジニア

AIエンジニア

主な原因は3つあります。1つ目はモデルが複雑すぎること。パラメータ数がデータ量に対して多すぎると、ノイズまで覚えてしまいます。2つ目は訓練データが少ないこと。サンプルが少ないと偏ったパターンを学習しやすくなります。3つ目は学習回数が多すぎることです。

AI初心者

AIを知りたい

どうやって過学習が起きていると判断するんですか?

AIエンジニア

AIエンジニア

学習曲線(Learning Curve)を見るのが一番わかりやすいです。エポックが進むにつれて訓練損失は下がり続けるのにバリデーション損失が上がり始めたら、それが過学習の兆候です。訓練精度とテスト精度の差が大きい場合も過学習を疑います。

状態 訓練精度 テスト精度 原因
未学習 低い 低い モデルが単純すぎる
適切な学習 高い 高い バランスが取れている
過学習 非常に高い 低い モデルが複雑すぎる

過学習を防ぐ手法

AI初心者

AIを知りたい

過学習を防ぐにはどうすればいいですか?

AIエンジニア

AIエンジニア

対策は大きく分けて4つのアプローチがあります。データを増やす(データ拡張含む)、モデルを単純化する(層やパラメータを減らす)、正則化を使う(L1/L2正則化、ドロップアウト)、早期停止(Early Stopping)で最適なタイミングで学習を止める方法です。

AI初心者

AIを知りたい

ドロップアウトって何ですか?

AIエンジニア

AIエンジニア

ドロップアウトは学習時にランダムにニューロンを無効化する手法です。例えばドロップアウト率0.5なら、各学習ステップで半分のニューロンがランダムに使われません。これにより特定のニューロンへの依存を防ぎ、汎化性能が向上します。ディープラーニングでは必須のテクニックです。

対策 方法 適用場面
データ拡張 回転・反転・ノイズ追加等 画像分類など
L1正則化(Lasso) 重みの絶対値にペナルティ 特徴選択が必要な場合
L2正則化(Ridge) 重みの二乗にペナルティ 一般的な過学習防止
ドロップアウト ニューロンのランダム無効化 ニューラルネットワーク
Early Stopping 検証誤差が上昇したら停止 反復学習全般
交差検証 複数の分割で評価 モデル選択・評価

バイアスとバリアンスのトレードオフ

AI初心者

AIを知りたい

過学習の話と関連して「バイアス-バリアンストレードオフ」という言葉を見たのですが?

AIエンジニア

AIエンジニア

これは機械学習の根本的な概念です。バイアスはモデルの予測が平均的にどれだけずれているか、バリアンスはデータが変わったときに予測がどれだけブレるかを表します。単純なモデルはバイアスが高くバリアンスが低い、複雑なモデルはその逆です。

AI初心者

AIを知りたい

結局、ちょうどいい複雑さを見つけることが大切なんですね。

AIエンジニア

AIエンジニア

その通りです。バイアスとバリアンスの合計が最小になるスイートスポットを見つけることが、良いモデルを作る本質です。交差検証でテスト精度を確認しながら、正則化の強さやモデルの複雑さを調整していきましょう。

まとめ

過学習は機械学習において最も注意すべき問題の一つです。訓練データへの過剰な適合を防ぐために、正則化、ドロップアウト、早期停止、データ拡張など複数の対策を組み合わせましょう。バイアスとバリアンスのトレードオフを理解し、交差検証で汎化性能を確認しながらモデルを調整することが、信頼性の高い予測を実現する鍵です。

関連記事

過学習の検出とEarlyStoppingの実装

学習曲線(train/validation loss)を描くと過学習が視覚的にわかります。EarlyStoppingコールバックで自動的に学習を止める方法も確認しましょう。

import numpy as np
from tensorflow.keras import layers, models
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.datasets import boston_housing
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

# 回帰用データ(ボストン住宅価格)
(X_train, y_train), (X_test, y_test) = boston_housing.load_data()
mean, std = X_train.mean(axis=0), X_train.std(axis=0)
X_train = (X_train - mean) / std
X_test = (X_test - mean) / std

# わざと過学習しやすいモデル(パラメータ過多)
model = models.Sequential([
    layers.Dense(256, activation="relu", input_shape=(13,)),
    layers.Dense(256, activation="relu"),
    layers.Dense(256, activation="relu"),
    layers.Dense(1),
])
model.compile(optimizer="adam", loss="mse")

# EarlyStopping: val_lossが5エポック改善しなければ停止
early_stop = EarlyStopping(
    monitor="val_loss",
    patience=5,
    restore_best_weights=True,
)

history = model.fit(
    X_train, y_train,
    epochs=200,
    batch_size=32,
    validation_split=0.2,
    callbacks=[early_stop],
    verbose=0,
)

# 学習曲線の可視化
plt.figure(figsize=(8, 4))
plt.plot(history.history["loss"], label="train loss")
plt.plot(history.history["val_loss"], label="val loss")
plt.axvline(len(history.history["loss"]) - 1, color="red",
            linestyle="--", label="EarlyStopping")
plt.xlabel("Epoch")
plt.ylabel("MSE")
plt.legend()
plt.title("Train vs Validation Loss")
plt.savefig("learning_curve.png")
print(f"停止エポック: {len(history.history['loss'])}")
print(f"テスト損失: {model.evaluate(X_test, y_test, verbose=0):.2f}")

train lossが下がり続けるのにval_lossが上がり始めたら過学習のサインです。EarlyStoppingは「いつ学習を止めるか」を自動判断してくれる最も手軽な正則化手法で、patience(我慢するエポック数)を適切に設定するだけで使えます。