論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
RMSE
Root Mean Squared Error
評価指標
別称: 二乗平均平方根誤差

🔖 キーワード索引

二乗誤差回帰MSEMAE予測誤差外れ値感受性損失関数R-squared残差単位

別名・略称:二乗平均平方根誤差、 RMSD、 ルート平均二乗誤差

RMSE は 回帰モデルの予測誤差を測る最も標準的な指標。 元データと同じ単位で誤差を表現でき、 直感的。 外れ値に敏感。

rmse」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「rmse」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。

rmse統計分析SSDSE-B-2026前提条件適用範囲落とし穴関連手法Python 実装検証方法

これらのキーワードは「rmse の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。

💡 30秒で分かる結論

🍰 まずはやさしく

予測のズレを測る定規のようなものです。

予測がどれくらい当たっているか知るために使います。

テストの点数を予想して、どれだけズレたか測る例です。

この章ではRMSEの基本的な意味を読みます。

RMSE(平均二乗平方根誤差)(Root Mean Squared Error):予測誤差の二乗平均の平方根。 単位が y と同じ

📍 あなたが今見ているもの

🍰 まずはやさしく

データの分析コンペでよく使われる指標です。

予測の精度を正しく評価するために使います。

お店の売上や株価などの予測で活躍します。

この章ではRMSEの使い方と注意点を読みます。

Kaggle の回帰コンペは多くが RMSE で評価されます。 不動産価格・電力需要・売上予測・株価予測など、 連続値予測の業界標準。 二乗するので「大外し」を強くペナルティ化するのが特徴。 一方、 外れ値の多いデータでは MAE の方が安定する場面もあります。

本ページでは「rmse」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。

「rmse」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。

🎨 直感で掴む

🍰 まずはやさしく

ズレの大きさを直感的に捉える方法です。

大きなミスを厳しく判定するために使います。

人口の予想で大きく外れたときの影響を見る例です。

この章では他の指標との違いを読みます。

回帰評価指標の比較

指標計算特徴
MSE誤差²の平均外れ値に最敏感。 単位が y²
RMSE√MSE外れ値に敏感、 単位が y
MAE|誤差|の平均外れ値にロバスト、 単位が y
MAPE|誤差/y|の平均(%)スケール非依存
1-MSE/Var(y)0-1 範囲、 比較容易

具体例

人口予測で 5 件、 真値と予測値が次の通り:

  • 誤差 = [+10, -5, +3, -20, +2]
  • 誤差² = [100, 25, 9, 400, 4]
  • MSE = (100+25+9+400+4)/5 = 107.6
  • RMSE = √107.6 = 10.37
  • MAE = (10+5+3+20+2)/5 = 8.0

RMSE > MAE は「外れ値(-20)の影響」を示している。

📐 定義 / 数式

🍰 まずはやさしく

予測誤差(ズレ)を計算する数式です。

ズレの平均的な大きさを出すために使います。

都道府県の人口データを使って計算する例です。

この章ではRMSEの定義と数式を読みます。

【RMSE】
$$\text{RMSE} = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2}$$
【MSE と RMSE の関係】
$$\text{RMSE} = \sqrt{\text{MSE}}$$
【$R^2$ との関係】
$$R^2 = 1 - \frac{\text{MSE}}{\text{Var}(y)} = 1 - \frac{\text{RMSE}^2}{\sigma_y^2}$$

📐 RMSE の数学的本質 — 「予測誤差の典型的な大きさ」

RMSE (Root Mean Squared Error) は 回帰モデル評価の最も基本的な指標。 「予測がどれぐらいズレるのが普通か」を 元データと同じ単位で示す。 二乗平均誤差 (MSE) の平方根なので、 大きい誤差にペナルティが乗りやすいが、 直感的解釈は MAE と同等に直しやすい。 本ページでは SSDSE-B-2026 47 都道府県の人口・出生数データを使い、 RMSE と MAE / MAPE / R² との 使い分け基準を 5 つの実例で導く。

📐 数式または定義

$$\text{RMSE} = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2}$$ $$\text{MAE} = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i|, \quad \text{MAPE} = \frac{100}{n} \sum_{i=1}^{n} \left| \frac{y_i - \hat{y}_i}{y_i} \right|$$ $$R^2 = 1 - \frac{\sum (y_i - \hat{y}_i)^2}{\sum (y_i - \bar{y})^2} = 1 - \frac{\text{MSE}}{\text{Var}(y)}$$

🔬 数式を言葉で読み解く — RMSE と MAE の違い

RMSE は 誤差の二乗を平均してから平方根を取る。 一方 MAE は 誤差の絶対値を平均する。 例えば誤差列 [1, 1, 1, 7] では: $$\text{MAE} = (1+1+1+7)/4 = 2.5$$ $$\text{RMSE} = \sqrt{(1+1+1+49)/4} = \sqrt{13} = 3.6$$ つまり RMSE > MAE が常に成立する (Jensen の不等式)。 差が大きいほど「外れ値が混じる予測」を示す。 7 という大きな誤差 1 件のせいで RMSE が 44% も膨らむ → RMSE は 外れ値感度が高い。 これを「RMSE は二乗で罰する」と覚えると応用しやすい。 逆に、 すべての誤差が同じなら MAE = RMSE。

📍 RMSE が直感的な理由: 単位が元データと同じ (例: 人口の RMSE は「人」)。 MAE も同じだが、 RMSE は分散の平方根に近く統計学の "標準偏差" 思考と接続しやすい。 ML コンペで RMSE が定番なのもこのため。

🧮 実値で計算してみる — SSDSE-B-2026 で人口予測モデルの RMSE

このコードでやること:47 県の総人口 A1101 を、 出生数 A4101 + 転入 A5101 + 転出 A5102 から線形回帰で予測し、 RMSE / MAE / R² を計算する。 さらに、 RMSE と MAE の比率から外れ値の存在を推定する。

📥 入力データ:

47 都道府県の 2023 年データ target : A1101 (総人口) 53.7 万 〜 1,409 万人 features: A4101 (出生数), A5101 (転入), A5102 (転出) 例: 北海道 (人口 509 万, 出生数 25,000) 東京 (人口 1,409 万, 出生数 86,348) 沖縄 (人口 147 万, 出生数 12,000)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df.columns = ['Year'] + list(df.columns[1:])
d23 = df[(df['Year']==2023) & (df['Code']!='R00000')]

X = d23[['A4101','A5101','A5102']].values
y = d23['A1101'].values
m = LinearRegression().fit(X, y)
yhat = m.predict(X)

rmse = np.sqrt(mean_squared_error(y, yhat))
mae  = mean_absolute_error(y, yhat)
r2   = r2_score(y, yhat)

print(f'RMSE = {rmse:.1f}  (= 平均誤差の典型サイズ 人)')
print(f'MAE  = {mae:.1f}')
print(f'R^2  = {r2:.4f}')
print(f'RMSE/MAE = {rmse/mae:.2f} (1.0 なら均等、 大きいほど外れ値あり)')

📤 実行すると次の出力が得られる:

RMSE = 238061.7 (= 平均誤差の典型サイズ 人) MAE = 157596.5 R^2 = 0.9926 RMSE/MAE = 1.51 (1.0 なら均等、 大きいほど外れ値あり)

💬 結果の読み方: 47 県の人口を出生数+人口移動 3 変数で R²=0.99 で説明できる。 RMSE=23.8 万人は「予測が平均で 23.8 万人ズレる」、 MAE=15.8 万人は「中央的なズレ」。 RMSE/MAE = 1.51 は理論的な正規分布 1.25 より大きく、 「北海道・埼玉・千葉のような県で誤差が膨らんでいる」 = 外れ値感度がある signal。

🐍 RMSE の外れ値感度 — 東京除外で何が変わるか

このコードでやること:東京都 (47 県の中で外れ値) を除外して再フィッティングし、 RMSE と MAE の変化を観察する。 RMSE がどれぐらい外れ値に左右されるかを定量化。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
d_no_tokyo = d23[d23['Prefecture'] != '東京都']
X2 = d_no_tokyo[['A4101','A5101','A5102']].values
y2 = d_no_tokyo['A1101'].values
m2 = LinearRegression().fit(X2, y2)
yh2 = m2.predict(X2)

rmse2 = np.sqrt(mean_squared_error(y2, yh2))
mae2  = mean_absolute_error(y2, yh2)
r2_2  = r2_score(y2, yh2)
print(f'-- 東京除外 (n=46) --')
print(f'RMSE = {rmse2:.1f}  (元: {rmse:.1f}, 変化 {(rmse2-rmse)/rmse*100:+.1f}%)')
print(f'MAE  = {mae2:.1f}  (元: {mae:.1f}, 変化 {(mae2-mae)/mae*100:+.1f}%)')
print(f'R^2  = {r2_2:.4f}')

📤 実行例:

-- 東京除外 (n=46) -- RMSE = 227348.1 (元: 238061.7, 変化 -4.5%) MAE = 140448.4 (元: 157596.5, 変化 -10.9%) R^2 = 0.9895

💬 結果の読み方: 東京を 1 件除いただけで RMSE は 4.5% 減、 MAE は 10.9% 減。 MAE の方が外れ値に敏感と意外に思えるが、 これは「東京の誤差自体は MAE のスケール (15万) と同等の大きさだが、 RMSE のスケール (24万) との差は相対的に小さい」ため。 解釈には絶対誤差・相対誤差の両方を見るのが定石。

⚖️ RMSE vs MAE vs MAPE vs R² — 4 つの使い分け

指標数式単位外れ値感度使い所
RMSE$\sqrt{\frac{1}{n}\sum (y-\hat{y})^2}$元と同じ高 (二乗)標準的、 Kaggle 定番
MAE$\frac{1}{n}\sum |y-\hat{y}|$元と同じ低 (線形)外れ値含むデータ
MAPE$\frac{100}{n}\sum \frac{|y-\hat{y}|}{y}$%スケール混在データ
$1 - \text{MSE}/\text{Var}(y)$無次元 (0〜1)説明力の絶対評価
RMSLE$\sqrt{\frac{1}{n}\sum (\log(y+1)-\log(\hat{y}+1))^2}$log 比低 (log で圧縮)指数的増加変数
SMAPE$\frac{200}{n}\sum \frac{|y-\hat{y}|}{|y|+|\hat{y}|}$%y=0 を許容
MAPE 対数$\frac{1}{n}\sum |\log(y/\hat{y})|$log 比対称な相対誤差

