K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

MAE・RMSE

入門

03.2.3

MAE・RMSE

最終更新 2020-02-26 読了時間 5 分
まとめ
MAE と RMSE は、回帰モデルの予測 \(\hat{y}_i\) と実測 \(y_i\) のずれをまとめて 1 つの数にする、もっとも基本的な誤差指標です。MAE は誤差の絶対値を平均し、RMSE は誤差を二乗して平均してから平方根で元の単位に戻します。誤差が [1, 1, 2, 1, 5] なら MAE = 2.0、RMSE ≈ 2.53 で、二乗する RMSE は誤差 5 を 25 として数えるため大きな外れを重く評価します。数学的に常に MAE ≤ RMSE ≤ √n·MAE が成り立ち、2 つの差が大きいほど誤差のばらつき(外れ値)が大きいと読めるので、scikit-learn の mean_absolute_error と mean_squared_error(squared=False) で両方を並べて報告するのが基本です。

直感:符号を消す 2 つの方法 #

5 日分の気温予報が実際より −1, +1, +2, −1, +5 ℃ ずれたとします。ずれをそのまま平均すると +1 と −1 が打ち消し合うので、符号を消してから平均したい。消し方が 2 つあります。絶対値を取れば 1, 1, 2, 1, 5 の平均で 2.0 ℃、これが MAE です。二乗すれば 1, 1, 4, 1, 25 の平均 6.4 の平方根で約 2.53 ℃、これが RMSE です。5 ℃ のずれが二乗の中では 25 として効くため、RMSE のほうが大きくなります。大外れを 1 回でも許したくないなら RMSE、平均的なずれを知りたいなら MAE、という使い分けはこの差から来ています。

定義と性質 #

観測値を \(y_i\)、予測値を \(\hat{y}_i\) とすると、2 つの指標は次のように定義されます。

$$ \mathrm{MAE} = \frac{1}{n} \sum_{i=1}^n |y_i - \hat{y}_i|, \qquad \mathrm{RMSE} = \sqrt{\frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2} $$

MAE は誤差の絶対値の平均で、誤差 10 の寄与は誤差 1 の 10 倍と線形に増えます。MAE を最小化する予測は条件付き中央値に対応し、外れ値に対して頑健です。RMSE は誤差を二乗して平均し平方根を取るので、誤差 10 の寄与は二乗和の中で誤差 1 の 100 倍になり、外れ値が多いと急に増えます。単位はどちらも元データと同じ ℃ や円で、RMSE は二乗の分を平方根で戻していますが、「大きな外れを嫌う」性質は残ります。


何が起きているか(ステップで見る) #

コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。

見るポイント:RMSE は二乗するぶん 1 つの大外れに引きずられる。MAE は線形、中央絶対誤差はほぼ動かない。

Python で計算する #

5 件の実測値と予測値から、scikit-learn の関数で MAE と RMSE を求めます。誤差は 0.5, 1.0, 1.0, 0.5, 1.0 なので、MAE = 0.8、RMSE ≈ 0.837 になるはずです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error

y_true = np.array([10, 12, 9, 11, 10])
y_pred = np.array([9.5, 13.0, 8.0, 11.5, 9.0])

mae = mean_absolute_error(y_true, y_pred)
rmse = mean_squared_error(y_true, y_pred, squared=False)

print(f"MAE = {mae:.3f}")
print(f"RMSE = {rmse:.3f}")

mean_squared_error(..., squared=False) とすれば平方根付きで RMSE を得られます。平方根を掛けない既定の値は MSE です。


外れ値がある場合の比較 #

次の実験では、20 件の予測に標準偏差 1.0 のノイズを乗せた「きれいな」状態と、そのうち 1 件だけを 15 ずらした「外れ値あり」の状態で、MAE と RMSE がどれだけ動くかを比べます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import numpy as np

rng = np.random.default_rng(42)
baseline = np.linspace(100, 110, 20)
prediction = baseline + rng.normal(0, 1.0, size=baseline.size)

