論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
MAPE
Mean Absolute Percentage Error
評価指標

🔖 キーワード索引

この用語と一緒に検索・参照されやすいタグ。 関連ページに飛ぶときの手がかりにも使えます。

#評価指標#MAPE#回帰#予測#パーセント誤差

MAPE (Mean Absolute Percentage Error、 平均絶対パーセント誤差) は予測誤差を真値で割って %で表現する指標。 単位が % なので「人口予測 MAPE 3%、 売上予測 MAPE 8%」 のように 異なるスケールの対象を横並びで比較 できる。 ただし真値が 0 や負だと分母が壊れる弱点を持つ。

MAPE平均絶対パーセント誤差スケール不変sMAPEWAPEMdAPEMASE0 割問題需要予測 KPI時系列評価

「定義 → 0 割問題 → sMAPE/WAPE への発展」が MAPE 理解の柱。

💡 30秒で分かる結論

🍰 まずはやさしく

予測のズレをパーセントで表す道具です。

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

スマホの充電の残り時間の予測などで使えます。

ここではMAPEの結論を短くまとめます。

MAPE(Mean Absolute Percentage Error)は、 予測誤差を真値に対するパーセントで表す回帰評価指標。

ここまでが要点です。 ただし実際に使う前に、 このページの「⚠️ よくある落とし穴」で挙げた 1. 真値 0 付近で爆発(症状: MAPE が ∞ や数千 % に)/2. 非対称性で過小予測を選んでしまう(症状: 学習が低い側に偏る)/3. 外れ値感度が高い(症状: 1 件の極端値で全体平均が跳ねる) には必ず目を通してください。 つまずくのは知識が無いときより、 知ってはいたが確認を飛ばしたときです。

💡 30秒で分かる結論

📍 文脈:「MAPE」はどんな場面で出てくる?

🍰 まずはやさしく

予測の正しさを測るための指標の一つです。

仕事で結果を報告するときに役立ちます。

部活の試合結果を予想して評価する時に似ています。

この用語がどんな場面で使われるかを紹介します。

本サイトの時系列予測・需要予測の章で頻出。 「経営層に説明しやすい」ので実務評価指標として根強く使われます。

この用語は一見すると単独で理解できそうに見えますが、 実際には前提となる概念(測定・尺度・サンプリングなど)と組合せて初めて意味を持ちます。 「定義を覚える」より「どんな問いに答える道具なのか」を捉えるのが効率的です。

📍 あなたが今見ているもの(文脈ボックス)

このページは MAPE (平均絶対パーセント誤差) を解説する用語ページです。
カテゴリ:回帰評価指標
ジャストインタイム型データサイエンス教育の一環として、必要な時に参照し、関連概念とともに学べる構成になっています。
基準ページ:correlation.html(149KB、12セクション、SSDSE-B 実値計算)と同等以上の品質を目指しています。

🎨 直感で掴む

🍰 まずはやさしく

ズレを割合で考える体温計のようなものです。

大きさが違うものを同じ基準で比べるために使います。

お小遣いの予算と実際の支出のズレを比べる感じです。

MAPEが直感的にどういう意味かを見ていきましょう。

MAPE (Mean Absolute Percentage Error、 平均絶対パーセント誤差) は「予測が真値から平均何 % ずれたか」を 1 数字で示す指標。 単位が % なので「人口予測の MAPE は 3%、 売上予測の MAPE は 8%」と 規模やスケールが異なる対象を横並びで比較 できる。 RMSE は「人」「円」のように単位付きで残るため、 規模の違うシリーズ同士の精度比較が難しい — その弱点を埋めるのが MAPE。

比喩: 体温計の誤差を「±0.3 度」と言うのが MAE(絶対誤差)、 「±0.8%」と言うのが MAPE。 36 度でも 38 度でも「8 %ズレ」なら相対的に同程度の精度と判断できる。 一方、 体重計の誤差を MAPE で測ると 60kg と 5kg では同じ ±0.1kg でも MAPE は 0.17% vs 2% と桁違いになり、 軽量物の精度が悪く見えるという「分母が小さい問題」 が露呈する。

💡 SSDSE-B-2026 で MAPE が「効く / 効かない」場面:人口(A1101、 1〜1400 万人)の予測誤差を MAPE で報告すると「東京は ±2%、 沖縄は ±5%」のように 規模に依らない誤差率 が並ぶ。 一方、 県別「年少人口比率」(A1301、 0.10〜0.20)のように 真値が小さい指標 で MAPE を取ると、 分母が小さいために MAPE が極端に振れる。 「真値が 0 から離れていてオーダーが揃っている」変数で使うのが鉄則。

🎮 触って理解する

青い点が実測値 y、 オレンジの点が予測値 ŷ です。 各点を上下にドラッグすると、 点ごとの絶対パーセント誤差 $\left|y-\hat{y}\right|/\left|y\right|$ と、 その平均である MAPE がリアルタイムに再計算されます(スマホでは指でそのまま動かせます)。 実測値をぐっと下(0 の近く)へ動かすと MAPE が爆発する様子、 予測を上(過大)に振ったときと下(過小)に振ったときの非対称な効き方、 そして MAPE・sMAPE が % で表されスケールに依存しない一方で MAE・RMSE は実測と同じ単位で増減する対比を体感してください。

実測値 y(青・ドラッグ可) 予測値 ŷ(オレンジ・ドラッグ可)
MAPE(%・スケール非依存)
sMAPE(対称版・上限200%)
MAE(実測と同単位)
RMSE(実測と同単位)
y 実測ŷ 予測|誤差|APE |y-ŷ|/|y|向き

※ この図の値は操作体験用のデモ値です(SSDSE-B-2026 の実測値ではありません)。計算式は本文の定義と一致します。

🎯 直感(相対誤差の平均)

MAPE は「1 点あたり平均で何 % ずれたか」を示します。 各点の縦の破線が誤差の大きさ、 それを実測値 y で割った % が APE、 その平均が MAPE です。 図の値を全体的に大きくしても小さくしても、 ずれの割合が同じなら MAPE は変わりません(スケール非依存)。 一方 MAE・RMSE は値の絶対的な大きさに比例して増減します。 だからこそ「人口予測 3%、 売上予測 8%」のように単位もスケールも違う対象を横並びに比較できるのが MAPE の強みです。

⚠️ よくある落とし穴(ゼロ割・非対称性・小値で不安定)

① ゼロ割・小値で不安定:「実測値を 0 に近づける」ボタンを押すと、 分母 $\left|y\right|$ が小さくなり APE が急騰、 y=0 では MAPE が ∞(未定義) になります。 実測値が 0 やゼロ近傍を含むデータに MAPE を使ってはいけない理由がこれです。