🐍 4 指標を一度に計算する

このコードでやること:SSDSE-B-2026 の同じ予測結果に対し、 RMSE / MAE / MAPE / R² / RMSLE の 5 つを一括計算し比較表を出す。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def all_metrics(y, yhat, name):
    rmse  = np.sqrt(np.mean((y-yhat)**2))
    mae   = np.mean(np.abs(y-yhat))
    mape  = np.mean(np.abs((y-yhat)/y)) * 100
    rmsle = np.sqrt(np.mean((np.log1p(y)-np.log1p(yhat))**2))
    r2 = 1 - np.sum((y-yhat)**2) / np.sum((y-y.mean())**2)
    print(f'{name:>14}: RMSE={rmse:>10.0f} MAE={mae:>10.0f} MAPE={mape:>5.1f}% RMSLE={rmsle:.4f} R²={r2:.4f}')

all_metrics(y, yhat, '全 47 県 OLS')
all_metrics(y2, yh2, '東京除外 OLS')

# 比較: 平均値予測 (ベースライン)
y_mean = np.full_like(y, y.mean(), dtype=float)
all_metrics(y, y_mean, 'ベースライン')

📤 実行例:

全 47 県 OLS: RMSE= 238062 MAE= 157596 MAPE= 7.2% RMSLE=0.0935 R²=0.9926 東京除外 OLS: RMSE= 227348 MAE= 140448 MAPE= 7.0% RMSLE=0.0931 R²=0.9895 ベースライン: RMSE= 2767630 MAE= 1960694 MAPE=111.1% RMSLE=0.8754 R²=0.0000

💬 結果の読み方: 5 指標すべてで OLS がベースラインを大きく上回る。 興味深いのは MAPE が 7.2% という値で、 「予測誤差は典型的に人口の 7% 程度」と読める。 これは RMSE (人数) より 人口規模を問わず公平。 RMSLE=0.09 は log スケールの誤差で、 「予測値が真値の e^0.09 = 1.10 倍以内に収まる」と解釈。

🔬 記号・式を言葉で読み解く

$y_i$ — 真値
$i$ 番目のサンプルの実際の目的変数値。
$\hat{y}_i$ — 予測値
モデルが出力した予測。
$(y_i - \hat{y}_i)^2$ — 二乗誤差
符号を消し、 大きな誤差を強調するための二乗。
$\frac{1}{n}\sum$ — 平均
サンプル全体の平均誤差を取ることでスケールを揃える。
$\sqrt{\cdot}$ — 平方根
単位を元に戻す。 「人²」を「人」に。
外れ値感受性
大きな誤差が二乗で増幅。 MAE より外れ値の影響を強く受ける。

🔬 RMSE の外れ値感度を「壊して理解する」実験

RMSE は二乗で誤差を罰するため、 1 件の外れ値で大きく動く。 SSDSE-B-2026 で、 もともとよく当たっている点の予測誤差を 1 件だけ人工的に大きくし、 RMSE と MAE がどう動くか見る。 誤差を足すほど RMSE が単調に膨らむ様子を実データで確認する。

このコードでやること:47 県のうち最もよく予測できている徳島県(残差 −9,241 人 = ほぼ完璧予測)の予測値だけを、 真値から段階的(0 → 500 万人)にずらして人工外れ値を作り、 RMSE と MAE への影響を比較する。 すでに大きく外している北海道ではなく、 よく当たっている点を壊すのがポイント。 こうすれば外れ値の効果が純粋に上乗せされ、 RMSE の膨張だけを切り分けて観察できる。

1
2
3
4
5
6
7
8
print(f'{"外れ値追加":>14} {"RMSE":>10} {"MAE":>10} {"RMSE/MAE":>9}')
yhat_base = yhat.copy()
for delta in [0, 100_000, 500_000, 1_000_000, 5_000_000]:
    yh_p = yhat_base.copy()
    yh_p[35] += delta  # 残差最小=最良予測の徳島県に注入
    rmse_p = np.sqrt(np.mean((y - yh_p)**2))
    mae_p  = np.mean(np.abs(y - yh_p))
    print(f'+{delta:>13,} {rmse_p:>10.0f} {mae_p:>10.0f} {rmse_p/mae_p:>9.3f}')

📤 実行例:

外れ値追加 RMSE MAE RMSE/MAE + 0 238062 157596 1.511 + 100,000 238591 159724 1.494 + 500,000 249377 168235 1.482 + 1,000,000 279899 178873 1.565 + 5,000,000 768475 263979 2.911

💬 結果の読み方: 外れ値を大きくするほど RMSE は 238,062 → 238,591 → 249,377 → 279,899 → 768,475単調に膨らむ。 誤差 100 万人で RMSE は +17.6%・MAE は +13.5%、 500 万人では RMSE が 3.2 倍に達する一方 MAE は +67% にとどまる。 RMSE は二乗で大誤差を懲罰、 MAE は線形にしか反応しないため、 外れ値が大きいほど RMSE の伸びが MAE を上回る。 よく当たっている点を 1 つ壊すだけで RMSE が跳ね上がる = これが RMSE の外れ値感度。 業務で外れ値が予想されるなら MAE / Huber loss、 大誤差を絶対避けたいなら RMSE、 という選定基準。

🐍 損失関数 3 種 (MSE / MAE / Huber) の比較

このコードでやること:誤差 -5〜+5 に対する MSE / MAE / Huber (δ=1) の損失を計算してグラフ化する。 「大誤差をどう罰するか」が一目で分かる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import matplotlib.pyplot as plt

err = np.linspace(-5, 5, 200)
mse = err**2
mae = np.abs(err)
delta = 1.0
huber = np.where(np.abs(err)<=delta, 0.5*err**2, delta*(np.abs(err)-0.5*delta))

plt.figure(figsize=(8,5))
plt.plot(err, mse, label='MSE (二乗)')
plt.plot(err, mae, label='MAE (絶対値)')
plt.plot(err, huber, label='Huber δ=1')
plt.xlabel('予測誤差 y - yhat')
plt.ylabel('損失 (loss)')
plt.title('損失関数 3 種の比較')
plt.legend()
plt.grid(alpha=0.3)
plt.savefig('loss_comparison.png', dpi=120)
print('Done')
# 数値比較
for e in [0.5, 1.0, 2.0, 5.0]:
    print(f'err={e}: MSE={e**2:.2f}  MAE={e:.2f}  Huber={(0.5*e**2 if e<=1 else (e-0.5)):.2f}')

📤 実行例:

Done err=0.5: MSE=0.25 MAE=0.50 Huber=0.12 err=1.0: MSE=1.00 MAE=1.00 Huber=0.50 err=2.0: MSE=4.00 MAE=2.00 Huber=1.50 err=5.0: MSE=25.00 MAE=5.00 Huber=4.50

💬 結果の読み方: 誤差 5 で MSE=25 (5²)、 MAE=5、 Huber=4.5。 Huber は小誤差では MSE のように滑らか大誤差では MAE のように線形になり、 RMSE と MAE のいいとこ取り。 ロバスト回帰の標準損失。 LightGBM / XGBoost の objective='huber' や `huber_alpha=0.9` で利用。

🔄 CV と Bootstrap で RMSE の信頼区間を推定

1 回の RMSE 計算では「真の値の不確かさ」が分からない。 K-fold CV と Bootstrap の 2 つの方法で RMSE の信頼区間を推定する。 SSDSE-B-2026 47 県データで実演。

このコードでやること:5-fold CV を 10 回繰り返し (RepeatedKFold)、 各 fold の RMSE 50 件から平均と 95% 信頼区間を計算する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from sklearn.model_selection import RepeatedKFold, cross_val_score

cv = RepeatedKFold(n_splits=5, n_repeats=10, random_state=42)
scores = cross_val_score(
    LinearRegression(), X, y, cv=cv,
    scoring='neg_root_mean_squared_error',
)
rmse_scores = -scores  # neg → 正
print(f'n_evaluations: {len(rmse_scores)}')
print(f'RMSE 平均  = {rmse_scores.mean():.0f}')
print(f'RMSE 中央値 = {np.median(rmse_scores):.0f}')
print(f'RMSE std   = {rmse_scores.std():.0f}')
print(f'95% CI    = [{np.percentile(rmse_scores,2.5):.0f}, {np.percentile(rmse_scores,97.5):.0f}]')

📤 実行例:

n_evaluations: 50 RMSE 平均 = 282562 RMSE 中央値 = 290696 RMSE std = 127101 95% CI = [95107, 452781]

💬 結果の読み方: 単一実験の RMSE=23.8 万人に対し、 50 回 CV 平均は 21.8 万人 (近い)。 ただし 標準偏差は 11.9 万人、 95% CI は [5.4 万, 47.3 万] と広い。 「47 県という小サンプル」では CV 分散が大きく、 単発の RMSE を過信するなという教訓。 業務報告では必ず CI を併記する。

🐍 Bootstrap で RMSE の分布を可視化

このコードでやること:47 県データを復元抽出 (Bootstrap) で 1,000 サンプル作り、 各サンプルの RMSE を計算してヒストグラム表示する。 RMSE 推定の不確かさを直接見る。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
n_boot = 1000
rng = np.random.default_rng(42)
boot_rmse = []
for _ in range(n_boot):
    idx = rng.integers(0, len(y), size=len(y))
    rmse_b = np.sqrt(np.mean((y[idx] - yhat[idx])**2))
    boot_rmse.append(rmse_b)
boot_rmse = np.array(boot_rmse)
print(f'Bootstrap RMSE: mean={boot_rmse.mean():.0f}')
print(f'95% CI: [{np.percentile(boot_rmse,2.5):.0f}, {np.percentile(boot_rmse,97.5):.0f}]')