mae_clean = np.mean(np.abs(baseline - prediction))
rmse_clean = np.sqrt(np.mean((baseline - prediction) ** 2))

prediction_with_outlier = prediction.copy()
prediction_with_outlier[0] += 15

mae_outlier = np.mean(np.abs(baseline - prediction_with_outlier))
rmse_outlier = np.sqrt(np.mean((baseline - prediction_with_outlier) ** 2))

print(f"MAE (clean, outlier) = {mae_clean:.2f}, {mae_outlier:.2f}")
print(f"RMSE (clean, outlier) = {rmse_clean:.2f}, {rmse_outlier:.2f}")

MAE は外れ値が 1 件加わっても 0.70 から 1.45 と緩やかに増えますが、RMSE は 0.85 から 3.53 へ大きく引っ張られ、誤差の跳ね上がりを敏感に捉えます。


指標の選び方 #

外れ値が少なく平均的な誤差を重視するなら、RMSE を採用すると 0.5 と 1.0 のような微妙なずれの違いも評価に乗ります。外れ値が多く頑健な指標が欲しいなら、MAE や中央絶対誤差(MedAE)を併用します。エネルギー損失や物理誤差のように報酬・コストが誤差の二乗に比例する問題では RMSE が自然で、「平均で 2 ℃ ずれる」と単位をそのまま伝えたい報告では MAE が直感的です。


追加の指標と組み合わせ #

MAPE は誤差を実測値で割った百分率で、売上 100 万円と 10 万円の店を同じ物差しで比べたいときに便利ですが、実測値が 0 付近だと発散します。RMSLE は対数を取ってから RMSE を計算し、需要予測で過小予測を強く罰したいときに使います。分位点損失(Pinball Loss)は、売上予測の上限・下限のようにリスク区間を評価したい場面で有効です。


ノイズと MAE/RMSE #

ノイズ量を 0 から 3.0 まで動かすと、MAE と RMSE がどう変化するか確認できます。ノイズが正規分布なら RMSE/MAE はおよそ 1.25 で一定に保たれ、外れ値が混ざるとこの比が広がります。

MAE と RMSE の違い #

MAE と RMSE はどちらも「予測のずれの大きさ」を測る指標ですが、誤差の扱い方が根本的に異なります。

数学的な違い:絶対値 vs 二乗 #

MAE は誤差の絶対値を平均するので、誤差が 1 でも 10 でも寄与は線形に増えます。RMSE は誤差を二乗してから平均し、最後に平方根を取るので、誤差 10 は二乗和の中で 100 として効き、大きな誤差ほど寄与が急増します。この違いにより、同じデータに対して RMSE は MAE よりも大きな誤差を「重く」評価します。

なぜ RMSE ≥ MAE が常に成り立つのか #

二乗平均は算術平均以上になるという**二乗平均と算術平均の不等式(QM-AM 不等式)**により、次が常に成り立ちます。

$$ \mathrm{MAE} \leq \mathrm{RMSE} \leq \sqrt{n} \cdot \mathrm{MAE} $$

直感的には、RMSE は大きな誤差を二乗で膨らませるため、絶対値だけの MAE を下回ることはありません。等号は 5 件の誤差がすべて 2.0 のように同じ大きさのときだけです。逆に、上界の \(\sqrt{n} \cdot \mathrm{MAE}\) に達するのは 1 個だけ誤差があり残りがすべて 0 の極端なケースです。

つまり MAE > RMSE になることは数学的にあり得ません。もし手元の計算でそうなった場合は、計算ミスか指標の取り違え(MSE と RMSE の混同など)を疑ってください。

外れ値への感度の比較 #

誤差が \(e\) のとき、MAE への寄与は \(|e|\)、RMSE への寄与(二乗ベース)は \(e^2\) で、誤差 10 は MAE には 10、RMSE の二乗和には 100 として効きます。このため外れ値が 1 つあるだけで RMSE は大きく跳ね上がりますが、MAE の変化は穏やかです。