② 過大・過小の非対称性:「過大 vs 過小」ボタンで確認できます。 過小予測(ŷ<y)は予測が 0 まで下げても APE は最大 100% で頭打ちになりますが、 過大予測(ŷ>y)は上限がなく APE が 100% を軽く超えます。 つまり MAPE は過小予測に甘く、 過大予測に厳しい非対称な指標で、 これを最小化する学習は系統的に予測を低めに寄せる副作用を生みます。

🚀 発展(sMAPE・MASE)

上の非対称性・ゼロ割を緩和する派生指標があります。 sMAPE(対称 MAPE)は分母を $\left(\left|y\right|+\left|\hat{y}\right|\right)/2$ に置き換え、 過大・過小の扱いを対称化して上限を 200% に抑えます(図の sMAPE カードで挙動を確認できます)。 MASE(Mean Absolute Scaled Error)は誤差をナイーブ予測(前期値など)の誤差で割って基準化し、 分母がゼロになりにくくスケール非依存性も保ちます。 sMAPE・MASE は本用語集に独立ページがまだ無いため、 ここでは概念のみ紹介します。 関連指標の詳細は MAERMSEMSE評価指標 の各ページを参照してください。

📐 定義・数式

🍰 まずはやさしく

計算方法を記号で書いたルールです。

正確に誤差を計算するために使います。

テストの点数のズレを計算する時に似ています。

ここではMAPEの数式について詳しく読み解きます。

やさしい説明で掴んだ感覚を、ここで MAPE の定義 の定義式に対応づけます。下の式は左辺 $\text{MAPE}$ が何で決まるかを右辺で書き下したもので、ŷ(予測値)、Σ(合計)、分数(割り算) が現れます。それぞれの記号が何の量を指すのかは、次の「🔬 数式を言葉で読み解く」で 1 つずつ確かめてください。

【MAPE の定義】
$$ \text{MAPE} = \frac{100}{n}\sum_{i=1}^{n}\left|\frac{y_i - \hat{y}_i}{y_i}\right| $$
「相対誤差」を絶対値で平均。 単位を持たないので異なる商品・期間でも比較しやすい。
📌 読み方のコツ:数式を見たら「左辺は何を定義しているか」「右辺の各項は何の合計・積・比か」を声に出して読み下してみる。 これだけで理解が大きく進みます。

📐 数式または定義

MAPE (平均絶対パーセント誤差) の中心となる数式・定義は次の通りです。

$$ \mathrm{MAPE} = \frac{100}{n}\sum_{i=1}^{n} \left|\frac{y_i - \hat{y}_i}{y_i}\right| $$

🔬 数式を言葉で読み解く — 数式を「言葉」に翻訳

数式を眺めるだけでは身につかないので、 各記号がどんな役割を担っているかを言葉で押さえます。 「数式を音読する習慣」がつくと、 論文や教科書を読むスピードが体感で 2 倍ほど上がります。

y_i
真値
ŷ_i
予測値
n
サンプル数
%
出力単位
sMAPE
分母を (|y|+|ŷ|)/2 に変えた対称版
📚 補足:同じ記号でも分野・教科書によって意味が違うことがあります(例: $\hat{y}$ は予測値だが、 統計の文脈では推定量を意味することも)。 不明確なときは、 必ずその文書の記号定義表を確認しましょう。

🔬 数式を言葉で読み解く

🔬 MAPE の数式を言葉で読み解く・完全版

MAPE の定義式 $\text{MAPE} = \frac{100}{n}\sum_{i=1}^{n}\left|\frac{y_i - \hat{y}_i}{y_i}\right|$ は 5 要素から成る。 各要素の意味を「言葉」に翻訳することで、 公式の暗記ではなく「なぜそういう形か」が理解できる。

① 分子 $|y_i - \hat{y}_i|$ — 「絶対誤差」

予測値 $\hat{y}_i$ と実測値 $y_i$ の差の絶対値。 絶対値を取るのは「上振れも下振れも同等にペナルティ」とする意図。 「-100 と +100 を相殺させない」ためにも絶対値が必須。

② 分母 $y_i$ — 「実測値での正規化」

絶対誤差を $y_i$ で割ることで「相対誤差 = 誤差 / 実測値」になる。 結果は単位を持たない無次元量 → 異なる単位 (円・件数・温度) の予測同士でも比較可能。 これが MAPE の最大の利点。

数式を言葉で読み解くと、 「実測値 1 万円の予測誤差 500 円」と「実測値 100 円の予測誤差 50 円」を同じ尺度 (5%) で比較できる。 売上予測、 来店者数予測など 規模差が大きい時系列で特に有用。

③ 総和 $\sum_{i=1}^{n}$ — 「全データ点で集計」

テストデータの全 $n$ 件について相対誤差を合計。 これにより「個別の誤差の傾向 (overshoot vs undershoot) は隠れる」が「全体の予測精度」が要約される。

④ $\times 100$ — 「百分率化」

100 をかけることで「%」表示にする。 「予測誤差 5%」のように一般人にも直感的な数値に。 業務報告では必須の表現。

⑤ $/n$ — 「平均化」

合計を $n$ で割って平均にする。 これにより「1 件あたりの平均誤差率」となる。 データ数の異なるテストセット同士でも比較可能。

要素役割意味
$|y_i - \hat{y}_i|$絶対誤差上下方向を区別しない
$/ y_i$正規化単位なしの相対量
$\sum$集計全データ点の合計
$\times 100$百分率化人間可読の単位
$/ n$平均化サンプルサイズ非依存

🧮 実値で計算してみる

数式だけでは「実感」が湧きにくいので、 具体的な数値で 1 度手計算してみると理解が定着します。 以下の例は、 本サイトで扱う SSDSE-B-2026 や公開教材に近い形式で用意しました。

需要予測 5 件の例:

真値予測|誤差/真値|
1001100.10
2001800.10
1501650.10
80720.10
50550.10
MAPE10%

手計算で得た値と、 後述の Python 実装で算出した値が一致することを確認すると、 「数式とコードの対応関係」がクリアに見えるようになります。

🧮 実値で計算してみる(SSDSE-B-2026)

政府統計の総合窓口 e-Stat が公開する SSDSE-B-2026.csv(47都道府県×項目)を用いた具体的計算例を示します。

SSDSE-B-2026 の都道府県「総人口」(A1101) を予測モデル(線形回帰:説明変数=出生数・死亡数・転入者数・婚姻件数・住宅着工戸数)で推定。MAPE = (|誤差_1/実値_1| + ... + |誤差_47/実値_47|)/47 × 100 ≒ 3.2%。鹿児島・鳥取等一部の県で誤差%が大きくなる傾向。

項目値・指標
データ件数47 都道府県
対象指標総人口・出生数・転入者数など
計算結果上記説明参照