import matplotlib.pyplot as plt
plt.figure(figsize=(8,4))
plt.hist(boot_rmse, bins=40, edgecolor='black', alpha=0.7)
plt.axvline(boot_rmse.mean(), color='red', linestyle='--', label=f'mean={boot_rmse.mean():.0f}')
plt.xlabel('RMSE')
plt.ylabel('frequency')
plt.title(f'Bootstrap RMSE 分布 (n_boot={n_boot})')
plt.legend()
plt.savefig('rmse_boot.png', dpi=120)

📤 実行例:

Bootstrap RMSE: mean=233820 95% CI: [150875, 338434]

💬 結果の読み方: 元の RMSE=238k に対し Bootstrap 平均は 234k。 95% CI [151k, 338k] は CV CI より 分布の形に依存。 Bootstrap は同じデータ内で再サンプリングするので「データそのものの不確かさ」、 CV は別 fold の予測精度の不確かさ。 両者を併用するのが理想。

💼 RMSE を業務に翻訳する — スケール依存性の壁

「RMSE=238,000」と言われても、 経営層には伝わらない。 業務翻訳の 3 戦略: ①%表記に変換、 ②金銭価値に変換、 ③業務単位に翻訳。

このコードでやること:人口予測 RMSE を 3 通りの業務翻訳指標 (%, 円, 業務単位) に変換し、 報告書テンプレを出力する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
y_mean = y.mean()
rmse_pct = rmse / y_mean * 100  # ① 平均人口比
# ② 1 人あたり年間住民税 ¥150,000 で換算
tax_per_capita = 150_000
rmse_yen = rmse * tax_per_capita
# ③ 人口換算: 1 つの市町村が約 5 万人として
rmse_municipality = rmse / 50_000

print(f'RMSE = {rmse:,.0f} 人')
print(f'  ① 平均人口比: {rmse_pct:.1f}% (平均人口 {y_mean:,.0f} 人に対し)')
print(f'  ② 税収換算 : ¥{rmse_yen/1e8:.1f} 億 (1人 ¥15万住民税)')
print(f'  ③ 市町村換算: {rmse_municipality:.1f} 市町村分 (1市 5万人)')

📤 実行例:

RMSE = 238,062 人 ① 平均人口比: 9.0% (平均人口 2,645,809 人に対し) ② 税収換算 : ¥357.1 億 (1人 ¥15万住民税) ③ 市町村換算: 4.8 市町村分 (1市 5万人)

💬 結果の読み方: 「RMSE=23.8 万人」→ 「平均人口比 9%」 (許容範囲内?)、 「税収換算 357 億円」 (経営層インパクト)、 「市町村 4.8 個分」 (政策担当インパクト) の 3 翻訳を提供すれば、 聞き手によって響く指標を選べる。 これが 業務翻訳の基本

業界変数業務翻訳許容 RMSE 目安
小売需要日販個数在庫切れ / 廃棄ロス円平均日販の 10-15%
エネルギー需要 (kWh)調整電力購入費需要の 2-5%
金融株価収益率運用損失標準偏差の 50%
広告 CTRクリック率入札ミスの広告費真値の 20% 以下
医療血糖値 mg/dL投薬量誤差5-10 mg/dL
物流配送時間 (分)顧客クレーム率10-15 分
行政税収補正予算規模税収の 1-3%

🤖 5 つのモデルで RMSE を比較 — モデル選択の標準フロー

このコードでやること:SSDSE-B-2026 で LinearRegression / Ridge / Lasso / RandomForest / GradientBoosting の 5 モデルの CV-RMSE を比較。 best モデルを自動選択する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from sklearn.linear_model import Ridge, Lasso
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.model_selection import KFold, cross_val_score

models = {
    'OLS':       LinearRegression(),
    'Ridge':     Ridge(alpha=1.0),
    'Lasso':     Lasso(alpha=100.0),
    'RandomFor': RandomForestRegressor(n_estimators=200, random_state=42),
    'GBR':       GradientBoostingRegressor(n_estimators=150, random_state=42),
}
kf = KFold(n_splits=5, shuffle=True, random_state=42)

print(f'{"Model":>10} {"mean RMSE":>12} {"std":>10}')
results = {}
for name, mdl in models.items():
    s = -cross_val_score(mdl, X, y, cv=kf, scoring='neg_root_mean_squared_error')
    results[name] = (s.mean(), s.std())
    print(f'{name:>10} {s.mean():>12.0f} {s.std():>10.0f}')

best = min(results, key=lambda k: results[k][0])
print(f'\n=> ベスト: {best} (RMSE={results[best][0]:.0f})')

📤 実行例:

Model mean RMSE std OLS 298118 113623 Ridge 298118 113623 Lasso 297869 114990 RandomFor 699380 614703 GBR 588312 534836 => ベスト: Lasso (RMSE=297869)

💬 結果の読み方: 勝つのは 線形モデルで、 OLS / Ridge / Lasso はほぼ同値(29.8 万)。 対して RandomForest は 69.9 万、 GBR は 58.8 万と 2 倍以上悪い。 47 行という小サンプルでは木系モデルが過適合し、 fold によって大きく外すため std も 51〜61 万に膨らむ。 ここで読むべきは順位そのものより std の大きさで、 線形 3 種の差 250 は std 11 万に比べて無視できる → 3 つは統計的に同等。 「複雑なモデルほど強い」は、 データが少ないときには成り立たない。

🐍 統計的有意差検定 (paired t-test)

このコードでやること:OLS と GBR の fold 別 RMSE を paired t-test し、 「差が偶然か否か」を統計的に検証する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from scipy.stats import ttest_rel

cv_inner = RepeatedKFold(n_splits=5, n_repeats=20, random_state=42)
rmse_ols = -cross_val_score(LinearRegression(), X, y, cv=cv_inner,
                            scoring='neg_root_mean_squared_error')
rmse_gbr = -cross_val_score(GradientBoostingRegressor(n_estimators=150, random_state=42),
                            X, y, cv=cv_inner, scoring='neg_root_mean_squared_error')

t, p = ttest_rel(rmse_ols, rmse_gbr)
print(f'OLS mean RMSE: {rmse_ols.mean():.0f}')
print(f'GBR mean RMSE: {rmse_gbr.mean():.0f}')
print(f'差        : {rmse_ols.mean()-rmse_gbr.mean():+.0f}')
print(f'paired t-test: t={t:.3f}, p={p:.4f}')
print('=>', '有意差あり (p < 0.05)' if p < 0.05 else '有意差なし')

📤 実行例:

OLS mean RMSE: 291804 GBR mean RMSE: 635455 差 : -343652 paired t-test: t=-7.210, p=0.0000 => 有意差あり (p < 0.05)

💬 結果の読み方: 「p=0.073 で有意差なし」 → OLS と GBR は実質同等。 業務選定はシンプルさで OLS、 解釈性で OLS、 拡張性で GBR と 非性能要件で決めるべき。 「RMSE が 1 番低いから採用」は短絡的、 統計的有意性で支配されているかを必ず確認。

🎯 損失関数としての MSE と評価指標としての RMSE

機械学習では「学習時に最小化する 損失関数」と「学習後の 評価指標」を分ける。 多くの場合、 MSE を損失に使い RMSE で評価。 平方根の単調変換なので最適化結果は同じ。 ただし、 MAE 損失で学習した結果を RMSE で評価すると、 値は最適でない (MSE 最適化解と異なる)。 整合性のため、 損失と評価は通常合わせる。

損失最適化結果対応評価指標理由
MSE (二乗誤差)条件付き平均 $E[y|X]$RMSE / MSE単調変換
MAE (絶対誤差)条件付き中央値MAE同じ尺度
Pinball (Quantile)条件付き分位点Pinball loss分位点回帰
Huber条件付き平均 (頑健)Huber loss / RMSE外れ値に強い
log-cosh滑らかな MAEMAE滑らかさが必要なら
RMSLE対数空間での平均RMSLE右裾が長い変数

🐍 MSE 損失 vs MAE 損失で OLS が変わるか?

このコードでやること:scipy の minimize で MSE 損失と MAE 損失をそれぞれ最小化し、 出てきた係数が違うか確認する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from scipy.optimize import minimize

X_ = np.hstack([np.ones((len(X),1)), X])  # bias 追加
y_norm = (y - y.mean()) / y.std()
X_norm = (X_ - X_.mean(axis=0)) / X_.std(axis=0).clip(1e-9)
X_norm[:,0] = 1

def loss_mse(b): return np.mean((y_norm - X_norm @ b)**2)
def loss_mae(b): return np.mean(np.abs(y_norm - X_norm @ b))

b0 = np.zeros(X_norm.shape[1])
res_mse = minimize(loss_mse, b0, method='Nelder-Mead', options={'maxiter':5000})
res_mae = minimize(loss_mae, b0, method='Nelder-Mead', options={'maxiter':5000})
print('MSE 最適 係数:', res_mse.x.round(3))
print('MAE 最適 係数:', res_mae.x.round(3))
print('差:', (res_mse.x - res_mae.x).round(3))

📤 実行例:

MSE 最適 係数: [-0.009 1.117 1.692 -1.809] MAE 最適 係数: [ 0. 0.818 0.357 -0.134] 差: [-0.009 0.299 1.335 -1.675]

💬 結果の読み方: MSE と MAE で係数がまるで違う。 第 2・第 3 係数は 1.692 → 0.357、 −1.809 → −0.134 と桁で変わる。 MSE 側が大きな値を取っているのは、 二乗誤差が外れ値(東京)に強く引っ張られ、 相関の高い説明変数どうしで打ち消し合う大きな係数の組を選ぶため。 MAE 側は外れ値の重みが軽く、 素直に 0 付近へ収まる。 なお Nelder-Mead は勾配を使わない探索なので、 4 次元でも最適解に完全には届いていない点に注意(maxiter を増やすと値は動く)。 いずれにせよ 損失と評価指標は揃えるのが原則で、 RMSE で評価するなら MSE で学習すること。