数値例で確認する #

5 件の予測がある場合を考えます。

データ\(y\)\(\hat{y}\)誤差 \(e\)\(|e|\)\(e^2\)
11011−111
22019111
33028224
44041−111
550455525
$$ \mathrm{MAE} = \frac{1+1+2+1+5}{5} = 2.0 $$$$ \mathrm{RMSE} = \sqrt{\frac{1+1+4+1+25}{5}} = \sqrt{6.4} \approx 2.53 $$

5 番目のデータに誤差 5 という「外れ値的な誤差」があるため、RMSE は MAE より約 26% 大きくなっています。もしすべての誤差が同じ 2.0 であれば、MAE = RMSE = 2.0 と一致します。


MAE と RMSE の比較表 #

特性MAERMSE
計算方法絶対値の平均二乗平均の平方根
外れ値への感度低い(線形)高い(二乗で増幅)
微分可能性0 で不連続(勾配不定)どこでも微分可能
解釈平均的な誤差の大きさ二乗平均平方根誤差
単位目的変数と同じ目的変数と同じ
不等式MAE ≤ RMSERMSE ≤ √n × MAE
最適化との相性中央値を推定(L1 回帰)平均値を推定(L2 回帰)
勾配ベース学習勾配が ±1 で一定勾配が誤差に比例

使い分けガイド #

RMSE を選ぶ場面 #

誤差 10 を誤差 1 の 100 倍として罰したい、つまり大きな誤差をとくに避けたい場合に向きます。医療予測や安全関連のシステムでは 1 件でも大きく外れると致命的で、RMSE なら外れ値を強くペナルティするため極端な予測ミスが見えやすくなります。MSE / RMSE はどこでも微分可能なので、ニューラルネットワークの損失関数として勾配ベースの最適化を行う場合にも扱いやすい。物理シミュレーションやエネルギー損失計算のように、ずれの二乗がそのまま実コストになる領域では RMSE が自然な選択です。

MAE を選ぶ場面 #

外れ値が多いデータに向きます。不動産価格やユーザー行動データのように分布の裾が重いデータでは、MAE のほうが安定した評価ができます。「平均して 2 万円ずれる」と一言で説明できるため、ビジネスの非技術者にも伝えやすい。MAE を最小化すると条件付き中央値を推定することになるので、偏った分布で頑健な中央値推定が目的の場合にも適します。

両方を併用する #

実務では MAE と RMSE を並べて報告するのがもっとも情報量が多い。両者の差(RMSE − MAE)が大きいほど、誤差のばらつき(=外れ値の存在)が大きいことを示します。上の表の誤差 [1, 1, 2, 1, 5] で、この差を計算してみます。

1
2
3
4
5
6
7
8
9
import numpy as np

errors = np.array([1, 1, 2, 1, 5])
mae = np.mean(np.abs(errors))
rmse = np.sqrt(np.mean(errors ** 2))

print(f"MAE  = {mae:.2f}")
print(f"RMSE = {rmse:.2f}")
print(f"差   = {rmse - mae:.2f}  ← 大きいほど外れ値の影響が強い")

まとめ #

MAE は誤差の絶対値の平均、RMSE は誤差の二乗平均の平方根で、どちらも元データと同じ単位の「平均的なずれ」を表しますが、外れ値への感度が違います。誤差 [1, 1, 2, 1, 5] では MAE = 2.0、RMSE ≈ 2.53 で、20 件中 1 件を 15 ずらすと MAE は 2 倍、RMSE は 4 倍になりました。QM-AM 不等式から常に MAE ≤ RMSE ≤ √n·MAE が成り立ち、2 つの差が大きいほど外れ値の影響が強いと読めます。MAE は解釈が容易で頑健、RMSE は大きな誤差を重視し勾配最適化と相性が良いので、mean_absolute_error と mean_squared_error(squared=False) で両方を並べて報告し、MAPE や RMSLE も合わせてビジネス上のコスト構造に合う指標を選びます。