回帰モデル評価
機械学習の世界では、モデルを構築することは最初の一歩に過ぎません。ちょうどケーキを焼いたら、味見をしないと成功かどうかわからないのと同じです。回帰モデル(住宅価格、気温、売上高などの連続値を予測するためのモデル)にとって、モデル評価は、私たちの味見のステップです。モデルの予測がどれだけ正確か、どこがうまくできているか、どこに改善の余地があるかを教えてくれます。
この記事では、回帰モデルの評価方法を体系的に学びます。核となる概念から具体的な指標、コード実践までを網羅し、評価レポートを理解できるだけでなく、実際に自分の手でモデルに「採点」を付けられるようになります。
回帰モデルと評価の核心概念
指標の詳細に入る前に、いくつかの基礎概念を理解する必要があります。これらはすべての評価手法の基盤です。
回帰問題とは?
回帰問題は教師あり学習の一種であり、その目標は入力特徴量に基づいて連続的な数値を予測することです。。
- 例:住宅の面積、築年数、立地条件(特徴量)からその販売価格(連続的な数値)を予測します。
なぜ評価が必要か?
- モデル選択:さまざまなアルゴリズム(線形回帰、決定木回帰など)のどれが自分のデータ上でより良い性能を発揮するかを比較します。
- パラメータ調整:モデルのパラメータ(正則化の強さなど)を調整する際、調整が有効かどうかを判断する客観的な基準が必要です。
- 性能の確認:モデルが未知のデータに対しても信頼できる予測能力を持つことを確認します。「机上の空論」を避けるためです。
重要な用語:誤差
すべての評価指標は「誤差」を中心に展開します。誤差とは、モデルの予測値(ŷ)と実際の値(y)の差です。
- 単一の点の誤差:
误差 = y - ŷ - 評価の本質は、これらの誤差をさまざまな方法で集計・分析することです。。
核心的な評価指標の詳細
最も一般的で重要な評価指標をいくつか紹介し、簡単な例を一貫して使います。
5軒の住宅価格を予測したと仮定しましょう:
| 実際の価格(y) | 予測価格(ŷ) | 誤差(y - ŷ) |
|---|---|---|
| 200 | 210 | -10 |
| 150 | 145 | 5 |
| 300 | 310 | -10 |
| 400 | 380 | 20 |
| 250 | 255 | -5 |
1. 平均絶対誤差(MAE)
わかりやすい説明:すべての予測「誤差」の絶対値を足し合わせて、平均を取ります。これは「平均的に見て、予測値が実際の値からおおよそどのくらいずれているか」を直接反映します。
計算式:
MAE = (1/n) * Σ|y_i - ŷ_i|ただし、nはサンプル数、Σは総和記号です。
計算例:
MAE = (|-10| + |5| + |-10| + |20| + |-5|) / 5 = (10+5+10+20+5)/5 = 50/5 = 10
解釈:平均的に、私たちの住宅価格予測は実際の価格から10万元ずれています。。
特徴:
- 利点:直感的でわかりやすく、極端な誤差値(外れ値)の影響を過度に受けません。
- 欠点:絶対値関数は数学的に至る所で微分可能とは限らず、一部の最適化シナリオでは不便です。
2. 平均二乗誤差(MSE)
わかりやすい説明:各誤差をまず「二乗」して(マイナス符号を消し、誤差を拡大して)、その平均を取ります。これは大きな誤差に非常に敏感です。。
計算式:
MSE = (1/n) * Σ(y_i - ŷ_i)^2
計算例:
MSE = [(-10)^2 + (5)^2 + (-10)^2 + (20)^2 + (-5)^2] / 5 = (100+25+100+400+25)/5 = 650/5 = 130
解釈:誤差の二乗の平均は130です。この数値自体には直接の単位の意味はありません(万元^2です)が、モデルを比較する際には非常に有効です。
特徴:
- 利点:数学的な性質に優れており(至る所で微分可能)、多くのモデル(線形回帰など)が学習時に最小化する目的関数です。
- 欠点:次元が元のデータと異なり、数値の大きさを解釈しにくく、外れ値に敏感です。
3. 二乗平均平方根誤差(RMSE)
わかりやすい説明:MSEの平方根です。MSEを「元の形に戻す」ことで、実際の値や予測値と同じ次元に戻します。
計算式:
RMSE = sqrt(MSE)
計算例:
RMSE = sqrt(130) ≈ 11.4
解釈:平均的に見ると、私たちの予測は実際の値からおよそ11.4万元ずれています。この解釈はMAE(10万元)と似ていますが、RMSEは二乗してから平方根を取るため、大きな誤差に高い重みを与え、通常はMAEより大きくなります。
特徴:
- 利点:元のデータと同じ次元を持ち、MSEよりも解釈性が高いです。大きな誤差へのペナルティがより重く、大きな誤差を重視する場面(金融リスク予測など)でよく使われます。
- 欠点:同様に外れ値に敏感です。
4. R²スコア(決定係数)
わかりやすい説明:私のモデルは、「当てずっぽう」(平均値で予測すること)よりどれだけ優れているのか?これは比率の値であり、モデルがデータの変動を説明する能力を示します。
計算式:
R² = 1 - (Σ(y_i - ŷ_i)^2 / Σ(y_i - y_mean)^2)ただし、y_meanは実際の値の平均値です。
「当てずっぽう」モデル:どの家に対しても、住宅価格の平均値を予測します。y_mean)。
- 計算すると、
y_mean = (200+150+300+400+250)/5 = 260 - 「当てずっぽう」モデルの誤差平方和:
Σ(y_i - 260)^2 = 1600+12100+1600+19600+100 = 35000
計算例:
R² = 1 - (650 / 35000) = 1 - 0.01857 ≈ 0.9814
解釈:私たちのモデルは目的変数(住宅価格)の98.14%変動を説明できます。これはモデルが非常によく適合していることを示します。
特徴:
- 範囲:理論上、R²の範囲は
(-∞, 1]。R² = 1:完全な予測。R² = 0:モデルは平均値で直接予測するのと同じ効果。R² < 0:モデルは平均値で直接予測するよりも劣る(モデルがデータにまったく適していないことを示す)。
- 利点:無次元で、異なるデータセット上のモデル性能を比較しやすいです。
- 欠点:モデルの特徴量が増えると、追加した特徴量が役に立たなくてもR²は自然に大きくなり、過学習を引き起こす可能性があります。
指標の比較と選び方
より明確に理解するために、表を使ってまとめましょう:
| 指標 | 計算式(簡略) | 次元 | 外れ値への感度 | 特徴と適用シーン |
|---|---|---|---|---|
| MAE | 平均絶対誤差 | yと同じ | 影響を受けにくい | 解釈が最も直感的。「平均でどれだけずれるか」に注目し、すべての回帰シナリオに適用できます。特に外れ値が多いデータに適しています。 |
| MSE | 平均二乗誤差 | yの二乗 | 非常に敏感 | 数学的性質が良い。モデル学習の一般的な損失関数です。数値自体は解釈しにくいです。 |
| RMSE | MSEの平方根 | yと同じ | 非常に敏感 | 最も一般的。MSEの数学的な利点と解釈可能性を兼ね備えています。大きな誤差へのペナルティが重く、金融・予測などの分野で人気があります。 |
| R² | 1 - (モデル誤差/ベースライン誤差) | 無次元 | 敏感 | 相対性能指標。単純なベースラインに対するモデルの改善度を比較するために使います。データセット間の比較が容易です。 |
選択の推奨事項:
- まずRMSEとR²を報告することを推奨します:RMSEは誤差の実際の大きさを示し、R²はモデルの相対的な性能を示します。これが最も一般的な組み合わせです。
- データに外れ値が多い場合は、MAEを重視します。
- モデルの学習・最適化段階では、損失関数としてMSEを使用します。
- 指標を一つだけ見て判断してはいけません!複数の指標を組み合わせて初めて、モデルを総合的に評価できます。
コード実践:Scikit-learn を使った評価
それでは、Pythonと機械学習ライブラリのScikit-learnを使って実際にやってみましょう。
環境準備
必要なライブラリがインストールされていることを確認してください:
例
完全なサンプルコード
例
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
# 1. シミュレーションデータの作成
np.random.seed(42) # 毎回同じ実行結果になるようにする
X = 2 * np.random.rand(100, 1) # 100個のサンプル、1つの特徴量、範囲[0,2)
y = 4 + 3 * X + np.random.randn(100, 1) # 真の関係:y = 4 + 3x + ノイズ
# 2. トレーニングセットとテストセットに分割(80%トレーニング、20%テスト)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 3. 単純な線形回帰モデルをトレーニング
model = LinearRegression()
model.fit(X_train, y_train)
# 4. テストセットで予測を実行
y_pred = model.predict(X_test)
# 5. すべての評価指標を計算
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse) # または mean_squared_error(y_test, y_pred, squared=False) を使用
r2 = r2_score(y_test, y_pred)
# 6. 評価結果を出力
print("=== 回帰モデル評価レポート ===")
print(f"平均絶対誤差 (MAE): {mae:.4f}")
print(f"平均二乗誤差 (MSE): {mse:.4f}")
print(f"二乗平均平方根誤差 (RMSE): {rmse:.4f}")
print(f"決定係数 (R² Score): {r2:.4f}")
print("\nモデルの係数:")
print(f" 切片 (Intercept): {model.intercept_)
print(f" 傾き (Coefficient for X): {model.coef_)
# 7. 結果を可視化
plt.figure(figsize=(10, 5))
# サブプロット1:実測値 vs 予測値の散布図
plt.subplot(1, 2, 1)
plt.scatter(y_test, y_pred, alpha=0.7, edgecolors='k')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2, label='完全予測線')
plt.xlabel('実測値 (y_test)')
plt.ylabel('予測値 (y_pred)')
plt.title('実測値 vs 予測値')
plt.legend()
plt.grid(True, linestyle='--', alpha=0.7)
# サブプロット2:誤差分布のヒストグラム
plt.subplot(1, 2, 2)
errors = y_test.flatten() - y_pred.flatten()
plt.hist(errors, bins=15, edgecolor='black', alpha=0.7)
plt.axvline(x=0, color='r', linestyle='--', label='ゼロ誤差線')
plt.xlabel('予測誤差')
plt.ylabel('度数')
plt.title('予測誤差の分布')
plt.legend()
plt.grid(True, linestyle='--', alpha=0.7, axis='y')
plt.tight_layout()
plt.show()
コードの行ごとの解説
- データの作成:私たちはシミュレーションしました
y = 4 + 3x + 噪声のデータです。これは典型的な線形関係にランダムなノイズを加えたものです。 - データセットの分割:
train_test_splitデータをランダムに2つに分割します。トレーニングセット (X_train,y_train) でモデルを学習し、未見のテストセット (X_test,y_test) でその汎化能力を評価します。これは評価の鍵となるステップです! - モデルのトレーニング:作成し、
LinearRegressionオブジェクトを生成して呼び出し、.fit()メソッドでトレーニングします。 - 予測の実行:呼び出して、
.predict()メソッドでテストセットの特徴量にX_test予測値を生成しますy_pred。 - 指標の計算:Scikit-learn の
metricsモジュール内の関数を使用して、MAE、MSE、R² を簡単に計算します。RMSE は MSE の平方根を取ることで得られます。 - 結果の出力:すべての指標とモデルが学習したパラメータをフォーマットして出力します。
- 可視化:
- 左の図:理想的には、散布点は赤い破線(完全予測線)の周りに密接に分布するはずです。
- 右の図:誤差分布のヒストグラムはおおよそ0を中心とした正規分布になるはずで、これは通常良い兆候です。
実践演習とまとめ
手を動かす練習
- コードの実行:上記のコードを自分の Python 環境にコピーして実行し、出力結果と図を確認してください。
- データの変更:増やしてみてください。
np.random.randn()内のノイズ規模を変えて再実行します。すべての評価指標がどのように変化するか観察しましょう。グラフはどのように異なりますか? - モデルの変更:使用してみてください。
from sklearn.tree import DecisionTreeRegressorで線形回帰モデルを置き換えます。2つのモデルの評価指標を比較してください。 - 計算演習:以下の3つのサンプルのMAE、MSE、RMSE、R²を手動で計算してください。
- 実測値 y: [10, 20, 30]
- 予測値 ŷ: [12, 18, 28]