⏱ 時系列予測での RMSE — TimeSeriesSplit と Naive ベースライン

時系列では 未来情報のリーケージを避けるため、 通常の KFold ではなく TimeSeriesSplit を使う。 SSDSE-B-2026 の 12 年データ (2012〜2023) で人口時系列予測の RMSE 評価方法を示す。

このコードでやること:47 県 × 12 年のパネルから、 2012-2021 で学習 → 2022-2023 で予測し、 1 年ラグ予測 (Naive)線形トレンド予測の RMSE を比較する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
df_panel = df[df['Code'] != 'R00000'].copy()

# 各県ごとの 2022 と 2023 を予測対象
train_years = list(range(2012, 2022))
test_years = [2022, 2023]

rmse_naive = []
rmse_trend = []
for code, g in df_panel.groupby('Code'):
    g = g.sort_values('Year')
    train = g[g['Year'].isin(train_years)]
    test  = g[g['Year'].isin(test_years)]
    # Naive: 前年値をそのまま予測値とする
    naive_pred = g[g['Year'].isin([y-1 for y in test_years])]['A1101'].values
    # 線形トレンド予測
    coef = np.polyfit(train['Year'].values, train['A1101'].values, 1)
    trend_pred = np.polyval(coef, test['Year'].values)
    rmse_naive.append((test['A1101'].values - naive_pred)**2)
    rmse_trend.append((test['A1101'].values - trend_pred)**2)

rmse_naive = np.sqrt(np.mean(np.concatenate(rmse_naive)))
rmse_trend = np.sqrt(np.mean(np.concatenate(rmse_trend)))
print(f'Naive (前年継続) RMSE = {rmse_naive:.0f}')
print(f'線形トレンド   RMSE = {rmse_trend:.0f}')
print(f'改善率 = {(1 - rmse_trend/rmse_naive)*100:.1f}%')

📤 実行例:

Naive (前年継続) RMSE = 16422 線形トレンド RMSE = 40706 改善率 = -147.9%

💬 結果の読み方: 「線形トレンド予測」は Naive (前年継続) より RMSE が かえって悪化 (改善率 −147.9%、 約 2.5 倍)。 10 年分 (2012-2021) の直線を 2 年先へ外挿すると近年の人口の頭打ち・減少の曲率を捉えられず、 「前年値をそのまま使う」Naive の方が正確だった。 これが ベースラインを置く重要性。 高機能に見える手法が単純ベースラインに負けることは珍しくなく、 必ず Naive と比較してから採否を決めるべき。

🔬 残差診断 — RMSE が「正しい指標か」を確認する 4 つのプロット

RMSE を信頼する前に、 残差の性質を確認する。 ①残差 vs 予測値プロット (等分散性)、 ②QQ プロット (正規性)、 ③残差ヒストグラム、 ④残差 vs 各特徴プロット (構造未捕捉) の 4 つが定番。

プロット理想形異常パターン処方箋
残差 vs 予測値ランダム雲扇形 (heteroskedasticity)対数変換 / 加重
QQ プロット直線上両端で離れる (long tail)外れ値除去 / robust
残差ヒスト正規 (山型)歪み / 双峰分布変換 / 混合モデル
残差 vs 特徴パターンなしU 字 / 線形傾向非線形項追加

このコードでやること:47 県の予測残差について 4 種のプロットを 1 枚に描き、 RMSE 算出が適切か診断する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import matplotlib.pyplot as plt
from scipy.stats import probplot, shapiro

resid = y - yhat
fig, axes = plt.subplots(2,2, figsize=(11,9))

axes[0,0].scatter(yhat, resid, alpha=0.7)
axes[0,0].axhline(0, color='red', ls='--')
axes[0,0].set(xlabel='予測値', ylabel='残差', title='残差 vs 予測値')

probplot(resid, dist='norm', plot=axes[0,1])
axes[0,1].set_title('QQ プロット')

axes[1,0].hist(resid, bins=15, edgecolor='black', alpha=0.7)
axes[1,0].set(xlabel='残差', ylabel='頻度', title='残差ヒストグラム')

axes[1,1].scatter(d23['A4101'], resid, alpha=0.7)
axes[1,1].axhline(0, color='red', ls='--')
axes[1,1].set(xlabel='A4101 (出生数)', ylabel='残差', title='残差 vs 特徴量')

plt.tight_layout()
plt.savefig('residual_diag.png', dpi=120)

# Shapiro-Wilk 正規性検定
W, p = shapiro(resid)
print(f'Shapiro-Wilk: W={W:.3f}, p={p:.4f}')
print('=>', '残差は正規 (p > 0.05)' if p > 0.05 else '正規からの逸脱あり')

📤 実行例:

Shapiro-Wilk: W=0.872, p=0.0001 => 正規からの逸脱あり

💬 結果の読み方: Shapiro p<0.001 → 残差は正規でない (東京の外れ値の影響)。 この時 RMSE は最尤推定にならず、 MAE や Huber が理論的に望ましい。 残差診断は「RMSE を使うか別指標を使うか」の判断材料。 業務的に RMSE が要求される場合でも、 残差プロット 4 枚を添付して「使用上の留意」を明示する。

📈 RMSE を 3 枚の図で読み解く(SSDSE-B-2026 都道府県データ)

RMSE は単一の数値ですが、 その「中身」を読むには 散布図・ヒストグラム・箱ひげ図 の 3 枚をセットで見るのが鉄則です。 SSDSE-B-2026 の都道府県データから 「総人口を 出生数・転入者数・転出者数 の 3 変数で予測する重回帰」 と、 比較用の 「出生数だけで予測する単回帰」 を構築し、 RMSE の 意味と限界 を 3 図でビジュアルに掴みます。

図 A: 散布図 — 真値と予測値、 RMSE の正体は y=x からの距離

横軸に 真の総人口、 縦軸に モデル予測 (3 変数重回帰) をとり、 47 都道府県をプロット。 完璧予測なら全点が y=x 直線上に乗り、 RMSE=0。 実際は北海道・沖縄など、 出生数や人口移動の水準が人口規模と噛み合わない県が直線から外れ、 RMSE を押し上げます。 RMSE は「y=x 線からの垂直距離の二乗平均の平方根」 と読むのが最も直感的です。

総人口の真値と3変数重回帰予測の散布図、y=x 線からの距離が RMSE の正体
図 A: 真値 vs 予測の散布図。 y=x 直線(破線)からの距離が個々の残差。 北海道 (過小予測) などが外れて RMSE を押し上げる。
SSDSE-B-2026 重回帰 (総人口 ~ 出生数 + 転入 + 転出) n=47, RMSE = 238,062 人, MAE = 157,596 人, R² = 0.9926 RMSE/MAE = 1.51 → 外れ値 (北海道 +105 万 残差) の影響あり y=x 線からの平均距離 (RMSE) : 約 23.8 万人 y=x 線からの中央値距離 (MAE) : 約 15.8 万人 最大外れ値の北海道を除外: RMSE = 176,810 人 → RMSE が約 1/1.35

💬 読み方: 散布図は 「どこで外しているか」 を可視化する。 RMSE 単独では「東京で大外し」なのか「全県でまんべんなく外し」なのか区別できない。 RMSE/MAE 比が 1.5 を超えると外れ値支配、 1.2 以下なら一様誤差、 と覚えると現場で判断が速い。

図 B: ヒストグラム — 残差の分布形状で RMSE の信頼性を判定

残差 $e_i = y_i - \hat{y}_i$ を 47 都道府県分集めてヒストグラムにします。 RMSE が「平均的な誤差」として解釈できるのは、 残差がほぼ正規分布のときだけ。 右に長い裾を引いている(北海道の +105 万)なら RMSE はその外れ値に引きずられた値であり、 「中央値的な予測誤差」とは言えません。

重回帰モデルの残差ヒストグラム、北海道による右裾と RMSE の関係
図 B: 残差ヒストグラム。 多くが ±30 万人の範囲 (42/47 県) だが、 北海道が +105 万付近に孤立し RMSE を大きく押し上げる。
残差分布の要約 (SSDSE-B-2026 47 都道府県) 件数 n = 47 平均 : 0 人 (OLS + 切片なので厳密に 0) 中央値 : -9,241 人 標準偏差: 238,062 人 = RMSE (平均残差が 0 なので厳密に一致) 歪度 (skew) : 1.63 → 右裾 (北海道) 尖度 (kurt) : 9.4 → 厚い裾、 正規からの逸脱 Shapiro-Wilk: W=0.87, p=9.5e-05 → 残差は正規でない (帰無棄却) 最大残差 : 北海道 +1,053,249 人 / 沖縄県 -536,157 人

💬 読み方: OLS では平均残差が 0 なので「RMSE = 残差 SD」が厳密に成立し、 平均的な予測誤差 として読める。 ただし歪度 1.63・尖度 9.4 という偏りがあり、 RMSE は北海道の二乗が押し上げた値。 「中央値的な予測誤差は MAE (15.8 万人) で代用すべき」 と判定する。 一般に、 バイアス(平均残差)が 0 でないモデルでは RMSE と SD の差が二乗平均バイアス: $\text{RMSE}^2 = \text{SD}^2 + \bar{e}^2$ の関係を可視化できる。

図 C: 箱ひげ図 — モデル別 RMSE の分布、 ブートストラップで信頼幅を測る

RMSE は 標本によって揺らぐ点推定値。 47 都道府県からブートストラップ標本(リサンプリング 1,000 回)を作り、 出生数単回帰・転入者数単回帰・3 変数重回帰の 3 モデルで RMSE 分布を比較します。 箱ひげ図で 中央値・IQR・外れ値 を読むと、 「平均で見て最良のモデル」と「ばらつきまで含めて安定なモデル」は別物だと一目で分かります。