🧮 SSDSE-B-2026 で MAPE 完全計算実習

「都道府県人口を、 別の経済指標から線形回帰で予測」したモデルの MAPE を計算する。 加えて、 MAE、 MSE、 RMSE、 sMAPE、 MASE と比較し、 各指標の挙動の違いを定量化する。

このコードでやること: SSDSE-B-2026 で人口予測モデルを線形回帰で構築し、 複数の評価指標を計算・比較する。

📥 入力データ: SSDSE-B-2026 の県別人口 (A1101) と他の説明変数

 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
32
33
34
35
36
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import (
    mean_absolute_error, mean_squared_error,
    mean_absolute_percentage_error
)

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
pref = df[df['SSDSE-B-2026'] == 2023].copy()

y_true = pref['A1101'].astype(float).values
# 実在する 5 指標を説明変数に (出生数・死亡数・転入・婚姻・住宅着工)
num_cols = ['A4101', 'A4200', 'A5101', 'A9101', 'H1800']
X = pref[num_cols].apply(pd.to_numeric, errors='coerce').fillna(0).values

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

# 主要評価指標
mae = mean_absolute_error(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
mape = mean_absolute_percentage_error(y_true, y_pred) * 100
# 対称 MAPE
smape = np.mean(2 * np.abs(y_pred - y_true) / (np.abs(y_true) + np.abs(y_pred))) * 100
# MAE 比のスコア (Mean Absolute Scaled Error の単純版)
mae_naive = np.mean(np.abs(np.diff(y_true)))   # 1 期前 lag を予測とする naive base
mase = mae / mae_naive

print(f'MAE  (Mean Absolute Error)            = {mae:>15,.0f}')
print(f'MSE  (Mean Squared Error)             = {mse:>15,.0f}')
print(f'RMSE (Root MSE)                       = {rmse:>15,.0f}')
print(f'MAPE (Mean Absolute Percentage Error) = {mape:>15.2f} %')
print(f'sMAPE (symmetric MAPE)                = {smape:>15.2f} %')
print(f'MASE (Mean Absolute Scaled Error)     = {mase:>15.3f}')

📤 実行結果:

MAE (Mean Absolute Error) = 67,378 MSE (Mean Squared Error) = 9,475,899,877 RMSE (Root MSE) = 97,344 MAPE (Mean Absolute Percentage Error) = 3.22 % sMAPE (symmetric MAPE) = 3.21 % MASE (Mean Absolute Scaled Error) = 0.038

💬 結果の読み方: MAPE 3.22% → 平均的に「実測値の約 3% の誤差」で人口を再現できるモデル。 出生・死亡・転入・婚姻・住宅着工という人口動態と連動する変数を使ったため精度が高い。 誤差率が膨らむのは人口最小級の県で、 鳥取県で 4.5%、 最大でも鹿児島県の 11.1%。 sMAPE 3.21% は対称化してもほぼ同値。 MASE 0.038 は都道府県を並べた断面データでの参考値。

🧮 数式に値を入れて手で計算する: MAPE

合成需要予測で MAPE (%) を計算する。

Step 1: 実績と予測

iyŷ|誤差|/y
1100900.10
21501650.10
32001800.10
42502750.10
53002700.10

Step 2: MAPE

MAPE = (1/n)·Σ|y-ŷ|/y × 100 = (0.10×5)/5 × 100 = 10.0 %

🐍 Python で再現

1
2
3
4
5
import numpy as np
y = np.array([100, 150, 200, 250, 300])
yhat = np.array([90, 165, 180, 275, 270])
mape = np.abs((y - yhat)/y).mean() * 100
print(f"MAPE: {mape:.1f}%")

📤 実行結果

MAPE: 10.0%

💬 手計算 (Step 2) 10.0% と Python 出力が完全一致。

🐍 Python 実装

公的統計(SSDSE-B-2026)を題材に、 最小限の Python コードで動作させます。 ファイルパス(data/raw/SSDSE-B-2026.csv)は自分の環境に合わせて変更してください。 まずはこのまま動かすことが理解の最短ルートです。

🎯 このコードでやること:MAPE(平均絶対パーセント誤差)— 予測の相対誤差指標。 需要予測 5 件の実測値・予測値を直接与え、 定義式そのままの最小 MAPE 関数を実装して計算します。
📥 入力データ(コード内のリスト) y = [100, 200, 150, 80, 50] # 実測値 yhat = [110, 180, 165, 72, 55] # 予測値
1
2
3
4
5
6
7
8
9
import numpy as np

def mape(y, yhat):
    y, yhat = np.asarray(y), np.asarray(yhat)
    return 100 * np.mean(np.abs((y - yhat) / y))

y = [100, 200, 150, 80, 50]
yhat = [110, 180, 165, 72, 55]
print(f'MAPE = {mape(y, yhat):.2f}%')
📤 実行結果(標準出力) MAPE = 10.00%
💬 読み方:5 件それぞれの相対誤差が 10% ずつ(例: |100−110|/100 = 0.10)なので平均も 10%。 実測値が 0 付近だとこの分母が壊れて爆発するため、 ゼロ値が混じる時は sMAPE を併用する。

▶ 実行 を押せばこのページの中でそのまま動きます(ライブラリもデータも同梱済みで、 準備は要りません)。 手元の Python に移して動かすときは pip install matplotlib numpy pandas scikit-learn が必要です。 読んでいるデータは data/raw/SSDSE-B-2026.csv。 日本語を含むので encoding='cp932' の指定を落とさないでください。

本サイトの全コードは 論文一覧ページ から実例として確認できます。 自分のデータで試したい場合は、 列名・欠損記号・単位の違いだけ調整すれば、 ほぼそのまま流用できます。

👣 ステップバイステップ実例

「MAPE」を初めて使う方向けに、 ハンズオン的な実行手順を整理します。 上の Python 実装と組み合わせて、 1 度自分の手でなぞってみることを強く推奨します。

  1. 環境準備:このページのコードは ▶ 実行 ボタンでそのまま動くので、 まずは何も入れずに試す。 手元で動かしたくなったら Python 3.9 以上に pandas・scipy・matplotlib を入れ、 Jupyter Notebook か Google Colab を使うと試行錯誤しやすい。
  2. データ取得:本サイト題材の SSDSE-B-2026 を data/raw/ に配置(または自分のデータを用意)。 列名と単位を確認。
  3. 探索的に観察df.head()df.describe()df.isna().sum() で全体像を把握。 ここで欠損や外れ値の見当を付ける。
  4. 前提検証:MAPE の適用条件(実測値 y ≠ 0、 単位がパーセントとして意味を持つこと、 過小予測と過大予測の非対称性を許容できること)を、 ヒストグラムや 0 値カウントで確認。 NG なら SMAPE / MAE などへ切替。
  5. 本処理:上のコードブロックを参考に、 関数を呼び出して値を取得。 中間出力をその都度プリントして合っているか確認。
  6. 結果可視化:散布図、 棒グラフ、 ヒートマップなど、 解釈しやすい図を 1〜2 枚作る。 タイトルには結論を書く。
  7. 解釈・記録:「📝 レポートでの報告」の 5 点セットに沿って Notebook に書き残す。 後の自分のために結論・限界・次の一手を明記。
  8. 共有:Notebook を GitHub や Drive に置き、 関係者にレビュー依頼。 ピアレビューで穴が見つかることが多いので大事。

この 8 ステップを 1 度回すと、 「用語を読んで分かった気になる」段階から「実際に使える」段階に進めます。 知識は身体で覚えるのが結局のところ最速です。

🐍 MAPE 自前実装 vs sklearn 実装の比較

sklearn の mean_absolute_percentage_error は便利だが、 中身を理解するには自前実装が有益。 加えて、 sklearn 版にはいくつか「隠れた挙動」がある。

このコードでやること: 数式通りの自前 MAPE と sklearn 版の MAPE を比較し、 ゼロ除算や微小値の扱いの違いを確認する。

📥 入力データ: SSDSE-B-2026 の人口データ + 仮想ゼロ値

 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
32
33
34
35
36
37
import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_percentage_error

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
pref = df[df['SSDSE-B-2026'] == 2023].copy()
y_true = pref['A1101'].astype(float).values
y_pred = y_true * 1.05

# 自前実装 (数式通り)
def mape_naive(y_true, y_pred):
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100

# sklearn の動作確認
def mape_sklearn(y_true, y_pred):
    return mean_absolute_percentage_error(y_true, y_pred) * 100

# epsilon 安全版 (ゼロ除算回避)
def mape_safe(y_true, y_pred, eps=1e-9):
    return np.mean(np.abs((y_true - y_pred) / np.maximum(np.abs(y_true), eps))) * 100

# Case 1: 正常データ
print('Case 1 (正常):')
print(f'  naive   = {mape_naive(y_true, y_pred):.4f}')
print(f'  sklearn = {mape_sklearn(y_true, y_pred):.4f}')
print(f'  safe    = {mape_safe(y_true, y_pred):.4f}')

# Case 2: ゼロ値を含むデータ
y_true_z = np.append(y_true, [0])
y_pred_z = np.append(y_pred, [1000])
print('\nCase 2 (ゼロ含む):')
try:
    print(f'  naive   = {mape_naive(y_true_z, y_pred_z):.4f}')
except Exception as e:
    print(f'  naive   = ERROR: {e}')
print(f'  sklearn = {mape_sklearn(y_true_z, y_pred_z):.4f}')
print(f'  safe    = {mape_safe(y_true_z, y_pred_z):.4f}')

📤 実行結果:

Case 1 (正常): naive = 5.0000 sklearn = 5.0000 safe = 5.0000 Case 2 (ゼロ含む): naive = inf (ゼロ除算による発散) sklearn = 9.38e+18 (sklearn は内部で eps≈2.22e-16 で割る → 巨大数値) safe = 2.08e+12 (eps=1e-9 で 0 の APE を 1000/1e-9 として計算 → 巨大寄与)

💬 結果の読み方: 数式通りの naive は inf、 sklearn は機械イプシロン (≈2.22e-16) で割るため約 9.4e18。 eps=1e-9 の安全版でも人口スケール (百万オーダー) に対して eps が小さすぎ、 約 2.1e12 と発散気味になる。 → eps はデータのスケールに合わせて選ぶ必要があり、 ゼロ値を含むデータでは事前処理 (行除外・sMAPE 切替) が必須。 sklearn 1.4 以降はゼロ値を含む場合に警告を出す。

🏢 業務でのMAPE活用 — 実例集

小売: 売上予測

日次・週次の売上予測モデルを MAPE で評価。 在庫発注、 人員配置、 商品仕入れの意思決定の基盤。 業界水準は 10-20%。 MAPE 5% を切れば「需要予測の優位性」がビジネス価値に直結。

物流: 需要予測

荷物量、 配送ルート最適化のための予測。 MAPE が改善すれば「過剰トラック手配の削減」「ドライバー残業の削減」が即座にコストインパクトに。

エネルギー: 電力需要予測

発電計画、 燃料調達の基礎。 MAPE 3% 以下が業界標準。 0.1% の改善でも年間数億円のコスト削減。 1 時間先〜数年先まで時系列が積層。

金融: 株価・為替予測

「予測精度」のベンチマークに MAPE 使用。 ただし金融市場は予測困難で、 MAPE 20-30% でも「ランダムウォークより良い」ことを示せれば価値。

医療: 入院数予測

救急、 病床稼働率の予測。 MAPE 10-15% が実用ライン。 ベッド管理、 看護師シフトの最適化につながる。

広告: コンバージョン予測

広告配信のクリック率・コンバージョン率を MAPE で評価。 リアルタイム入札 (RTB) の精度に直結。 MAPE が改善 = ROAS (広告投資収益率) 向上。

公共: 観光客・乗客数予測

交通機関、 観光地の需要予測。 SSDSE-B-2026 のような公的データを活用。 MAPE 15-25% が標準。 季節性、 イベント効果の取り込みが鍵。

⚠️ よくある落とし穴

この用語を使うときに初学者が踏みやすい失敗パターン。 1 度経験してしまえば次から避けられますが、 先に知っておくに越したことはありません。

❌ 1. 真値 0 付近で爆発(症状: MAPE が ∞ や数千 % に)
原因: 定義 |y−ŷ|/|y| の分母 y が 0 や微小値だと値が発散する。 例えば SSDSE-B-2026 で「市町村合併直後 0 人」の年を含めると爆発。 回避: 0 を含む系列では sMAPE(対称版)や MASE(季節 naive 比)に切替え、 ゼロ行は事前に除外する。
❌ 2. 非対称性で過小予測を選んでしまう(症状: 学習が低い側に偏る)
原因: y > ŷ の最大は 100% だが y < ŷ は無限大、 つまり過小予測の方が罰金が小さい。 在庫予測で MAPE を最小化すると欠品リスクが上がる。 回避: 損失非対称な業務では Pinball loss / Quantile Regression / WAPE を使う。
❌ 3. 外れ値感度が高い(症状: 1 件の極端値で全体平均が跳ねる)
原因: 算術平均なので |y_i−ŷ_i|/|y_i| が 1 件だけ 500% でも全体に効く。 SSDSE-B-2026 で「東京」を含む県別予測で起きやすい。 回避: median APE (MdAPE) を併記、 あるいは外れ値を Winsorize(上下 1% を裾切り)してから集計する。
❌ 4. 負値・ゼロ越え系列に適用(症状: 利益・気温で意味不明な値)
原因: MAPE は |y| を仮定するので符号が変わる系列(営業損益、 気温偏差)では絶対値で割ることになり解釈不能。 回避: 絶対値スケールが固定された需要・人口・売上高のみで使い、 損益や気温には RMSE / MAE / RMSLE を使う。
❌ 5. スケール差のある系列を一括平均(症状: 大きい系列に支配される)
原因: 複数 SKU や複数都道府県を 1 つの MAPE にまとめると、 小さい系列の誤差が無視される一方、 ゼロ近傍の系列が一気に押し上げる。 回避: 系列ごとに MAPE を出してから加重平均 (WAPE) するか、 系列ランク別に層化評価する。
🛡 MAPE を採用するときの 3 条件:(1) 真値 $y_i$ が 0 から離れている(最小値 / 平均値 > 0.05 が目安)、 (2) 過小予測と過大予測のコストが 非対称でない、 (3) 同じスケールの予測対象を 横並びで比較 したい。 この 3 条件のいずれかが崩れるなら、 sMAPE / MASE / WAPE / RMSE のどれかに切替える。

⚠️ 落とし穴

⚠️ MAPE の致命的な落とし穴 — $y=0$ ゼロ除算

MAPE の最大の弱点は分母 $y_i$ の存在。 $y_i = 0$ なら計算不能 ($\infty$)、 $y_i$ が小さければ誤差率が暴走する。

具体例: 売上が 0 円の日

店舗売上予測で「日曜定休 → 売上 0 円」「予測モデル → 売上 1000 円」のとき、 個別 APE = |0 - 1000| / 0 = ∞。 これが 1 日でも入ると MAPE 全体が無限大に。

対策一覧

このコードでやること: SSDSE-B-2026 の人口データに人工的に「ゼロに近い値」を混ぜ、 MAPE と sMAPE、 WAPE の挙動を比較。

📥 入力データ: 47 県人口 + 仮想的に「人口 100 の島」を 1 件追加

 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
import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_percentage_error

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
pref = df[df['SSDSE-B-2026'] == 2023].copy()
y_true = pref['A1101'].astype(float).values
y_pred = y_true * 1.05   # 一律 5% 過大予測

# Case A: 通常データ
mape_a = mean_absolute_percentage_error(y_true, y_pred) * 100
smape_a = np.mean(2*np.abs(y_pred-y_true)/(np.abs(y_true)+np.abs(y_pred))) * 100
wape_a = np.sum(np.abs(y_true-y_pred)) / np.sum(np.abs(y_true)) * 100

# Case B: ゼロに近い値を追加
y_true_b = np.append(y_true, 100)
y_pred_b = np.append(y_pred, 1000)   # 100 を 1000 と予測 → APE = 9.0
mape_b = mean_absolute_percentage_error(y_true_b, y_pred_b) * 100
smape_b = np.mean(2*np.abs(y_pred_b-y_true_b)/(np.abs(y_true_b)+np.abs(y_pred_b))) * 100
wape_b = np.sum(np.abs(y_true_b-y_pred_b)) / np.sum(np.abs(y_true_b)) * 100

print('Case A (通常データ):')
print(f'  MAPE  = {mape_a:.2f} %')
print(f'  sMAPE = {smape_a:.2f} %')
print(f'  WAPE  = {wape_a:.2f} %')
print('Case B (人口 100 の異常値追加):')
print(f'  MAPE  = {mape_b:.2f} %')
print(f'  sMAPE = {smape_b:.2f} %')
print(f'  WAPE  = {wape_b:.2f} %')

📤 実行結果:

Case A (通常データ): MAPE = 5.00 % sMAPE = 4.88 % WAPE = 5.00 % Case B (人口 100 の異常値追加): MAPE = 23.65 % sMAPE = 8.19 % WAPE = 5.00 %

💬 結果の読み方: Case B で MAPE は約 4.7 倍に跳ね上がる (異常値 1 件で 5.00% → 23.65% と 18.65 ポイント悪化)。 sMAPE は影響を受けるが穏やか。 WAPE は変化なし → 「小さい値の影響を抑える」性質。 用途に応じて使い分けが必要。

⚖️ MAPE の非対称性 — 「過大予測 vs 過小予測」

MAPE は非対称な指標で、 「過小予測 (under-forecast) のペナルティが過大予測 (over-forecast) より大きい」性質がある。 これが業務適用時の落とし穴の一つ。

数式で見る非対称性

実測値 100、 予測 50 → APE = |100-50|/100 = 50%

実測値 100、 予測 200 → APE = |100-200|/100 = 100%

「100 ずれている」という点では同じだが、 過大予測の方が APE が大きい。 数式を言葉で読み解くと、 「分母が固定 ($y_i$) のため、 上方向は誤差が無限に大きくなれるが、 下方向は最大 100% で頭打ち」。

業務影響

このコードでやること: SSDSE-B-2026 で「+30% 過大」「-30% 過小」の 2 つの予測モデルを作り、 MAPE と sMAPE を比較。

📥 入力データ: 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
import numpy as np
import pandas as pd
from sklearn.metrics import mean_absolute_percentage_error

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
pref = df[df['SSDSE-B-2026'] == 2023].copy()
y_true = pref['A1101'].astype(float).values

y_over = y_true * 1.30   # 30% 過大予測
y_under = y_true * 0.70  # 30% 過小予測

mape_over = mean_absolute_percentage_error(y_true, y_over) * 100
mape_under = mean_absolute_percentage_error(y_true, y_under) * 100
smape_over = np.mean(2*np.abs(y_over-y_true)/(np.abs(y_true)+np.abs(y_over))) * 100
smape_under = np.mean(2*np.abs(y_under-y_true)/(np.abs(y_true)+np.abs(y_under))) * 100

print(f'30% 過大予測:')
print(f'  MAPE  = {mape_over:.2f} %')
print(f'  sMAPE = {smape_over:.2f} %')
print(f'30% 過小予測:')
print(f'  MAPE  = {mape_under:.2f} %')
print(f'  sMAPE = {smape_under:.2f} %')
print(f'\n→ MAPE は両方とも {mape_over:.0f}% (対称的に見える)')
print(f'→ sMAPE は過大 {smape_over:.2f}% vs 過小 {smape_under:.2f}% (非対称)')

📤 実行結果:

30% 過大予測: MAPE = 30.00 % sMAPE = 26.09 % 30% 過小予測: MAPE = 30.00 % sMAPE = 35.29 % → MAPE は両方とも 30% (対称的に見える) → sMAPE は過大 26.09% vs 過小 35.29% (非対称)

💬 結果の読み方: MAPE は ±30% で対称に見えるが、 実は内部で分母が $y_i$ なので「過大予測時の最大誤差は無限大、 過小予測時は 100% 上限」。 sMAPE では過小予測の方が大きく出る → 「予測モデルが体系的に保守的」かどうかを sMAPE で検出可能。

⚠️ MAPE 落とし穴 拡張版 (10 件)

  1. $y = 0$ でのゼロ除算: 計算不能 → 事前にゼロ除外、 epsilon 加算、 または sMAPE/WAPE/MASE への切替
  2. $y$ が小さい時の暴走: $y = 1$ に対し $\hat{y} = 5$ なら APE = 400%。 小さな実測値が支配的に
  3. 非対称性: 過大予測 vs 過小予測で MAPE への影響が違う。 業務リスクと整合しているか確認
  4. MAPE 最適化バイアス: MAPE を損失関数として学習すると、 体系的に過小予測になる傾向
  5. 外れ値の過大影響: 1 件の極端な APE が全体 MAPE を引き上げる。 中央値版 (MdAPE) を併用
  6. 業界横断比較の罠: 「MAPE 10%」の意味が業界によって全く違う。 業界水準を確認
  7. サンプルサイズ依存: $n$ が小さいと推定値が不安定。 信頼区間を Bootstrap で算出
  8. %表示の誤解: 「MAPE 50%」を「半分間違っている」と誤読されることあり。 詳細説明を付ける
  9. 負値・複素数: $y < 0$ の場合、 単純な MAPE は意味不明に。 絶対値版や対数版を使用
  10. クロスバリデーション時の集計: fold ごとに MAPE を計算し平均するか、 全予測を合体させて MAPE を計算するかで値が異なる

📊 MAPE 可視化 — エラー分布グラフ

MAPE は単一の数値要約だが、 個別の APE 分布を可視化することで「どの観測点で誤差が大きいか」が分かる。

このコードでやること: SSDSE-B-2026 で線形回帰人口予測の個別 APE を計算し、 ヒストグラム + 都道府県別 APE バーチャートで可視化。

📥 入力データ: 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
32
33
34
35
36
37
38
39
40
41
42
43
44
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
pref = df[df['SSDSE-B-2026'] == 2023].copy()
y_true = pref['A1101'].astype(float).values
names = pref['Prefecture'].astype(str).values

# 簡易予測モデル
num_cols = ['A4101', 'A5101', 'H1800']  # 出生数・転入・住宅着工
X = pref[num_cols].apply(pd.to_numeric, errors='coerce').fillna(0).values
y_pred = LinearRegression().fit(X, y_true).predict(X)

# 個別 APE
ape = np.abs((y_true - y_pred) / y_true) * 100
mape = ape.mean()

# 可視化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
ax1.hist(ape, bins=20, color='#00838F', edgecolor='black', alpha=0.7)
ax1.axvline(mape, color='red', linestyle='--', label=f'MAPE={mape:.2f}%')
ax1.set_xlabel('APE (%)')
ax1.set_ylabel('県数')
ax1.set_title('個別 APE のヒストグラム')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 都道府県別 APE (上位 15)
order = np.argsort(ape)[::-1][:15]
ax2.barh(names[order][::-1], ape[order][::-1], color='#FF6F00')
ax2.set_xlabel('APE (%)')
ax2.set_title('APE 上位 15 県')
ax2.grid(True, alpha=0.3, axis='x')

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

print(f'MAPE     = {mape:.2f} %')
print(f'中央APE  = {np.median(ape):.2f} %')
print(f'最大APE  = {ape.max():.2f} % ({names[ape.argmax()]})')
print(f'最小APE  = {ape.min():.2f} % ({names[ape.argmin()]})')

📤 実行結果:

MAPE = 9.65 % 中央APE = 8.14 % 最大APE = 46.36 % (沖縄県) 最小APE = 0.32 % (兵庫県)

💬 結果の読み方: MAPE 9.65% は中央値 APE 8.14% より高い → 「少数の県で大きく外している」右裾の分布。 沖縄県で 46% と突出 (離島で人口構造が本土と異なり 3 変数回帰から外れやすい) → 少数の外れ県が MAPE を押し上げる性質を実証。 中央 APE (MdAPE 8.14%) も併記すると分布全体が見える。

🎯 まとめ — MAPE マスター 7 ヶ条

  1. 「相対誤差の平均」が MAPE の本質。 単位なしで規模差ある対象を比較できる。
  2. $y = 0$ で破綻。 ゼロ値を含むデータでは sMAPE、 WAPE、 MASE を検討。
  3. 非対称性に注意。 過小予測の方が MAPE が大きく出やすい (sMAPE で確認)。
  4. 小さな $y$ で暴走。 中央値 APE (MdAPE) も併記すると分布の歪みが見える。
  5. 業界水準は対象による。 電力 1-3%、 小売 10-20%、 株価 20%以上が標準。
  6. 学習指標と評価指標を分離。 学習には MAE/MSE、 評価のみ MAPE が安全。
  7. MAPE 単独では不十分。 RMSE、 R²、 予測区間と併記して報告する。

📝 やってみよう — MAPE 5 ステップ実習

  1. Step 1: SSDSE-B-2026 を読み込み、 47 県人口を sklearn.linear_model.LinearRegression で他の指標から予測する。
  2. Step 2: sklearn.metrics.mean_absolute_percentage_error で MAPE を計算。
  3. Step 3: 自前で sMAPE、 WAPE、 MASE を実装し、 値を比較する。
  4. Step 4: 人為的に「ゼロに近い実測値」を挿入し、 各指標の挙動を観察。
  5. Step 5: matplotlib で個別 APE のヒストグラムを描画、 「分布の歪み」を確認。

5 ステップやり切ると、 「単一の % 数値が要約する情報の限界」が体感できる。 MAPE だけに頼らず、 複数指標と分布可視化で「予測モデルの全体像」を把握する習慣をつけよう。

✅ MAPE 実務チェックリスト

  1. □ データに $y = 0$ が含まれていないか確認したか
  2. □ データに $y < 0$ が含まれていないか確認したか
  3. □ 極端に小さい $y$ がないか確認したか(暴走源)
  4. □ MAPE と sMAPE の両方を計算したか
  5. □ 中央値 APE (MdAPE) も併記したか
  6. □ 個別 APE の分布をヒストグラムで確認したか
  7. □ 上位 5-10 件の高 APE 観測点を特定し、 原因を調査したか
  8. □ MAPE と RMSE/MAE を併記したか
  9. □ クロスバリデーションでの MAPE 安定性を確認したか
  10. □ 業務 KPI との対応関係を明示したか(MAPE 1% 改善 = 売上 X 円?)
  11. □ ベンチマーク(naive、 業界水準)との比較を行ったか
  12. □ 過小予測 vs 過大予測のバイアスを確認したか

📜 MAPE の歴史 — 「相対誤差」の起源

MAPE は 1980 年代の経済予測・売上予測の文脈で「異なる尺度の予測精度を比較可能にする」目的で広く使われるようになった。 単純で直感的、 業務報告に使いやすいことから、 多くの業界で標準指標として定着した。

1950s-60s: 数値解析・統計学での「相対誤差」

統計学・数値解析の教科書で「相対誤差 (relative error) = |誤差| / 真値」として登場。 MAPE は「相対誤差の平均」の自然な拡張。

1980s: 売上・需要予測での標準化

大手小売・製造業の需要予測で MAPE が標準評価指標に。 「マネジメント層への報告」に最適と評価された。

1990s-2000s: sMAPE、 MASE の登場

MAPE の弱点 (ゼロ除算、 非対称) を是正する派生指標が次々と提案。 Hyndman & Koehler (2006) "Another look at measures of forecast accuracy" が MAPE 系指標を体系的に整理。

2010s-2020s: 機械学習時代の指標選択

sklearn、 TensorFlow、 PyTorch などのライブラリが標準的に MAPE を提供。 Kaggle 等のコンペでも MAPE / sMAPE が評価指標として頻出。 一方で「MAPE 以外も検討すべき」議論が活発化。

📊 MAPE vs 他指標 — 同一データでの徹底比較

SSDSE-B-2026 で 3 つの予測モデル (Naive、 Mean、 LinearRegression) を作り、 10 種類の評価指標で比較する。

このコードでやること: 3 モデルを 10 指標で評価し、 ランキングを比較。 「どの指標を選ぶかでモデル選択が変わる」ことを実証する。

📥 入力データ: SSDSE-B-2026 の県別人口 + 説明変数

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import (
    mean_absolute_error, mean_squared_error,
    mean_absolute_percentage_error, r2_score
)

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
pref = df[df['SSDSE-B-2026'] == 2023].copy()
y_true = pref['A1101'].astype(float).values

num_cols = ['A4101', 'A5101', 'H1800']  # 出生数・転入・住宅着工
X = pref[num_cols].apply(pd.to_numeric, errors='coerce').fillna(0).values

predictions = {
    'Mean (全平均)':  np.full_like(y_true, y_true.mean()),
    'Median (中央値)': np.full_like(y_true, np.median(y_true)),
    'LR (3 var)':    LinearRegression().fit(X, y_true).predict(X),
}

def evaluate(y_true, y_pred):
    mae = mean_absolute_error(y_true, y_pred)
    rmse = np.sqrt(mean_squared_error(y_true, y_pred))
    mape = mean_absolute_percentage_error(y_true, y_pred) * 100
    smape = np.mean(2*np.abs(y_pred-y_true)/(np.abs(y_true)+np.abs(y_pred))) * 100
    wape = np.sum(np.abs(y_true-y_pred)) / np.sum(np.abs(y_true)) * 100
    median_ape = np.median(np.abs((y_true-y_pred)/y_true)) * 100
    r2 = r2_score(y_true, y_pred)
    bias = np.mean(y_pred - y_true)
    return {'MAE': mae, 'RMSE': rmse, 'MAPE': mape, 'sMAPE': smape,
            'WAPE': wape, 'MdAPE': median_ape, 'R²': r2, 'Bias': bias}

print(f'{"指標":>8} ', end='')
for name in predictions:
    print(f'{name:>16}', end=' ')
print()
print('-' * 70)

results = {name: evaluate(y_true, pred) for name, pred in predictions.items()}
for metric in ['MAE', 'RMSE', 'MAPE', 'sMAPE', 'WAPE', 'MdAPE', 'R²', 'Bias']:
    print(f'{metric:>8} ', end='')
    for name in predictions:
        val = results[name][metric]
        if abs(val) > 1e6:
            print(f'{val:>16,.0f}', end=' ')
        else:
            print(f'{val:>16,.3f}', end=' ')
    print()

📤 実行結果:

指標 Mean (全平均) Median (中央値) LR (3 var) ---------------------------------------------------------------------- MAE 1,960,694 1,622,681 184,802.267 RMSE 2,767,630 2,977,040 260,694.888 MAPE 111.102 54.339 9.652 sMAPE 70.777 55.759 9.306 WAPE 74.106 61.330 6.985 MdAPE 80.232 45.168 8.136 R² 0.000 -0.157 0.991 Bias 0.000 -1,096,809 0.000

💬 結果の読み方: すべての指標で LR が最良 → 「ロバストな結論」。 一方 Mean と Median を比べると、 MAE・MAPE・MdAPE では Median が良いのに、 RMSE では Mean が良い (大規模県=東京の二乗誤差は Mean 予測の方が小さいため)。 「指標選択がモデルの優劣を逆転させる」ことを実証。

🗺 概念マップ

MAPE を中心に、 MAE / RMSE / SMAPE / WAPE / MdAPE などの回帰評価指標を、 スケール依存性と対称性の 2 軸で整理した概念マップ。

MAPE 0割問題に注意 電力需要予測 気温予測 (1 日先) 株価予測 (短期) 小売店売上 (日次) 商品需要 (週次)

MAPE は売上予測・需要予測で標準指標。 SSDSE-B-2026 の県別人口予測なら絶対値が十分大きいため 0 割問題は発生しにくい。

🔗 隣接手法への橋渡し

MAPE (平均絶対パーセント誤差) は単独で使うのではなく、 上流の実測値 (0 を含まないこと) 整理、 並列の MAE / SMAPE / WAPE、 下流の予測精度モニタリング (KPI ダッシュボード) と組み合わせる。 売上・需要予測の業界標準指標として扱う。

SSDSE-B-2026 の県別人口予測なら、 上流で 47 県の年次データを整理し (0 含まず)、 中段で線形回帰・ARIMA・LightGBM を比較、 下流で MAPE = mean(|yi - ŷi| / |yi|) × 100 を県別 + 全体で報告、 5% 以下なら実用域と判断する。

🌳 手法選択フロー

MAPE を使うか他指標を使うかは、 (1) 実測値に 0 が含まれるか、 (2) 過小予測と過大予測を対称に扱うか、 (3) スケール非依存比較が要るか、 で判定する。 0 を含むなら MAPE は発散するので SMAPE / WAPE へ。 直前章「🔗 隣接手法への橋渡し」で示した「予測 → 精度評価 → モニタリング」パイプラインの 精度評価 段を担うのが本フロー。

[START] 回帰モデルの精度をどう測るか?
   ↓
Q1: 実測値 y に 0 や非常に小さい値があるか?
   ├ Yes (在庫切れ日・閉店日・少需要 SKU) → MAPE は分母 0 で発散 → Q2 へ
   └ No (常に正の値)                       → Q3 へ
   ↓
Q2: 0 を含むが %誤差で報告したい?
   ├ Yes → SMAPE (対称版: |y - ŷ| / ((|y| + |ŷ|)/2))
   ├ Yes + 大口顧客の影響を可視化したい → WAPE (Σ|y - ŷ| / Σ|y|)
   └ No  → MAE (絶対量) / RMSE (二乗ベース)
   ↓
Q3: スケール非依存で複数 SKU を比較したい?
   ├ Yes (商品 A: 売上 1 万円, 商品 B: 100 万円) → MAPE で %統一
   └ No (同一スケール) → MAE / RMSE で十分
   ↓
Q4: 過小予測と過大予測の扱いは?
   ├ 対称 (どちらも同じくらい嫌)         → SMAPE / MAE
   ├ 非対称 OK (在庫過剰の方が痛い)        → MAPE のままで OK
   └ 非対称 + 明示的に重み付けしたい      → Pinball Loss (分位回帰)
   ↓
Q5: 外れ値・季節性をどう扱う?
   ├ 外れ値ロバスト                       → 中央値ベース (MdAPE)
   ├ 季節性を考慮                         → MASE (季節基準で正規化)
   └ 標準運用                             → MAPE + RMSE 併記

[次段: モニタリング]
   → 週次/月次で MAPE 推移を KPI ダッシュボードに出す
   → 5% 以下: 実用域、 5-15%: 改善余地、 15% 以上: 再モデリング要

実務では MAPE と SMAPE / WAPE を必ず併記し、 さらに分位誤差 (P50/P90) を見るのが定石で、 需要が極端に少ない品目では MAPE が見かけ上肥大化する罠を避けるため WAPE をメインにする現場も多い。 SSDSE-B-2026 で県別人口を予測する場合、 全県が正の値なので MAPE が使えるが、 東京 (1409 万人) と鳥取 (54 万人) の予測誤差を均等扱いするか否かで MAPE / WAPE のどちらが「実態に近い」かが変わる。

場面主指標併記指標避けるべき
需要予測 (0 を含む)WAPESMAPEMAPE (発散)
県別人口予測MAPEMAERMSE 単独 (東京が支配)
在庫過剰回避が重要Pinball (非対称)MAPE対称な MAE
複数モデルを論文で比較MASE (季節基準)SMAPEMAPE 単独 (スケール依存)

🧭 解説深化:MAPEが「最小化する予測」は平均でも中央値でもない

このページでは既に「ゼロ除算」「非対称性(過大予測に甘い)」「小値での爆発」を詳しく扱っている。 ここでは重複を避け、 それらの根っこにある一つの事実——「MAPEを最小にする予測点は、平均でも中央値でもない特殊な位置にある」——を、 SSDSE-B-2026 の実測値だけで可視化する。 この一点を掴むと、上の3つの落とし穴が「同じ現象の別の顔」だと分かる。

🎯 直感:1/y で重み付けした「加重中央値」

RMSE を最小にする定数予測は平均、 MAE を最小にする定数予測は中央値——これは有名。 では MAPE は? 誤差 $|y_i-\hat y_i|$ を $y_i$ で割るということは、 実測値が小さい点ほど「1件あたりの重み」が大きいということ。 数学的には、MAPE を最小にする定数予測は「重み $1/y_i$ を付けた加重中央値」になる。 実測値が小さい観測ほど発言力が強いので、 最適予測は自然と小さい側へ引っ張られる。 これが「MAPEは過小予測を好む」の本当の理由である。

実データで確認(秋田県・総人口 A1101・2012〜2023 / 12年 / すべて実測)。 人口は毎年減り続けている:

秋田県 総人口(人):
 2012:1,063,000  2013:1,050,000  2014:1,037,000  2015:1,023,119
 2016:1,011,000  2017:  999,000  2018:  985,000  2019:  972,000
 2020:  959,502  2021:  945,000  2022:  930,000  2023:  914,000

この12年を「1つの定数」で言い当てるとき、指標ごとに最適な定数はズレる:

指標最適な定数予測正体
RMSE 最小990,718= 平均
MAE 最小985,000〜999,000= 中央値レンジ(中央値 992,000)
MAPE 最小985,000= 1/y 加重中央値(下端=最小側

MAPE 最小の定数 985,000 は、 平均(990,718)よりも中央値レンジの下端よりも低い。 直近ほど人口が小さく(=$1/y_i$ が大きく)、 その年の発言力が強いため、 最適予測が下側へ引っ張られたのである。 スライダーで自分の手で確かめられる:

定数予測 c = 985,000
MAPE
MAE
RMSE
各ボタンで「その指標を最小化する定数」へジャンプ。 3つが別の場所にあることを確かめよう。

⚠️ 落とし穴(重要):横断集約すると「小さい県」が支配する

上の話は時系列だけの問題ではない。 複数系列(例:47都道府県)を1つの MAPE にまとめるときにも同じ $1/y$ 重みが牙をむく。 実測で確認しよう。

架空の仮定: どの県も総人口予測が一律で +50,000 人ズレたとする(絶対誤差は全県同じ)。 実測人口(SSDSE-B-2026・2023年・47都道府県 A1101)で各県の APE を出すと:

全県平均 MAPE = 3.514 %   (絶対誤差はどの県も同じ +50,000 人なのに)
 最悪 3県: 鳥取県 9.311%(人口 537,000) / 島根県 7.692% / 高知県 7.508%
 最良 3県: 東京都 0.355%(人口14,086,000) / 神奈川県 0.542% / 大阪府 0.571%
 最悪 ÷ 最良 = 26.2 倍

誤差の中身は完全に同一(全県 +50,000 人)なのに、 MAPE で見ると鳥取県は東京都の 26倍ダメな予測に見える。 つまり全国 MAPE の平均値は「予測の良し悪し」ではなく「人口の小さい県の集まり具合」に強く支配される。 県別に人口規模が桁違いのデータを1つの MAPE で束ねると、 モデル改善のインセンティブが小さい県へ過剰に偏る。 これは時系列で見た「最適予測が下へ引っ張られる」現象の、 空間版(横断版)である。

🚀 発展:分母を替える三兄弟、そして log の視点

一言でまとめると: MAPE は「割合で見たい」という真っ当な動機の指標だが、 分母 $y_i$ が小さいほど声が大きくなるという構造上、 最適予測は下へ・集約は小規模系列へ偏る。 この偏りを制御したいなら、 分母の取り方(WAPE / sMAPE / MASE / log)を意識的に選ぶ。

🔗 関連ページ