機械学習は、データからモデルを構築し、未知のデータに対して予測を行うための技術です。しかし、モデルの適合度が不適切であると予測精度が低下します。ここでは、機械学習における過剰適合と過小適合について解説し、その対策を提示します。
過剰適合 (Overfitting) とは
過剰適合とは、モデルが訓練データに過度に適合しすぎて、訓練データに対しては高い予測性能を示すものの、未知のデータ(テストデータ)に対しては予測性能が低くなる現象です。
過剰適合の主な原因
- モデルが複雑すぎる(パラメータが多い、表現力が高いなど)
- 訓練データが少ない
- 訓練データにノイズが多い
過剰適合が発生すると、モデルは訓練データのノイズや個々の事例に過敏に反応し、データに内在する一般的なパターンを捉えられなくなります。
過剰適合の例
| 現象 | 原因 | 対策 |
|---|---|---|
| 訓練データでは高精度、テストデータでは低精度 | モデルが訓練データのノイズまで学習してしまっている | 訓練データを増やす、モデルを単純化する、正則化を行う、交差検証を行う |
| モデルの予測値の分散が大きい | モデルが訓練データのわずかな違いに過剰に反応している | 特徴量の数を減らす、データの次元削減を行う |
| 不要な特徴量までモデルが学習してしまう | モデルの表現力が高すぎる | より多くのデータを収集する, 特徴量選択を行う |
過剰適合を防ぐ方法
- データ量の増加: より多くの訓練データで学習することで、モデルはデータの一般的な特徴を捉えやすくなります。
- モデルの単純化
- 特徴量の数を減らす: 不要な特徴量を削除、または次元削減を行います。
- モデルのパラメータ数を減らす: 線形モデル、決定木など、より単純なモデルを使用します。
- ニューラルネットワークの場合: 層の数やユニット数を減らします。
- 正則化 モデルの複雑さにペナルティを与えることで、過剰適合を抑制します。
- 交差検証: データを訓練データと検証データに分割し、モデルの汎化性能を評価します。
Pythonコード例 (正則化による過剰適合の抑制)
このコードでは、load_diabetesデータセットを使用し、線形回帰、L1正則化(Lasso)、L2正則化(Ridge)の3つのモデルを比較しています。 alpha パラメータで正則化の強さを調整できます。正則化により、MSEが改善する(小さくなる)可能性があり、過剰適合が抑制されます。
# データの準備 (例: scikit-learnのload_diabetesを使用) from sklearn.datasets import load_diabetes from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression, Lasso, Ridge from sklearn.metrics import mean_squared_error diabetes = load_diabetes() X_train, X_test, y_train, y_test = train_test_split( diabetes.data, diabetes.target, test_size=0.2, random_state=42 ) # 通常の線形回帰 (過剰適合しやすい) model_linear = LinearRegression() model_linear.fit(X_train, y_train) pred_linear = model_linear.predict(X_test) mse_linear = mean_squared_error(y_test, pred_linear) print(f"線形回帰のMSE: {mse_linear:.2f}") # L1正則化 (Lasso回帰) model_lasso = Lasso(alpha=0.1) # alphaは正則化の強さを調整 model_lasso.fit(X_train, y_train) pred_lasso = model_lasso.predict(X_test) mse_lasso = mean_squared_error(y_test, pred_lasso) print(f"Lasso回帰のMSE: {mse_lasso:.2f}") # L2正則化 (Ridge回帰) model_ridge = Ridge(alpha=0.1) # alphaは正則化の強さを調整 model_ridge.fit(X_train, y_train) pred_ridge = model_ridge.predict(X_test) mse_ridge = mean_squared_error(y_test, pred_ridge) print(f"Ridge回帰のMSE: {mse_ridge:.2f}")
過小適合 (Underfitting) とは
過小適合とは、モデルが単純すぎて、訓練データのパターンを十分に捉えられていない状態です。訓練データ、テストデータの両方で予測性能が低くなります。
主な原因
- モデルが単純すぎる(パラメータが少ない、表現力が低いなど)
- 特徴量が不足している
- 特徴量の表現が不適切
過小適合の例
| 現象 | 原因 | 対策 |
|---|---|---|
| 訓練データ、テストデータ共に精度が低い | モデルがデータの複雑さを表現できていない | より複雑なモデルを使用する、特徴量を追加する、特徴量の表現を見直す |
| 学習曲線が収束しない | モデルの学習が不十分 | 学習回数を増やす、学習率を調整する |
| データの傾向を捉えられていない | 特徴量が不足している | 特徴量エンジニアリングを行う |
過小適合を防ぐ方法
- モデルの複雑化
- より表現力の高いモデルを使用する: 多項式回帰、サポートベクターマシン、決定木、ニューラルネットワークなど。
- ニューラルネットワークの場合: 層の数やユニット数を増やす。
- 特徴量エンジニアリング
- 既存の特徴量から新しい特徴量を作成する。
- ドメイン知識を活用して、有用な特徴量を見つける。
- ハイパーパラメータの調整: モデルの学習に影響を与えるパラメータ(学習率、バッチサイズなど)を適切に調整する。
- 学習時間を増やす: モデルの学習が十分でない場合は、学習時間を増やします。
Pythonコード例 (モデルの複雑化による対策)
このコードでは、単純な線形回帰ではデータに適合しきれていない(過小適合)状態から、PolynomialFeatures を使って特徴量の次元を増やし、多項式回帰を行うことで、よりデータに適合したモデルを構築し、複雑なモデルにしていきます。
# データの準備 (例: 単純な非線形データ) import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import make_pipeline # データの作成 rng = np.random.RandomState(1) x = 10 * rng.rand(50) y = np.sin(x) + 0.1 * rng.randn(50) x_plot = np.linspace(0, 10, 100) # 線形回帰 (過小適合) model_linear = LinearRegression() model_linear.fit(x[:, np.newaxis], y) y_plot_linear = model_linear.predict(x_plot[:, np.newaxis]) plt.scatter(x, y, label="data") plt.plot(x_plot, y_plot_linear, label="linear regression", color="red") # 多項式回帰 (モデルを複雑化) model_poly = make_pipeline(PolynomialFeatures(degree=7), LinearRegression()) model_poly.fit(x[:, np.newaxis], y) y_plot_poly = model_poly.predict(x_plot[:, np.newaxis]) plt.plot(x_plot, y_plot_poly, label="polynomial regression", color="green") plt.legend() plt.show()
まとめ
過剰適合と過小適合は、機械学習モデルの性能を左右する重要な問題です。適切なモデルの選択、データの前処理、正則化、交差検証などの手法を組み合わせて、これらの問題に対処することが重要です。モデルの評価には、訓練データだけでなく、必ずテストデータ(未知のデータ)を用いて汎化性能を評価することが重要です。
最後にAI・機械学習の学習に利用できるUdemy
のサイトを紹介します。ぜひ活用ください。
[PR]