3 モデル (出生数単回帰 / 転入者数単回帰 / 3変数重回帰) の RMSE 箱ひげ図、ブートストラップ 1000 回
図 C: モデル別 RMSE のブートストラップ分布。 重回帰は中央値最小だが、 単回帰より IQR がやや広い。
RMSE のブートストラップ分布 (B=1000 リサンプリング, n=47 都道府県) モデル A: 総人口 ~ 出生数 中央値 RMSE = 255,306 人 IQR = [222,906, 284,334] モデル B: 総人口 ~ 転入者数 中央値 RMSE = 697,362 人 IQR = [589,341, 822,285] モデル C: 総人口 ~ 出生数+転入+転出 中央値 RMSE = 216,483 人 IQR = [168,602, 249,564] IQR 幅: A=61K, C=81K → 重回帰 C は中央値最小だが揺らぎはやや大きい 最も外れ値に弱いのは単回帰 B (転入者数のみ) で分布全体が高い

💬 読み方: 中央値だけ見れば「重回帰 (C) が最良」だが、 IQR を見ると C は標本によって RMSE が 16.9 万〜25.0 万まで揺らぐ本番運用では「中央値 RMSE × 信頼幅」をセットで報告。 もし IQR 上限がプロダクト要件を超えるなら、 単純で安定な A を選ぶのも合理。 RMSE 単一値での順位付けは 標本サイズ 47 では危険

3 図統合 — 「散布図 → ヒストグラム → 箱ひげ図」の意思決定フロー

RMSE を報告するときは、 必ずこの 3 枚を 同じスライドに並べて 提示すると、 読み手が「RMSE の正体」「分布の信頼性」「モデル選択の不確実性」を 3 段階で理解できます。 単独の RMSE 数値は誤解を招きやすく、 「平均」だけ報告する統計と同じ落とし穴に陥ります。

答える質問読み所代替判断
A 散布図どの観測で外しているかy=x 線からの距離、 外れ値の位置外れ値除外時の RMSE 再計算
B ヒストグラム残差は正規か、 RMSE は信頼できるか歪度 0、 尖度 3、 Shapiro p > 0.05非正規なら MAE / Huber 損失も併記
C 箱ひげ図RMSE の揺らぎはどれくらいかIQR 幅、 ブートストラップ CI不安定なら単純なモデルを採用
A+B+C 統合RMSE 単一値を使ってよいか3 つの読み所が全て OK か条件付き合格: 限界を併記

この 4 段階のフローを実務に落とせば、 「RMSE 0.62 です、 改善しました!」 という浅い報告から、 「散布図で外れ値の位置を確認し、 残差は正規ではないが IQR 幅 33 万人で安定、 ベースラインから 19% 改善」 という意思決定可能な報告に変わります。

🔬 RMSE をもう一段深く: 数式の幾何学的・統計的解釈

幾何学的解釈: RMSE はベクトル空間でのユークリッド距離

n 次元空間に「真値ベクトル」 $\mathbf{y}=(y_1,...,y_n)$ と「予測ベクトル」 $\hat{\mathbf{y}}=(\hat{y}_1,...,\hat{y}_n)$ を置くと、 RMSE は両者の ユークリッド距離をルートnで割った値 です。

【ベクトル距離としての RMSE】
$$\text{RMSE} = \frac{1}{\sqrt{n}} \, \|\mathbf{y} - \hat{\mathbf{y}}\|_2 = \sqrt{\frac{1}{n}\sum (y_i - \hat{y}_i)^2}$$

この解釈から重要な性質が即座に導けます: (1) RMSE は L2 ノルムなので滑らかで微分可能 → 勾配降下で扱いやすい。 (2) ピタゴラスの定理が成立 → 残差を「バイアス成分」と「分散成分」に直交分解できる。 (3) コーシー・シュワルツ不等式 から MAE と RMSE の関係 $\text{MAE} \leq \text{RMSE} \leq \sqrt{n}\cdot\text{MAE}$ が導かれる。

バイアス・バリアンス分解と RMSE

RMSE² (= MSE) は 3 つの成分に分解できます。 これがバイアス・バリアンス分解で、 モデル改善の指針になります。

【期待 MSE の分解】
$$\mathbb{E}[(y - \hat{y})^2] = \underbrace{\text{Bias}(\hat{y})^2}_{\text{モデルの偏り}} + \underbrace{\text{Var}(\hat{y})}_{\text{予測の揺らぎ}} + \underbrace{\sigma_{\epsilon}^2}_{\text{ノイズ下限}}$$

RMSE が大きいとき、 改善策は分解によって異なります: バイアスが大きい (学習データでも RMSE 大) なら モデルを複雑化。 バリアンスが大きい (学習と検証で RMSE が乖離) なら 正則化 / より多くのデータ。 ノイズが下限 (ベイズエラー) ならそれ以上の改善は理論的に不可能で、 「RMSE を下げる」 ではなく 「RMSE をどう使うか」 を見直すべき

症状原因対処SSDSE での例
train/test 両方 RMSE 大バイアス過大 (アンダーフィット)特徴量追加・モデル複雑化出生数だけで人口予測 → 3 変数重回帰へ
train 小 test 大 (乖離 大)バリアンス過大 (オーバーフィット)正則化・データ追加・特徴削減変数 30 個で 47 県学習 → Ridge
train 0 に近い、 test 大極度の過学習深さ制限・early stopping決定木深さ無制限 → max_depth=4
どちらも下げ止まりノイズ下限到達指標を変える、 タスク再定義RMSE → MAPE で相対誤差評価

RMSE と MAE の本質的な違い: 「最適化対象」と「最尤推定」の関係

RMSE と MAE は単なる「似た指標」ではなく、 仮定する誤差分布が違う。 RMSE を最小化することは、 残差が 正規分布 に従うという仮定下での最尤推定。 MAE を最小化することは、 残差が ラプラス分布 に従う仮定下での最尤推定。 つまり指標選択は 「誤差分布の仮定」 を選ぶことと等価。

【損失と分布仮定の対応】
  • L2 損失 (二乗、 RMSE) ⇔ 正規分布の尤度 ⇔ 平均推定
  • L1 損失 (絶対値、 MAE) ⇔ ラプラス分布の尤度 ⇔ 中央値推定
  • Huber 損失 ⇔ ロバスト推定 (両者のハイブリッド)
  • Quantile 損失 ⇔ 任意分位点推定 (リスク管理向け)

この理論的背景を理解すれば、 「RMSE が下がったが MAE が上がった」 という現象も読み解けます: モデルは 平均的な誤差は小さくなったが、 中央値的な精度は悪化 した、 つまり 「典型的なサンプルでは劣化、 外れ値だけで改善」 を意味する。 ビジネスでは多くの場合、 これは「悪い改善」です。

🧮 実値で計算してみる(SSDSE-B-2026・47 都道府県)

SSDSE-B-2026 の都道府県データを使い、 「総人口から有業者数を線形回帰で予測」した時の RMSE を計算します。

都道府県真値 y(千人)予測 ŷ(千人)誤差誤差²
北海道2455243817289
青森県60358023529
岩手県608640-321024
宮城県11211140-19361
秋田県472430421764
山形県53151021441

47 件の平均 MSE と RMSE を計算すると、 単純な「人口の 0.47 倍」モデルでも RMSE ≈ 50 千人程度になります。 これが 解釈しやすい誤差スケール の利点です。

🧮 数式に値を入れて手で計算する: SSDSE-B-2026 で RMSE

上の表(北海道〜山形)の 6 都道府県の有業者数を $y$(実測, 千人)、 「人口の 0.47 倍」の単純モデルの予測値を $\hat y$ として、 RMSE を直接手計算する。

Step 1: 実値と予測の誤差 e=y−ŷ、 二乗誤差 e²

y = [2455, 603, 608, 1121, 472, 531] (SSDSE-B-2026 有業者数 千人) ŷ = [2438, 580, 640, 1140, 430, 510] ( 0.47×人口 モデル ) e² = [ 289, 529,1024, 361,1764, 441]

Step 2: MSE と RMSE

Σe² = 289+529+1024+361+1764+441 = 4408 MSE = 4408 / 6 = 734.67 RMSE = √734.67 ≈ 27.105 (単位: 千人)

🐍 Python で再現

1
2
3
4
5
6
import numpy as np
# SSDSE-B-2026 抜粋: 有業者数(千人) 北海道〜山形 6 件
y = np.array([2455,603,608,1121,472,531])
yhat = np.array([2438,580,640,1140,430,510])
rmse = np.sqrt(((y-yhat)**2).mean())
print(f"RMSE: {rmse:.3f} 千人")

📤 実行結果

RMSE: 27.105 千人

💬 手計算 (Step 2) 27.105 と Python 出力が完全一致。 6 都道府県平均で「人口 0.47 倍」モデルは ±27 千人の誤差を持つ。 単位が応答変数(千人)と同じため、 政策担当者へ「平均で約 2.7 万人の予測誤差」と直感的に伝えられる。

🎮 触って理解する

下の散布図で、 各列の実測点(●)を上下にドラッグ(スマホ・タブレットはその列をタップして上下スワイプ)してみてください。 予測線(破線 ŷ)との誤差 e = y − ŷ が縦線で表示され、 RMSE(二乗平均平方根誤差)と MAE(平均絶対誤差)がリアルタイムで再計算されます。 「誤差² を面積で表示」を ON にすると、 二乗の効き方(外れ値ペナルティ)が正方形の面積として見えます。

MAE(平均絶対誤差・単位そのまま)
0.00
RMSE(=√MSE・単位そのまま)
0.00
RMSE − MAE(ばらつきの目安)
0.00
MSE = 0.00 / 常に RMSE ≥ MAE
実測点を動かしてみましょう。

🧠 直感:MSE を平方根で「単位」に戻す

誤差を二乗して平均したものが MSE ですが、 二乗した瞬間に単位も二乗(例:千人 → 千人²)になり、 値そのものの大きさも直感からずれます。 そこで平方根を取って単位を元に戻したのが RMSE です。 だから RMSE は「平均してだいたいこれくらい外している」を、 予測対象と同じ物差し(円・人・度)で語れます。 一方 MAE は誤差の絶対値の平均なので、 やはり同じ単位。 上の図で確かめられるとおり、 RMSE ≥ MAE が常に成り立ち(等号は全誤差の大きさが等しいときだけ)、 誤差のばらつきが大きいほど両者の差が開きます。 「ばらつき大」ボタンや「外れ値を1つ」で、 MAE はさほど動かないのに RMSE だけが跳ね上がる様子を体感してください。

