バイアス(Bias)と分散(Variance)

バイアス(Bias)と分散(Variance)は、機械学習モデルの性能を評価する際に重要な概念であり、トレードオフの関係にある概念として知られています。これらの概念はモデルの予測誤差の原因を理解するために役立ちます。

バイアス(Bias)

バイアスとは、モデルの予測と実際の値との間の平均的な誤差を指します。モデルが過度に単純化されている場合に高くなる傾向があり、訓練データに対してもテストデータに対しても誤差が大きくなります。この状態をアンダーフィッティング(Underfitting)と言います。

分散(Variance)

分散とは、モデルが異なる訓練データセットに対してどれだけ変動するかを示します。モデルが過度に複雑である場合に高くなる傾向があり、訓練データに対しては低い誤差を示す一方、テストデータに対しては高い誤差を示します。この状態をオーバーフィッティング(Overfitting)と言います。

この記事では、シミュレーションとして高バイアス・高分散のサンプルを再現し、アンダーフィッティングとオーバーフィッティングの現象を確認します。

シミュレーション用データの生成

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
X = np.sort(np.random.rand(100, 1) * 10, axis=0)
y = np.sin(X).ravel() + np.random.randn(100) * 0.5

ここでは正弦波に従うが、ランダムなノイズによって多少のばらつきを持つデータを生成しています。

plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='darkorange', label='Noisy data')
plt.xlabel('X')
plt.ylabel('y')
plt.show()

グラフに描画すると下記のようになります。

多項式モデルで次数を変えて学習

多項式モデルで次数を変えて先ほどのデータに対して学習を行ってみます。

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

degrees = [1, 4, 20]
plt.figure(figsize=(15, 5))

for i in range(len(degrees)):
    ax = plt.subplot(1, len(degrees), i + 1)
    plt.setp(ax, xticks=(), yticks=())

    polynomial_features = PolynomialFeatures(degree=degrees[i])
    X_train_poly = polynomial_features.fit_transform(X_train)
    X_test_poly = polynomial_features.transform(X_test)

    model = LinearRegression()
    model.fit(X_train_poly, y_train)
    y_train_pred = model.predict(X_train_poly)
    y_test_pred = model.predict(X_test_poly)

    train_error = mean_squared_error(y_train, y_train_pred)
    test_error = mean_squared_error(y_test, y_test_pred)

    plt.scatter(X, y, s=10, edgecolor='black', c='darkorange', label="data")
    plt.plot(X, model.predict(polynomial_features.fit_transform(X)), label=f"degree {degrees[i]}")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.legend(loc="best")
    plt.title(f"Degree {degrees[i]}\nTrain Error: {train_error:.2f}\nTest Error: {test_error:.2f}")

plt.show()

下記のような結果になります。

  • 次数1 : 次数が低いため、シンプルなモデルとなっています。この状況ではバイアスが高くなります。大きな誤差が生じており、アンダーフィッティングの状態が確認できます。

  • 次数4 : バイアスと分散のバランスが良く、誤差が比較的少ないです。

  • 次数20 :複雑なモデルになっています。データに対して過剰に適合しており、分散が高く、オーバーフィッティングの状態が確認できます。