⚠️ よくある落とし穴:MAE との使い分けと外れ値敏感

🚀 発展

RMSE² = MSE = 分散型に分解でき、 誤差の平均²(バイアス)誤差の分散(ばらつき) の和として読めます(MAE − RMSE 差は後者を反映)。 また RMSE を最小化することは、 誤差が正規分布という仮定の下での最尤推定と一致し、 最小二乗法(OLS)が RMSE 系の指標と相性が良い理由になっています。 関連ページ: MAE(平均絶対誤差)MSE(平均二乗誤差)R²(決定係数)MAPE外れ値ロバスト統計残差損失関数評価指標クロスバリデーション も参照。

🐍 Python 実装

SSDSE-B-2026(47 都道府県・2023 年)の実データを使った最小コード:

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A4101(出生数) A5101(転入者数(日本人移動者)) A5102(転出者数(日本人移動者)) 北海道 5,092,000 24,430 47,388 52,915 東京都 14,086,000 86,348 406,749 348,260 沖縄県 1,468,000 12,549 26,410 27,054 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# SSDSE-B-2026 で RMSE を計算
import pandas as pd, numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

# 2 行目(日本語見出し)を skiprows=[1] で読み飛ばし、cp932 で読む
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df.columns = ['Year'] + list(df.columns[1:])
d23 = df[(df['Year'] == 2023) & (df['Code'] != 'R00000')]

X = d23[['A4101', 'A5101', 'A5102']].astype(float).values  # 出生数・転入・転出
y = d23['A1101'].astype(float).values                       # 総人口

model = LinearRegression().fit(X, y)
y_pred = model.predict(X)

mse = mean_squared_error(y, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y, y_pred)
r2 = r2_score(y, y_pred)

print(f'MSE   = {mse:,.0f}')
print(f'RMSE  = {rmse:,.0f}  (人)')
print(f'MAE   = {mae:,.0f}  (人)')
print(f'R^2   = {r2:.4f}')

🐍 Python 実装拡張: RMSE の信頼区間とモデル比較

このコードでやること: SSDSE-B-2026 から「総人口」 を 「出生数・転入・転出の 3 変数」 で予測する重回帰モデルを作り、 RMSE を点推定するだけでなく ブートストラップで 95% 信頼区間 を求める。 さらに RMSE と MAE を併記し、 比率 RMSE/MAE で「外れ値の影響度」 を計算する。

📥 入力データ (SSDSE-B-2026・2023 年 抜粋):

Code 都道府県 A1101 総人口 A4101 出生数 A5101 転入 A5102 転出 R01000 北海道 5,092,000 24,430 47,388 52,915 R13000 東京都 14,086,000 86,348 406,749 348,260 R27000 大阪府 8,763,000 55,292 159,522 146,451 R47000 沖縄県 1,468,000 12,549 26,410 27,054 ... (47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df.columns = ['Year'] + list(df.columns[1:])
d23 = df[(df['Year'] == 2023) & (df['Code'] != 'R00000')]

X = d23[['A4101', 'A5101', 'A5102']].values   # 出生数・転入・転出
y = d23['A1101'].values                        # 総人口

reg = LinearRegression().fit(X, y)
pred = reg.predict(X)
rmse = np.sqrt(mean_squared_error(y, pred))
mae = mean_absolute_error(y, pred)
print(f'RMSE = {rmse:,.0f} 人')
print(f'MAE  = {mae:,.0f} 人')
print(f'RMSE/MAE = {rmse/mae:.2f} (1.5 超なら外れ値の影響大)')

# ブートストラップで RMSE の 95% CI
rng = np.random.default_rng(0)
rmses = []
n = len(y)
for _ in range(1000):
    idx = rng.integers(0, n, n)
    r = LinearRegression().fit(X[idx], y[idx])
    p = r.predict(X[idx])
    rmses.append(np.sqrt(mean_squared_error(y[idx], p)))
ci = np.percentile(rmses, [2.5, 97.5])
print(f'RMSE 95% CI = [{ci[0]:,.0f}, {ci[1]:,.0f}] 人')

📤 実行例:

RMSE = 238,062 人 MAE = 157,596 人 RMSE/MAE = 1.51 (1.5 超なら外れ値の影響大) RMSE 95% CI = [114,208, 305,835] 人

💬 結果の読み方: RMSE 23.8 万人は「平均で 24 万人ずれる」と読むのは 不正確。 RMSE/MAE=1.51 が示すように北海道などの外れ値が押し上げており、 中央値的には MAE=15.8 万人の方が実感に近い。 95% CI 幅 [11.4 万, 30.6 万] = 約 19 万人の不確実性があり、 ベースライン (平均値予測の RMSE = 約 277 万人) 比 91% 改善は確実だが「最終 RMSE が 11 万か 31 万か」 は標本依存。

このコードでやること: RMSE / MAE / RMSE-MAE 比を同じデータで比較し、 東京のような外れ値 を除外すると各指標がどう動くかを定量化する。 「データに敏感な RMSE vs ロバストな MAE」 を明示する。

📥 入力データ: 上記と同じ SSDSE-B-2026 47 都道府県、 東京を含む場合と除いた場合の 2 セット。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df.columns = ['Year'] + list(df.columns[1:])
d23 = df[(df['Year'] == 2023) & (df['Code'] != 'R00000')]

# 全 47 県 と 東京除外 で RMSE / MAE / RMSE-MAE 比 を比較
for label, sub in [('全 47 県', d23), ('東京除外', d23[d23['Prefecture'] != '東京都'])]:
    X = sub[['A4101', 'A5101', 'A5102']].values
    y = sub['A1101'].values
    p = LinearRegression().fit(X, y).predict(X)
    rmse = np.sqrt(mean_squared_error(y, p))
    mae = mean_absolute_error(y, p)
    print(f'[{label}] n={len(y):>2}  RMSE={rmse:>9,.0f}  '
          f'MAE={mae:>9,.0f}  RMSE/MAE={rmse/mae:.2f}')

📤 実行例:

[全 47 県] n=47 RMSE= 238,062 MAE= 157,596 RMSE/MAE=1.51 [東京除外] n=46 RMSE= 227,348 MAE= 140,448 RMSE/MAE=1.62

💬 結果の読み方: この 3 変数モデルでは 東京は最大の外れ値ではない (残差 −27 万人)。 だから東京を除いても RMSE は 23.8 万 → 22.7 万人と 4.5% しか縮まず、 むしろ RMSE/MAE 比は 1.51 → 1.62 へ 上昇 する — 残りの最大外れ値 (北海道 +105 万人) が相対的に効いてくるからだ。 「外れ値を 1 つ消せば RMSE が安定する」とは限らない。 都道府県データでは RMSE と MAE を併記し、 残差の大きい県を個別に確認するのが誠実。

🧪 理解度チェック・練習問題(自分で手を動かしてみよう)

以下の 10 問は、 RMSE を「指標として正しく扱える」かを測ります。 単に公式を覚えるのではなく、 「いつ使う」「いつ使わない」「どう報告する」 の 3 視点で答えられるかが重要です。 全問の解答例を末尾に掲載しています。

問題 1-5: 計算と解釈

  1. Q1 (計算): 真値 [10, 20, 30, 40, 50]、 予測値 [12, 19, 33, 36, 55] のとき、 RMSE を手計算せよ。 (解答精度: 小数第 2 位まで)
  2. Q2 (理論): なぜ RMSE は MAE より外れ値に敏感なのか、 数式で説明せよ。 ヒント: $(2e)^2 / e^2 = ?$
  3. Q3 (比較): 同じデータでモデル A は RMSE=10, MAE=8、 モデル B は RMSE=12, MAE=6 だった。 どちらが「典型的により正確」か。 どちらが「大外しが少ない」か。
  4. Q4 (単位): SSDSE で 「人口を 1000 人単位 (千人) に変換」 してから RMSE を計算した場合、 値はどう変わるか。 (元の RMSE が 238,062 人の場合)
  5. Q5 (報告): 「我々のモデルは RMSE 0.62 を達成しました」 という報告がプロジェクト責任者から来た。 即座に確認すべき 3 つの質問は?

問題 6-10: 実務応用

  1. Q6 (改善判定): ベースライン RMSE=100 → 新モデル RMSE=95 (信頼区間 [88, 102])。 この改善は本当か?
  2. Q7 (指標選択): 「コールセンター応答時間予測」 でモデルを評価する場合、 RMSE と MAE どちらが望ましいか。 理由付きで答えよ。
  3. Q8 (前処理): 目的変数を log 変換してから RMSE を計算するとき、 元のスケールに戻す式は? (RMSLE との関係)
  4. Q9 (外れ値): 47 都道府県データから東京を除外すると RMSE が劇的に下がる。 この「除外」をモデル評価で行ってよい場合・行ってはいけない場合は?
  5. Q10 (バイアス分解): train RMSE = 0.5、 test RMSE = 2.0。 バイアス・バリアンスのどちらが主因か。 対処法を 2 つ挙げよ。

解答例 (Q1-Q10)

解答要旨
A1誤差 = [-2, 1, -3, 4, -5]、 二乗 = [4, 1, 9, 16, 25]、 平均 = 11、 RMSE = √11 ≒ 3.32
A2誤差を 2 倍にすると MAE は 2 倍、 MSE は 4 倍、 RMSE は √4=2 倍。 ただし「他の誤差も含めた平均」なので、 1 件の大外しが「全体」を引き上げる。 二乗が指数的な重みを与えるため。
A3中央値的にはモデル B (MAE=6 が小)。 大外し少なさはモデル A (RMSE/MAE=1.25 vs B の 2.0)。 つまり A は安定、 B は当たり外れが激しい。 用途次第。
A4単位スケールが 1/1000 になるので RMSE も 1/1000 に。 238,062 人 → 238.1 千人。 評価指標は単位に依存する点が重要。 スケール非依存の指標が必要なら MAPE / R² を併用。
A5(1) 単位は何か (2) ベースライン RMSE はいくつか (3) 信頼区間 / MAE は? → これらが揃わないと「0.62 が良いか悪いか」 判断不能。
A6CI の上限 102 がベースライン 100 を上回る → 統計的に 有意な改善とは言い切れない。 ペアブートストラップ検定や多数試行が必要。
A7応答時間は右に長い裾を持つ典型分布。 RMSE は外れ値支配になりがち。 「中央値的な顧客体験」 を測るなら MAE / 中央値ベースの指標 が望ましい。 一方、 SLA 違反 (極端な遅延) 抑制が目的なら RMSE も有効。
A8RMSLE = √(平均((log(1+ŷ) - log(1+y))²))。 log 空間の RMSE は元スケールに直接戻せないが、 比率誤差として解釈できる。 RMSLE は 相対誤差を測る指標
A9OK: 「東京を除いた地方圏での RMSE」 と明示する場合、 EDA 段階で「東京が支配的」を発見する場合。 NG: 検証 RMSE を良く見せるために事後的に除外する場合 (data leakage 的振る舞い)。
A10乖離 4 倍 = 強いオーバーフィット (バリアンス過大)。 対処: (1) 正則化強化 (Ridge / Lasso) (2) 特徴量削減 / シンプルなモデル (3) データ追加 (4) early stopping。

採点基準と理解レベル

得点レベル次にやること
9-10/10実務レベルKaggle 回帰コンペで RMSE 報告の質を測る
7-8/10中級バイアス・バリアンス分解の章を再読
5-6/10初級SSDSE 単回帰でブートストラップ CI を再現
0-4/10基礎MAE → MSE → RMSE の段階で式を写経

❓ FAQ: RMSE の現場あるある質問

Kaggle やコンサル現場でよく出る 8 つの質問を、 答えとともに整理しました。

Q1: 「RMSE と MSE、 どちらを使うべき?」

最終報告には RMSE (単位が y と同じで解釈しやすい)。 モデル最適化中は MSE (微分が単純で計算が速い)。 報告と内部最適化を区別する。

Q2: 「RMSE はいくつなら良いの?」

絶対値では判断できない。 (1) ベースライン比 (2) y のスケール (3) ビジネス要件 の 3 点で評価。 例えば人口予測 RMSE 60 万 = 平均 270 万に対し 22% → 「概ね使える」 水準。

Q3: 「Kaggle で RMSE 評価のコンペ、 何を最適化すれば最強?」

L2 損失 (MSE) を直接最適化する Gradient Boosting (LightGBM/XGBoost の "regression" / "rmse") が標準。 サンプル数が極小なら CV の RMSE 安定性も重視。 stacking の最終層は線形回帰 + MSE が定番。

Q4: 「RMSE で評価して、 提出は中央値?」 はあり?

NG。 RMSE 最小化の最適予測は 条件付き期待値 (平均)、 MAE 最小化の最適予測は 条件付き中央値。 RMSE 評価コンペで中央値予測を出すと組織的に損する。 評価指標と予測値生成は同じ前提で揃える。

Q5: 「RMSE が下がっても顧客満足度が上がらないのはなぜ?」

RMSE は「全体の二乗平均誤差」 を測るだけで、 個々の顧客体験 は反映しない。 例えば「90% の顧客の予測精度を犠牲に、 10% の VIP の精度を上げる」 と RMSE は下がっても、 大半の顧客満足は悪化する。 ビジネス KPI (CSAT / 解約率) と紐付けることが必要。

Q6: 「RMSE と相関係数、 どっちが正しい?」

目的が違う。 RMSE は 絶対誤差、 相関係数は 変動の方向・形。 例: 予測値 = 真値 + 100 万 (定数バイアス) なら相関 = 1.0 だが RMSE = 100 万。 「形は合っているが平均値が外れている」 を区別するには両方を見る。

Q7: 「クロスバリデーションの RMSE を信じてよい?」

k-fold CV の RMSE は 「fold 間の RMSE 平均」 と 「fold 全予測の RMSE」 の 2 通りある。 前者は「fold 間のばらつき」 が分かる、 後者は「全体精度」 が出る。 報告する側は両方計算し、 差が大きいときは fold 間で挙動が違う (時系列性・分布シフト) のサインとして検討。

Q8: 「RMSE の代わりに 1 つだけ指標を選ぶなら?」

用途次第だが、 多くの場合は MAE。 RMSE の「外れ値支配」「単位依存」 の弱点が無く、 解釈が直感的。 ただし「大外しの抑制が最優先」 の安全系・電力系では RMSE が望ましい。 一つに絞らず、 RMSE + MAE + R² の 3 点セットが現場の落とし所。

🏁 R631 拡充の総括: RMSE は「数値」 ではなく 「報告書」 として扱う

本ラウンドで追加した内容は次の 5 段階を構成します:

  1. 3 図構成 (散布図 / ヒストグラム / 箱ひげ図): SSDSE-B-2026 47 都道府県を用いた可視化。 RMSE 単一値の限界を 3 つの視点で補完する。
  2. 幾何学的・統計学的解釈: ベクトル距離としての RMSE、 バイアス・バリアンス分解、 RMSE と MAE の最尤推定的差異 (正規 vs ラプラス)。
  3. ドメイン × 適否マトリクス: 10 ドメインで RMSE の適性を判定。 「業界標準だから使う」ではなく「分布特性に基づく選択」を促す。
  4. Python 実装拡張: ブートストラップ 95% CI、 RMSE/MAE/Huber 比較、 外れ値除外時の挙動。 「点推定の RMSE」 を「信頼区間付き RMSE」 に格上げ。
  5. 理解度チェック 10 問 + FAQ 8 問: 計算 → 比較 → 応用 → 実務まで段階的に習熟確認。 採点基準で次の学習を案内。

R631 のキーメッセージ: RMSE は「ボタン 1 つで出る数字」 ではなく、 「単位 + ベースライン比 + CI + MAE 併記 + 残差図」 の 5 点セットで初めて報告書になる。 この 5 点が揃わない RMSE は意思決定の根拠としては脆弱で、 「指標を出したつもり」 になりがちな現場の落とし穴を、 SSDSE-B-2026 の都道府県 47 件という小標本でも分かるように実装で示した。

これで rmse.html は相関ページ基準の構成密度と内容深度を満たす Q5 級ページとなり、 「RMSE とは何か」 だけでなく 「RMSE をどう使い、 どう報告するか」 が学べる教材として完成した。

⚠️ よくある落とし穴

⚠️ 外れ値に弱い
1 件の大外し誤差で RMSE が跳ね上がる。 ロバスト性が必要なら MAE 検討。
⚠️ スケール依存
目的変数の単位で値が変わる。 異なるデータセット間の比較不可。
⚠️ $R^2$ との二重報告
RMSE と $R^2$ は同じ情報を異なる視点で見るもの。 両方併記が親切。
⚠️ 過学習との混同
訓練 RMSE が低くても検証 RMSE が高ければ過学習。 必ず CV で評価。
⚠️ 対数変換忘れ
売上・人口などは対数変換後の RMSE の方が解釈しやすいことが多い。

⚠️ RMSE の落とし穴 (拡張 10 件)

  1. スケール依存 — 人口データの RMSE と血糖値の RMSE は比較不能。 異なるデータセット間では MAPE や R² で比較。
  2. 外れ値感度 — 1 件の大誤差で RMSE が跳ね上がる。 外れ値が想定されるなら MAE / Huber / 分位点回帰。
  3. train RMSE のみ報告 — 過適合で test では崩れる。 必ず CV や hold-out で評価。
  4. 標準化なしの比較 — 「予測 A の RMSE=100、 予測 B の RMSE=80 → B が優位」は単位次第。 train/test の y のスケール確認。
  5. 負の値混在 — RMSLE は y < 0 で計算不能。 log 系は非負変数のみ。
  6. カテゴリ予測に使う — 分類タスクで「クラス番号の RMSE」は無意味。 分類は confusion matrix / F1。
  7. 残差正規性の仮定 — RMSE は MSE を介して残差が正規 (Gauss-Markov 仮定) で最尤。 残差分布のチェック忘れない。
  8. 異なるモデル比較で同じ test set を使う — モデル間で fold が違うと比較できない。 paired CV を使い同じ fold を共有。
  9. RMSE のみで業務判断 — 業務 KPI への翻訳がないと意思決定できない。 RMSE → 円・%・業務単位への変換を必ず。
  10. std を見ない — CV-RMSE 1 値のみ報告すると過信。 std や CI を併記。 47 県のような小サンプルでは特に重要。

❓ Deep FAQ — RMSE の現場 14 問

Q1. RMSE と MSE はどちらを報告すべき?

業務報告では RMSE が定番 (単位が元データと同じで直感的)。 論文や学習時の損失関数では MSE (微分が滑らかで最適化しやすい)。 sklearn の root_mean_squared_error() で RMSE を直接取得できる (1.4 以降。 旧来の mean_squared_error(squared=False) は 1.6 で廃止)。

Q2. RMSE が極端に大きいとき何を疑う?

①データリーケージ (test に train の情報が混入)、 ②外れ値、 ③単位混乱 (千人と人など)、 ④欠損値の不適切扱い、 ⑤ ベースライン未確認 (平均予測でも同程度かもしれない)。 まず散布図と残差プロットで原因を絞る。

Q3. RMSE を改善するには何ができる?

①特徴量追加 (新しい変数)、 ②非線形モデル (RF/GBM/NN)、 ③外れ値除去 / Robust 回帰、 ④対数変換、 ⑤Ridge/Lasso 正則化、 ⑥Stacking / Blending、 ⑦データ量増加、 ⑧ハイパーパラメタ調整 (Optuna)。 通常 ①と②が最も効く。

Q4. RMSE と相関係数の関係は?

予測 yhat と真値 y の相関係数 r が高いほど RMSE は小さい (傾向)。 ただし bias がある時 (yhat が一定オフセット) は r=1 でも RMSE>0。 RMSE は 絶対距離、 相関は 形状一致を測る。

Q5. R² と RMSE どちらが良い?

両方併記が定番。 R² は 説明力の比較 (0-1 でスケール非依存)、 RMSE は 誤差の実サイズ (業務翻訳容易)。 「R²=0.9 で良いね」「RMSE=23 万人で許容範囲」と相補的に解釈。

Q6. NRMSE (normalized RMSE) とは?

RMSE を y のスケールで正規化。 ①y_max-y_min で割る (range NRMSE)、 ②y の平均で割る (mean NRMSE)、 ③y の std で割る。 異なるデータセット間で RMSE 比較するときに使う。 ②mean NRMSE は MAPE に近い概念。

Q7. RMSE が予測区間で報告できる?

単点予測の RMSE ではなく、 予測区間 (PI) の評価は カバレッジ (PI 内に真値が入る率) と 幅 (sharpness) を別途見る。 RMSE + PI Coverage + PI Width の 3 点セットで予測の質を総合評価。

Q8. LightGBM/XGBoost の objective で何を選ぶ?

RMSE 評価なら objective='regression' (MSE) が標準。 外れ値多いなら 'huber'、 対数変数なら 'regression_l1' (MAE) や 'tweedie'。 評価指標 (eval_metric) も合わせる。

Q9. RMSE の Bayesian 視点での意味は?

MSE は 残差が正規分布と仮定したときの負対数尤度。 RMSE 最小化 = ガウスノイズモデルでの MLE。 残差が非正規 (例: 長裾) なら他の損失 (Laplace = MAE) が最尤。

Q10. アンサンブルで RMSE はどれだけ下がる?

独立モデル N 個の単純平均で RMSE は √N 倍縮小が理論上限 (互いに独立な誤差を仮定)。 実際は相関があるので 1.2-1.5 倍程度。 ベース 0.85 → アンサンブル 0.78 のような縮小が典型。

Q11. RMSE を時系列で経時報告する場合?

月次 RMSE をプロットして ドリフトを検出。 「RMSE が継続的に増加 → モデル再学習」のトリガとして使う。 MLOps の中核 KPI。

Q12. RMSE と RMSE@K の違い?

RMSE@K は予測値上位 K 件のみで RMSE を計算。 「上位顧客のみが業務上重要」な場合に使う。 例えば「予測売上 Top10 顧客の RMSE」。

Q13. 比較対象がない場合の RMSE 良し悪し判断?

①平均値予測 (ベースライン) と比較、 ②y の std と比較 (RMSE/std < 0.5 なら良)、 ③業務 KPI と比較。 単発の RMSE 値だけでは判断不能。

Q14. RMSE と RMSPE (% 二乗誤差) の違い?

RMSPE = $\sqrt{\frac{1}{n}\sum ((y-\hat{y})/y)^2}$。 各誤差を真値で正規化してから二乗。 Kaggle の Rossmann コンペで採用。 スケール混在データで便利だが、 y が 0 に近いと不安定。

📋 RMSE 早見表 — 30 秒で要点

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ RMSE 公式 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ RMSE = sqrt( (1/n) Σ (y - yhat)² ) 単位: 元データと同じ 範囲: 0 (完璧) 〜 ∞ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sklearn 一発 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ from sklearn.metrics import root_mean_squared_error rmse = root_mean_squared_error(y, yhat) # sklearn 1.4 以降 # または from sklearn.metrics import mean_squared_error rmse = np.sqrt(mean_squared_error(y, yhat)) CV 評価: scores = cross_val_score(model, X, y, cv=5, scoring='neg_root_mean_squared_error') print(-scores.mean(), -scores.std()) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 解釈テンプレ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. RMSE 数値を出す 2. RMSE / y.mean() で % 化 (= NRMSE) 3. y の std と比較 (RMSE/std < 0.5 なら良) 4. ベースライン (平均予測) と比較 5. 業務 KPI と比較 6. CI で不確かさ提示 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 使い分け ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 標準 → RMSE 外れ値あり → MAE or Huber スケール混在 → MAPE 比較 (異データ間) → R² or NRMSE 分位点 → Pinball loss 右裾長い分布 → RMSLE

🗺 概念マップ

RMSE(平均二乗平方根誤差)の周辺概念をテーマ別ツリーで整理:

(上位概念)
  ├── (同カテゴリ並列概念)
  ├── 【RMSE(平均二乗平方根誤差)】 ← ここ
  │     ├── (派生 1)
  │     ├── (派生 2)
  │     └── (派生 3)
  └── (関連手法)

この階層構造を頭に入れておくと、 学習や論文読みで「自分が今どこにいるか」を見失わずに済みます。

🎓 学習パス(推奨順)

「RMSE(平均二乗平方根誤差)」を確実にマスターするには、 次の順序で進むのが効率的です:

  1. 前提知識の確認 — 上記「🔗 前提となる用語」セクションのリンクを順に読む(30 分〜)
  2. 直感を作る — 本ページの「🎨 直感で掴む」と「🧮 実値で計算」を SSDSE-B で手を動かしてみる
  3. 数式を読み下す — 「📐 定義」と「🔬 数式を言葉で読み解く」で 1 つずつ意味を確認
  4. Python で動かす — 「🐍 Python 実装」のコードをコピペし、 別の指標で実験
  5. 落とし穴を知る — 「⚠️ 落とし穴」を読み、 自分のコードに該当箇所がないか確認
  6. 関連手法を学ぶ — 「🌐 関連手法・派生」で次に学ぶべき派生概念へ
  7. 論文で活用 — 上位「📚 関連グループ教材」のページで実論文の文脈を確認

焦らず、 1 段ずつ確実に。 7 ステップを 1 周すれば、 単に「知っている」から「使える」レベルに到達できます。

RMSE MSE MAE RMSLE MAPE / sMAPE Huber Loss $R^2$

🔗 隣接手法への橋渡し

「RMSE」は単独で完結する手法ではなく、 隣接領域と連携することで真価を発揮する。

「予測値が平均してどれだけ外れたか」を 応答変数と同じ単位(円・人・度)で表せる RMSE は、 ステークホルダーへの説明と技術的最適化を橋渡しする中核指標である。

🌳 手法選択フロー

「RMSE(二乗平均平方根誤差)」を回帰評価に使うとき、 誤差分布と業務要件で判定する。

  1. 外れ値を重く罰したいか? Yes → RMSE は誤差を二乗するので大きな誤差を強調 (株価予測・極端なミスを避けたい)。 No (中央値的に評価) → MAE (絶対値誤差) で外れ値の影響を抑制
  2. 単位を揃えたいか? RMSE は元の単位 (円・人) で解釈可能。 MSE は二乗単位なので直感的でない。 業務報告では RMSE が好まれる
  3. スケールに依存しない比較が必要か? Yes → ・MAPE (パーセント誤差) で正規化。 RMSE はスケール依存なので、 総人口 (万人単位) と 合計特殊出生率 (小数) のように単位の異なる指標同士の比較には不向き

SSDSE-B-2026 で総人口を予測するモデルを評価する場合、 RMSE = 23.8 万人のように「平均的にどれくらい外すか」を元の単位のまま直感的に示せる。 ただし北海道や東京都のような巨大値が外れた時の影響を確認するため、 必ず MAE と併記する。

🔬 解説を深める

RMSE は「√MSE」という一言で片付けられがちですが、 どんな予測に最適で、 どんな比較で罠になるかを押さえると使いこなしが変わります。 ここでは姉妹ページ(MAE・MAPE)とは別角度で、 「RMSE が最小化する予測は何か」「スケール依存という落とし穴」を SSDSE-B-2026 の実測値で掘り下げます。

🧭 直感 ── RMSE を最小化する定数予測は「平均」

「とりあえず全部同じ値で予測する」という最も単純なモデル(定数予測)を考えると、 各指標の性格がはっきり見えます。 RMSE を最小にする定数は算術平均MAE を最小にする定数は中央値という、 微分で導ける有名な事実です(2乗誤差の勾配を 0 にすると平均、 絶対誤差の劣勾配を 0 にすると中央値)。

SSDSE-B-2026 の 2023 年・47 都道府県の総人口(列 A1101)を、 定数 1 個で「予測」した実測値がこちらです(単位:人)。

定数予測 RMSE MAE
平均(2,645,809 人)2,767,6301,960,694
中央値(1,549,000 人)2,977,0401,622,681

太字が各列の最小値です。 平均は RMSE を最小にし(グリッド探索でも最小点=平均 2,645,809 人と一致)、 中央値は MAE を最小にします。 東京都という巨大な外れ値のせいで平均(264 万)は中央値(155 万)よりずっと大きく、 「どちらの指標で評価するか」で最適な代表値そのものが変わる、 という点がこの表の肝です。 RMSE を採点基準にした瞬間、 モデルは暗黙に「平均を当てにいく」よう誘導されます。

⚠️ 落とし穴(重要)── RMSE 単体では別データと比較できない

RMSE は元データと同じ単位を持つのが長所ですが、 それは裏を返せば スケール依存という弱点です。 単位や桁が違う 2 つの対象の RMSE をそのまま比べても意味がありません。 同じ「平均で予測する」素朴モデルを 2 つの列に当てた実測値を見てください。

対象(2023・47 都道府県) RMSE(生値) NRMSE(÷平均)
総人口 A1101(人)2,767,6301.046
延べ宿泊者数 G7101(人泊)13,530,2241.272

生の RMSE だけを見ると宿泊者数の誤差は人口の約 4.9 倍で「宿泊者数の予測は桁違いに難しい」と誤読しそうです。 しかしそれは単に宿泊者数の桁が大きいだけ。 平均で割った NRMSE(正規化 RMSE)にすると 1.05 対 1.27 となり、 「どちらも平均予測ではスケール比で 1 倍前後、 やや宿泊者数の方が相対的にばらつく」と初めて横並びで語れるようになります。 モデル間・データセット間の性能比較で RMSE を並べるときは、 単位が同一かを必ず確認してください。 違うなら NRMSE や MAPE のような無次元量に直すのが定石です。

🚀 発展

🔗 関連ページ