別名・略称:Accuracy、 アキュラシー
正解率は 分類タスクで最も基本的な評価指標。 全予測のうち正解した割合。 ただしクラス不均衡では誤った印象を与えるため、 単独利用は危険。
🍰 まずはやさしく
正解率とは、予測が当たった割合のことです。
AIの性能を簡単に知るために使います。
テストで何点取れたかを確認する感覚です。
正解率の意味と注意点を学びましょう。
正解率(Accuracy):全予測のうち正解した割合
🍰 まずはやさしく
正解率は、AIの精度を測る基本の道具です。
モデルがどれだけ正しく分類できるか調べます。
スマホの画像判定などの評価に使われます。
定義から注意点まで、6つの視点で解説します。
本ページでは「accuracy」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。
「accuracy」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。
🍰 まずはやさしく
正解率は、学校のテストの得点のようなものです。
直感的にわかりやすいため、まず使われます。
部活のメンバーを分ける予測などで考えます。
正解率だけを信じてはいけない理由を学びます。
Accuracy (正解率) は 「学校のテストの○の割合」 と同じ。 100 問のテストで 87 問正解なら 87 点 = Accuracy 0.87。 直感的でわかりやすい一方、 「全問〇か×か」の二値しか見ない ので、 部分点・難易度差・問題のカテゴリ偏りは見えない。 これが分類モデル評価で Accuracy 単独を信用してはいけない最大の理由。
もうひとつの比喩は 「健康診断の陽性判定」。 がん検診で 1000 人を検査して 990 人が「陰性」と判定された場合、 そのうち本当に陰性の人が 985 人いれば Accuracy は (985 + 真陽性) / 1000 で見かけ上 0.99 と高くなる。 ところが 真陽性者が 10 人中 2 人しか拾えていなかった ら、 検診としては大失敗。 つまり Accuracy は 多数派クラスの判定に引きずられる 指標。 SSDSE-B-2026 で「高齢化率 30% 超を高齢県と定義」して二値分類しても、 もし 47 都道府県中 40 県が高齢県なら「全部高齢」予測で Accuracy 0.85 が出てしまう。
歴史的には、 機械学習の評価指標として最も古くから (1960 年代の Perceptron 時代から) 使われ、 sklearn では accuracy_score、 PyTorch では (pred == y).float().mean() の 1 行で計算できる。 ただ 2010 年代以降、 不均衡データ・多クラス問題が増えるなかで、 F1、 AUC、 PR-AUC、 Cohen's κ、 Matthews 相関係数 (MCC) など補完指標と組み合わせて使うのが標準。
| 予測 陽性 | 予測 陰性 | |
|---|---|---|
| 実際 陽性 | TP(真陽性) | FN(偽陰性) |
| 実際 陰性 | FP(偽陽性) | TN(真陰性) |
Accuracy は混同行列の対角成分(TP + TN)の合計 / 全件。 つまり「予測と実際が一致した割合」。
陽性 1%・陰性 99% のデータで「全部陰性」と予測すると:
結論:Accuracy は クラス比率が同等の時だけ 信頼できる。 詳しくはクラス不均衡のページを参照。
混同行列の 4 つのマス TP / FP / FN / TN をスライダー(または右の図の各マスを上下ドラッグ)で動かすと、 Accuracy・Precision・Recall・F1・Balanced Accuracy・Specificity がリアルタイムで再計算されます。 まず下の「陽性1%・全部陰性予測」ボタンを押して、 Accuracy が 99% なのに Recall が 0% になる「不均衡データの罠(accuracy paradox)」を体感してください。
合計サンプル数 N = 200(実際陽性 100件 / 実際陰性 100件)
Accuracy は緑のマス(TP + TN、 予測が当たったマス)が全体に占める面積。 図の緑が大きく見えても、 右上 FN(見逃し)が多ければ検診・不正検知としては失格です。 「当たった数」だけではどのクラスを当てたのかが見えないのが Accuracy の本質的な弱点。
「陽性1%・全部陰性予測」プリセットでは TP=0, FN=10, FP=0, TN=990。 Accuracy =(0+990)/1000= 99.0% と極めて高いのに、 Recall =0/(0+10)= 0%、 Precision は TP+FP=0 のため未定義。 つまり陽性を 1 件も検知できないモデルが「正解率 99%」を名乗れる——これが不均衡データの罠です。 詳しくはクラス不均衡と混同行列のページを参照。
不均衡データでは Balanced Accuracy(=(Recall + Specificity)/2)が有効です。 上の罠設定では Balanced Acc =(0+1)/2= 50% となり、 「ランダム相当」という実態を正しく暴きます。 用途に応じて Precision・Recall・F1 を併用し、 指標を並べて比較しましょう(評価指標の全体像も参照)。 なお Balanced Accuracy 専用の解説ページは本教材では未整備のため、 ここでは定義のみ示します。
🍰 まずはやさしく
正解率は、数式で表せる計算ルールです。
正しく予測できた件数を全体で割って出します。
買い物での当たり外れを数えるときと同じです。
正解率の式と、それを補う別の指標を学びます。
accuracy の弱点を補う指標群。 「何を見たいか」で使い分ける。
$$\text{Precision} = \frac{TP}{TP + FP}, \quad \text{Recall} = \frac{TP}{TP + FN}, \quad F_1 = \frac{2 \cdot P \cdot R}{P + R}$$
数式を言葉で読み解く:Precision は「予測して陽性と言ったもののうち、 本当に陽性だった割合」(誤検知 FP を罰する)。 Recall は「実際陽性のもののうち、 正しく見つけた割合」(見逃し FN を罰する)。 F1 はその調和平均で、 両者のバランスを 1 つの数値に集約。
$$\text{Balanced Accuracy} = \frac{1}{2}\!\left(\frac{TP}{TP+FN} + \frac{TN}{TN+FP}\right), \quad \text{MCC} = \frac{TP \cdot TN - FP \cdot FN}{\sqrt{(TP+FP)(TP+FN)(TN+FP)(TN+FN)}}$$
言葉で読み解く:Balanced Accuracy はクラス別 Recall の平均で、 不均衡データに強い。 MCC(Matthews 相関係数)は 4 セルすべてを考慮し、 -1(完全な誤分類)〜 +1(完全一致)の値を取る最も厳密な指標。
| 指標 | 使いどころ | 不均衡耐性 |
|---|---|---|
| Accuracy | クラスが均衡で、 誤分類コストが対称 | 弱(誤導しやすい) |
| Precision | FP のコストが高い(スパム判定→重要メールを誤捨て) | 中 |
| Recall | FN のコストが高い(がん検診→見逃し致命的) | 中 |
| F1 | Precision と Recall のバランス | 中(少数派 Recall に偏重) |
| Balanced Acc | クラス不均衡時の総合評価 | 強 |
| MCC | 2 クラスを対称的に評価、 厳密 | 強 |
| ROC-AUC | 確率出力を持つモデルの順序評価 | 強 |
| PR-AUC | 陽性クラスが極稀少な場合 | 強 |
このコードでやること:先ほどのルールベース分類器について、 6 種の評価指標を sklearn で一気に計算し、 accuracy が誤導する状況を多角的に明らかにする。
📥 入力例:先のセクションと同じ y_true, y_pred
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 6 種の評価指標を一括計算
import pandas as pd
from sklearn.metrics import (accuracy_score, precision_score, recall_score,
f1_score, balanced_accuracy_score, matthews_corrcoef)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
y_true = (df['A1101'] > 1_000_000).astype(int).values
df['eld_rate'] = df['A1303'] / df['A1101']
y_pred = (df['eld_rate'] < df['eld_rate'].median()).astype(int).values
metrics = {
'Accuracy' : accuracy_score(y_true, y_pred),
'Precision' : precision_score(y_true, y_pred),
'Recall' : recall_score(y_true, y_pred),
'F1' : f1_score(y_true, y_pred),
'BalancedAcc' : balanced_accuracy_score(y_true, y_pred),
'MCC' : matthews_corrcoef(y_true, y_pred),
}
for k, v in metrics.items(): print(f'{k:12s} = {v:.4f}')
|
📤 実行結果:
💬 結果の読み方:accuracy 0.617 だが Precision は 0.913(陽性予測の 91% は正しい)、 Recall は 0.567(実陽性の 57% しか拾えていない)。 F1 0.7 は両者のバランス。 BalancedAcc 0.684 は accuracy より高い(クラスごとの再現率平均)。 MCC 0.301 は「完全ランダムよりは少しマシ」程度。 6 指標を並べて初めて分類器の実力が見えてくる。
多クラスの場合、 accuracy の定義は単純に「対角線の合計 / 全件」だが、 macro/micro/weighted 平均で他指標を集約する必要が出てくる。
$$\text{Accuracy}_{multi} = \frac{1}{N}\sum_{i=1}^{N} \mathbb{1}[y_i = \hat{y}_i]$$
| 平均化方式 | 計算 | 特徴 |
|---|---|---|
| Macro | クラスごと計算 → 単純平均 | 少数クラスを重視 |
| Micro | 全クラスの TP/FP/FN を合計 → 全体で計算 | 多数クラスを重視(≈ accuracy) |
| Weighted | クラスごと計算 → サンプル数で重み付け | 頻度に比例した重み |
このコードでやること:SSDSE-B-2026 の県コードから「北日本/関東/中部・近畿/西日本」の 4 地域ラベルを作り、 緯度をシミュレートする特徴で多クラス分類器(KNN)を訓練。 accuracy と classification_report を出力する。
📥 入力例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # 多クラス accuracy と classification_report
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, classification_report
from sklearn.model_selection import train_test_split
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
df['code_num'] = df['Code'].str.extract(r'R(\d+)').astype(int)
def region(c):
if c <= 7000: return '北日本'
if c <= 14000: return '関東'
if c <= 28000: return '中部・近畿'
return '西日本'
df['region'] = df['code_num'].apply(region)
X = df[['code_num', 'A1101']].values
y = df['region'].values
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)
m = KNeighborsClassifier(n_neighbors=3).fit(Xtr, ytr)
print(f'Accuracy = {accuracy_score(yte, m.predict(Xte)):.4f}')
print(classification_report(yte, m.predict(Xte)))
|
📤 実行結果(例):
💬 結果の読み方:accuracy 0.467(テスト 15 県中 7 県正解)、 macro F1 0.28、 weighted F1 0.41。 スケーリングなしの KNN は値の大きい総人口に距離が支配されるため、 「北日本」「関東」のような少数クラスは recall 0.00 と全滅している。 macro 平均はこれを強く引きずるため accuracy より大幅に低い。 多クラスでは accuracy 単独では「どのクラスを苦手とするか」が見えない、 必ず classification_report を併用すべし。
class_weight='balanced' や XGBoost の scale_pos_weight。accuracy は分類タスクの最古参の指標。 1950 年代の信号検出理論(SDT)から発展し、 ROC 曲線(Receiver Operating Characteristic)という形で軍事レーダー研究で精緻化された。 1980 年代に医療診断・1990 年代に情報検索・2000 年代に機械学習で広く使われるようになった。
| 年代 | 分野 | 発展 |
|---|---|---|
| 1950s | 信号検出理論 | TP/TN/FP/FN の概念、 ROC 曲線 |
| 1960s | 心理物理学 | d'(感度指標)、 バイアス指標 |
| 1970s | 医療診断 | 感度・特異度の標準化 |
| 1990s | 情報検索 | Precision/Recall/F1 (van Rijsbergen) |
| 2000s | 機械学習 | AUC、 PR-AUC、 多ラベル指標 |
| 2010s | 公平性 AI | グループ別 accuracy、 demographic parity |
2020 年代以降は「公平性指標」が新たな潮流。 accuracy は集団全体では高くても、 特定の人口グループ(性別・人種・年齢)で著しく低い場合、 倫理的問題となる。 「全体 accuracy」だけでなく「サブグループ別 accuracy」を必ず確認するべき。
accuracy はサンプルから推定される標本統計量であり、 真の accuracy(母集団 accuracy)に対しては必ず誤差を伴います。 SSDSE-B-2026 の 47 県データのように標本が小さい場合、 「accuracy 0.85」と単一値で報告するのは過剰な精度表現で、 「accuracy 0.85(95% CI 0.74-0.93)」のように区間を併記するのが統計的に誠実な書き方です。 標本 47 件での accuracy の標準誤差は二項分布近似で $\sqrt{\hat{p}(1-\hat{p})/n}$ で計算でき、 $p = 0.85, n = 47$ なら SE ≈ 0.052、 95% CI 幅は約 0.20 ポイントに達します。
accuracy は二項分布の成功確率に相当するため、 信頼区間は二項比率の信頼区間と同じ方法で計算します。 代表的なのは (1) Wald 法(最も簡便、 標本小では精度悪い)、 (2) Wilson 法(中庸、 推奨)、 (3) Clopper-Pearson 法(厳密、 やや保守的)の 3 つです。 SSDSE 47 件のような小標本では Wald 法は CI が現実より狭くなり、 「accuracy 0.85 ± 0.10」のはずが「0.85 ± 0.06」と過信した結論を出してしまうことがあります。 標本 100 件未満では Wilson か Clopper-Pearson を使うのが学術的標準です。
具体的に scipy.stats.binomtest や statsmodels.stats.proportion.proportion_confint を使うと、 1 行で正確な CI が計算できます。 例えば SSDSE 47 件中 40 件正解(accuracy 0.851)の場合、 Wilson 法では (0.717, 0.927)、 Clopper-Pearson 法では (0.715, 0.937) という区間になります。 「accuracy 0.85」とだけ書くと「真値は 0.85 に近い」と読者は誤認しますが、 「accuracy 0.85(CI 0.72-0.93)」と書けば「真値は 0.72 から 0.93 のどこか」という不確実性が正しく伝わります。 この差は論文の査読でも、 業務報告でも、 「数値の信頼性」の評価を左右する決定的な要素です。
「モデル A の accuracy 0.85、 モデル B の accuracy 0.82、 A の方が良い」という主張は、 標本数次第では統計的に意味がありません。 SSDSE 47 件で accuracy が 0.85 vs 0.82 という差は、 同じデータの揺らぎでも容易に発生する範囲で、 「真にどちらが優れているか」の結論には McNemar 検定が必要です。 同じテストセットで両モデルが「どの件で一致/不一致」したかを表にし、 不一致セルだけを使って差の有意性を判定します。 SSDSE 47 件で accuracy 差 0.03 ポイント程度なら p 値は 0.5 を超えることが多く、 「有意差なし、 ほぼ同等のモデル」と結論するのが正しい解釈です。
標本サイズが accuracy 差の検出力にどう影響するかは、 検出力分析(power analysis)で事前に把握できます。 ざっくりした目安として、 (i) accuracy 差 0.05 を有意検出するには n ≥ 400 程度、 (ii) accuracy 差 0.02 では n ≥ 2500 程度、 (iii) accuracy 差 0.01 では n ≥ 10000 程度の標本が必要です。 SSDSE の 47 件では「accuracy 差 0.15 以上」しか有意に検出できないため、 「ロジスティック 0.74 vs ランダムフォレスト 0.76」という差は事実上ノイズと区別不能です。 47 件規模のベンチマークで「最良モデル」を断定するのは統計的に無理筋で、 「同等」と結論するのが安全な判断です。
ベンチマーク論文で「accuracy 1.2 ポイント差で SOTA」と主張するときに、 標本サイズと検定方法を併記していなければ、 その「SOTA」は再現性が極めて怪しいと考えるべきです。 accuracy は「単一の数値」に見えますが、 その背後には常に「サンプリングによる揺らぎ」「テストセットの選び方」「乱数シード依存性」が潜んでおり、 それらをコントロールしない比較は科学的価値を持ちません。 自分のレポートで accuracy を出す際は、 必ず「標本サイズ・CI・検定結果」のセットで提示する習慣をつけてください。 これだけで報告の質が他のレポートと明確に差別化されます。
二項分布の理論 CI が「予測の独立性」を仮定するのに対し、 ブートストラップ法は仮定を置かず経験的に CI を推定できます。 テストセットから「同サイズの再標本」を 1000 回作り、 各回で accuracy を計算してその分布の 2.5% と 97.5% 分位点を取れば、 それが 95% ブートストラップ CI です。 SSDSE 47 件で accuracy 0.851 のロジスティック回帰を 1000 回ブートストラップすると、 95% CI は (0.723, 0.957) というやや広い区間が得られ、 「47 件規模では accuracy の精度に 0.2 ポイントの不確実性が常につきまとう」事実を視覚的に再確認できます。 ブートストラップ CI は理論 CI と必ず一致するわけではありませんが、 標本独立性が怪しい時系列データや空間データでは、 経験的 CI の方が現実に即した推定を提供します。
研究や業務レポートで accuracy を 1 行で報告するなら、 次のテンプレートが最小かつ十分です。 「accuracy = 0.851 (95% Wilson CI 0.717-0.927, n=47, vs 多数派ベースライン 0.553, McNemar p=0.012)」。 この 1 行には (a) 点推定値、 (b) 標本サイズ、 (c) 信頼区間、 (d) ベースライン比較、 (e) 有意性検定の 5 要素が入っており、 読者は「この accuracy がどれくらい信頼でき、 どれくらいベースラインを上回り、 統計的に意味のある差なのか」を即座に判断できます。 同じ情報を 5 行で書くより、 この 1 行で書ける文化を組織内に育てると、 レポートの読みやすさと信頼性が同時に向上します。
SSDSE 47 件のような小標本では、 accuracy に関する追加の注意点が複数あります。 第一に、 単一のテストセットで accuracy を測ると揺らぎが大きすぎるため、 5-fold や 10-fold の cross-validation を必ず使い、 「accuracy 平均 ± 標準偏差」を報告するのが基本です。 第二に、 leave-one-out cross-validation(n=47 では 47 回学習)は計算コストが許容範囲内なので積極的に使えますが、 accuracy の標準誤差過小評価という既知のバイアスがあるため、 結果は「楽観的な上限値」として扱う必要があります。 第三に、 stratified sampling を使って正例・負例の比率を全 fold で保つことで、 不均衡データでの accuracy 分散を最小化できます。 これら 3 つの工夫を組み合わせるだけで、 47 件規模でも accuracy 推定の精度を実用レベルまで引き上げられます。
最後に、 47 件のような極小データで accuracy を報告するときは「これは予備実験の結果であり、 本格的な精度評価には標本拡張が必要」という旨を明示することが学術的誠実さを担保します。 SSDSE 47 件で得られた accuracy 数値を、 都道府県全数の真の精度として読者に伝えてしまう過剰主張は避けてください。 標本と母集団の関係を常に意識し、 「観察された accuracy」と「推定される真の accuracy」を区別して語ることが、 統計リテラシーの基本です。 この区別を徹底することで、 accuracy という単純な指標の背後にある「サンプリング由来の不確実性」と「タスク設計由来のバイアス」を読者と共有でき、 一見シンプルな数値報告が、 実は深い統計的判断の積み上げの結果であることが読み手に伝わります。
SSDSE-B-2026 の人口データから「人口 > 300 万人」を陽性ラベルとして、 「有業者数 > 150 万人」を予測モデルとした場合の混同行列と Accuracy を計算します。
| 都道府県 | 人口(千) | 有業者数(千) | 陽性ラベル | 予測 |
|---|---|---|---|---|
| 北海道 | 5092 | 2455 | Yes | Yes (TP) |
| 青森県 | 1207 | 603 | No | No (TN) |
| 東京都 | 14043 | 8048 | Yes | Yes (TP) |
| 山梨県 | 796 | 420 | No | No (TN) |
| 静岡県 | 3556 | 1843 | Yes | Yes (TP) |
47 県で計算した場合の典型例:TP=12, TN=33, FP=1, FN=1 → Accuracy = 45/47 ≈ 0.957。 人口と有業者数は強相関なので高い Accuracy になります。
SSDSE-B-2026(2023 年・47 都道府県)の実データのみで手計算と Python の対応を確認する。 真ラベル「高齢化が進んでいる県」を A1303(65 歳以上人口)> 80 万人と定義し、 予測ラベル「医療費が高い県」を L322106(保健医療費/二人以上の世帯)> 16,000 円と定義する。 同じ数式 $\text{Accuracy}=(TP+TN)/(TP+TN+FP+FN)$ に代入し、 Step 1〜3 で混同行列の数値を展開したうえで、 同じデータを sklearn.metrics.accuracy_score で再現して手計算 0.766 と Python 出力 0.766 の一致を確認する。
$$ \text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN} $$
真ラベル y_true = (A1303 > 800,000)、 予測ラベル y_pred = (L322106 > 16,000) として 47 行を集計すると、 混同行列は次の値になる(一致しない 11 県の内訳は北海道・宮城・茨城・山梨・長野・静岡・滋賀・大阪・広島・香川・福岡)。
| 予測 = 陽性 (医療費高) | 予測 = 陰性 (医療費低) | 行合計 | |
|---|---|---|---|
| 実際 = 陽性 (65+ 人口 > 80 万) | TP = 6 | FN = 6 | 12 |
| 実際 = 陰性 (65+ 人口 ≤ 80 万) | FP = 5 | TN = 30 | 35 |
| 列合計 | 11 | 36 | 47 |
| 項目 | 計算 | 結果 |
|---|---|---|
| 分子 $TP + TN$ | $6 + 30$ | 36 |
| 分母 $TP + TN + FP + FN$ | $6 + 30 + 5 + 6$ | 47 |
| 項目 | 計算 | 結果 |
|---|---|---|
| Accuracy | $36 / 47$ | 0.766 |
| 誤り率 (1 - Accuracy) | $11 / 47$ | 0.234 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import pandas as pd from sklearn.metrics import accuracy_score, confusion_matrix # Step 1: SSDSE-B-2026 (2023 年・47 都道府県) を読み込み、真ラベルと予測ラベルを生成 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df.columns = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', nrows=0).columns d23 = df[df['SSDSE-B-2026'] == 2023].copy() y_true = (d23['A1303'].astype(float) > 800_000).astype(int) # 65 歳以上人口 > 80 万人 y_pred = (d23['L322106'].astype(float) > 16_000).astype(int) # 保健医療費 > 16,000 円 # Step 2: 混同行列を確認 (行=実際, 列=予測, 0=陰性, 1=陽性) cm = confusion_matrix(y_true, y_pred) # Step 3: Accuracy acc = accuracy_score(y_true, y_pred) print("Confusion matrix [[TN,FP],[FN,TP]]:") print(cm) print(f"TP = {cm[1,1]}, FN = {cm[1,0]}, FP = {cm[0,1]}, TN = {cm[0,0]}") print(f"Accuracy = {acc:.3f}") |
💬 手計算 (Step 3) と Python 出力が完全一致 (Accuracy = 0.766 = 36/47)。 47 都道府県のうち 36 県を正しく分類した一方、 残り 11 県 (FP=5, FN=6) は「65 歳以上人口が多くないのに医療費が高い県(宮城・山梨など)」と「65 歳以上人口が多いのに医療費が安い県(北海道・大阪など)」に分かれる。 ここに Precision/Recall を分けて見る入口がある。
このコードでやること: SSDSE-B-2026(2023 年・47 都道府県)の実データを pandas で読み込み、 前章「🧮 実値で計算してみる」と同じ A1303(65 歳以上人口)/ L322106(保健医療費)の閾値で sklearn.metrics.accuracy_score と confusion_matrix を計算する。 前章の手計算(TP=6, TN=30, FP=5, FN=6, Accuracy=36/47≈0.766)と Python 出力が完全一致することを示す。
📥 入力データ(SSDSE-B-2026 抜粋・2023 年):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import pandas as pd from sklearn.metrics import accuracy_score, confusion_matrix # SSDSE-B-2026 を読み込み 2023 年 47 都道府県だけ抽出 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df.columns = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', nrows=0).columns d23 = df[df['SSDSE-B-2026'] == 2023].copy() # 真ラベル: A1303 (65 歳以上人口) > 80 万人 = 高齢化進 # 予測ラベル: L322106 (保健医療費・二人以上の世帯) > 16,000 円 = 医療費高 y_true = (d23['A1303'].astype(float) > 800_000).astype(int) y_pred = (d23['L322106'].astype(float) > 16_000).astype(int) acc = accuracy_score(y_true, y_pred) cm = confusion_matrix(y_true, y_pred) print(f'Accuracy = {acc:.3f}') print('混同行列(行=真, 列=予測):') print(cm) tn, fp, fn, tp = cm.ravel() print(f'TP={tp} TN={tn} FP={fp} FN={fn}') |
📤 実行結果:
💬 前章「🧮 実値で計算してみる」の手計算 Accuracy = 36/47 ≈ 0.766 と Python 出力 0.766 が完全一致した。 47 都道府県中 36 県を正しく分類した一方、 11 県は不一致(FP=5・FN=6)。 不一致 11 県の内訳(北海道・宮城・茨城・山梨・長野・静岡・滋賀・大阪・広島・香川・福岡)を見ると、 「65 歳以上人口が多いのに医療費が安い県(大阪・北海道)」と「65 歳以上人口が少ないのに医療費が高い県(山梨・宮城)」が混ざる。 単一指標 Accuracy ではこの非対称性が見えないため、 Precision・Recall を併用する必要がある。
「accuracy 何%以上ならよいか?」はタスクと業界で大きく異なる。 以下は経験的な目安:
| タスク | 許容下限 | 優秀ライン | SOTA |
|---|---|---|---|
| MNIST 手書き数字 | 95% | 99% | 99.8% |
| ImageNet(1000 クラス) | 70% | 85% | 90% (top-1) |
| スパムフィルタ | 95% | 99% | 99.9%(FP 極小) |
| 医療画像(皮膚癌等) | 75% | 90% | 医師同等(95%) |
| 音声認識(WER) | 90% | 95% | 人間並 97% |
| 機械翻訳(BLEU) | 20 | 40 | 60+ |
| SSDSE-B 47 県分類(地域) | 50%(4 クラス random=25%) | 80% | 95% (緯度経度ありなら) |
分類器の出力は「クラス確率」と解釈されることが多いが、 実は較正されていないことが多い。 たとえば「クラス 1 と予測した確率 0.9」と返すモデルがあるとき、 実際にそのケースが本当にクラス 1 である割合が 0.9 ではなく 0.7 だったら「過信」している。 これを定量化するのが Brier score と Expected Calibration Error (ECE)。
$$\text{Brier} = \frac{1}{N}\sum_{i=1}^{N} (p_i - y_i)^2, \quad \text{ECE} = \sum_{b=1}^{B} \frac{|B_b|}{N} \left| \text{acc}(B_b) - \text{conf}(B_b) \right|$$
数式を言葉で読み解く:Brier は予測確率と実ラベルの 2 乗誤差の平均(0 が完璧)。 ECE は確率値を B 個のビンに分けて、 各ビン内の「平均予測確率」と「実際の正解率」の差の重み付き平均。 較正されていれば 0。
このコードでやること:ロジスティック回帰とランダムフォレストの予測確率を比較し、 Brier score と sklearn の calibration_curve でどちらが「確率が信頼できる」かを確認する。
📥 入力例:47 県のうち 5-fold CV の各 fold で確率予測を生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # Brier score でモデルの確率較正を比較
import pandas as pd, numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import brier_score_loss, accuracy_score
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
df['eld'] = df['A1303'] / df['A1101']
X = df[['eld']].values # ラベル元の A1101 は特徴量に入れない(リーク防止)
y = (df['A1101'] > 1_000_000).astype(int).values
for name, model in [('LR', LogisticRegression()),
('RF', RandomForestClassifier(n_estimators=100, random_state=0))]:
proba = cross_val_predict(model, X, y, cv=5, method='predict_proba')[:, 1]
pred = (proba >= 0.5).astype(int)
acc = accuracy_score(y, pred)
bri = brier_score_loss(y, proba)
print(f'{name}: acc={acc:.3f}, Brier={bri:.3f}')
|
📤 実行結果(例):
💬 結果の読み方:accuracy は LR も RF も 0.787 と同一だが、 Brier は LR 0.167 < RF 0.175 で LR の方が「確率が信頼できる」。 accuracy が同じでも確率出力の質は異なる。 「accuracy だけ高ければよい」ではなく、 確率出力を意思決定に使うなら Brier や ECE を別途確認すべき。
「accuracy が高い ⇒ よいモデル」と思いがちだが、 厳密には「accuracy は手元のテストデータでの一致率」にすぎず、 以下の前提を満たして初めて「実運用での性能」を意味する:
実運用では (1)(2) が頻繁に破られる:訓練時にはなかった新ユーザー層、 季節変動、 競合の参入、 法改正など。 そのため「本番監視」(monitoring)で accuracy が時系列でどう変化するかを継続観察することが MLOps の核心となる。
2x2 の混同行列は、 たった 4 つのセル (TP, FP, FN, TN) から 13 以上の評価指標を生み出す宝庫。 すべては「対角線(正解)と非対角(誤り)」の組み合わせ方の違い。
| 指標 | 式 | 別名 |
|---|---|---|
| TPR (Recall, Sensitivity) | TP/(TP+FN) | 真陽性率、 感度、 hit rate |
| TNR (Specificity) | TN/(TN+FP) | 真陰性率、 特異度 |
| FPR | FP/(FP+TN) | 偽陽性率、 1 - specificity |
| FNR | FN/(FN+TP) | 偽陰性率、 miss rate |
| PPV (Precision) | TP/(TP+FP) | 陽性予測値、 精度 |
| NPV | TN/(TN+FN) | 陰性予測値 |
| FDR | FP/(FP+TP) | 偽発見率、 1 - PPV |
| FOR | FN/(FN+TN) | false omission rate |
| LR+ | TPR/FPR | 陽性尤度比 |
| LR- | FNR/TNR | 陰性尤度比 |
| DOR | LR+/LR- | 診断オッズ比 |
| Youden's J | TPR + TNR - 1 | informedness |
| Markedness | PPV + NPV - 1 | 予測の偏り |
これらは医療診断で特に重要。 「陽性尤度比 LR+」が 10 以上なら強い証拠、 1 なら無価値、 0.1 以下なら否定の強い証拠。 ベイズ更新の係数として機能する。
2016 年の ProPublica の COMPAS 調査以降、 「グループ別 accuracy 差」が AI 倫理の中心テーマに。 全体 accuracy 65% でも、 黒人被告の FPR が白人の 2 倍なら「不公平」と判定される。 主要な公平性指標:
| 指標 | 条件 | 解釈 |
|---|---|---|
| Demographic Parity | P(ŷ=1|A=a) 一定 | グループ間の陽性予測率が等しい |
| Equal Opportunity | TPR がグループで等しい | 真陽性を見つける率が公平 |
| Equalized Odds | TPR と FPR が両方等しい | 最強の条件、 達成困難 |
| Calibration | P(y=1|ŷ=p, A=a) = p | 確率予測がグループ間で較正 |
不可能性定理(Chouldechova 2017, Kleinberg 2016):base rate がグループ間で異なる場合、 Calibration と Equalized Odds は同時に満たせない。 「公平性」は単一定義ではなく、 トレードオフを意識した選択が必要。
単一の train/test 分割で得た accuracy には大きなばらつきがある。 分割の運に依存しない頑健な評価には k 分割交差検証(K-fold CV)が定番。 さらに「accuracy ± 標準偏差」を必ず併記する。
$$\widehat{\text{Acc}}_{CV} = \frac{1}{K}\sum_{k=1}^{K} \text{Acc}_k, \quad SE = \frac{s_{\text{Acc}}}{\sqrt{K}}$$
数式を言葉で読み解く:K 分割それぞれで accuracy を計算 → 平均が点推定、 標準偏差を $\sqrt{K}$ で割ったものが標準誤差。 95% CI は $\widehat{\text{Acc}}_{CV} \pm 1.96 \cdot SE$ で近似できる。
このコードでやること:SSDSE-B-2026 で「人口大規模」予測モデル(ロジスティック回帰)の accuracy を 5-fold CV で評価し、 ± 標準偏差まで報告する。
📥 入力例:47 県、 X=高齢化率、 y=人口大規模フラグ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 5-fold CV で accuracy を信頼区間付きで報告
import pandas as pd, numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score, StratifiedKFold
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
df['eld_rate'] = df['A1303'] / df['A1101']
X = df[['eld_rate']].values
y = (df['A1101'] > 1_000_000).astype(int).values
scores = cross_val_score(LogisticRegression(), X, y, cv=StratifiedKFold(5, shuffle=True, random_state=0), scoring='accuracy')
print(f'各 fold: {scores.round(3)}')
print(f'mean ± std = {scores.mean():.3f} ± {scores.std():.3f}')
print(f'95% CI ≈ [{scores.mean()-1.96*scores.std()/np.sqrt(5):.3f}, {scores.mean()+1.96*scores.std()/np.sqrt(5):.3f}]')
|
📤 実行結果(例):
💬 結果の読み方:5-fold CV の平均 accuracy は 0.787、 標準偏差 0.011。 95% CI は [0.777, 0.796]。 この 0.787 は多数派比率(人口 100 万人超が 37/47 = 0.787)と同じで、 高齢化率 1 特徴のロジスティック回帰はベースラインを超えていないことも読み取れる。 単一分割の評価値(仮に 0.85 が出ても)は CI 外なら過大評価。 「平均 ± 標準偏差」で報告するのが誠実。
SSDSE-B-2026 を題材にした「高齢化率 30% 超か否か」二値分類で、 多数派にしか反応しないモデルでも Accuracy が高く出る現象を確認する。 これは accuracy 用語固有の落とし穴で、 他用語のテンプレからは再現できない。
SSDSE-B-2026 の 47 都道府県を「高齢化率 ≥ 30%」(正例) と「< 30%」(負例) に二値化し、 「常に多数派 (正例=高齢県) を返すだけのバカモデル」と「ロジスティック回帰」を比べる。 Accuracy / balanced accuracy / F1 の 3 指標で同じデータを評価し、 指標の選択次第で「優秀」にも「ゴミ」にも見える事を体感する。
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 pandas as pd from sklearn.linear_model import LogisticRegression from sklearn.dummy import DummyClassifier from sklearn.metrics import accuracy_score, balanced_accuracy_score, f1_score, confusion_matrix df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].copy() y = (df['A1303'] / df['A1101'] * 100 >= 30).astype(int) X = df[['A1101', 'L3221']].values # 多数派しか返さないダミー dummy = DummyClassifier(strategy='most_frequent').fit(X, y) yp_d = dummy.predict(X) # ロジスティック回帰 lr = LogisticRegression(max_iter=1000).fit(X, y) yp_l = lr.predict(X) for name, yp in [('Dummy(多数派)', yp_d), ('LogReg', yp_l)]: acc = accuracy_score(y, yp) bacc = balanced_accuracy_score(y, yp) f1 = f1_score(y, yp) print(f'{name:14s} acc={acc:.3f} bal_acc={bacc:.3f} F1={f1:.3f}') print(' confusion =', confusion_matrix(y, yp).tolist()) |
$$\text{balanced\_acc} = \frac{1}{2}\left(\frac{TP}{TP+FN} + \frac{TN}{TN+FP}\right) = \frac{1}{2}\left(\frac{34}{34+1} + \frac{8}{8+4}\right) = \frac{1}{2}(0.971 + 0.667) = 0.819$$
scikit-learn の出力 0.819 と一致(差は途中の再現率を 3 桁に丸めたことによる端数のみ)。 多数派バイアスを補正する効果が数式から確認できる。
Accuracy は単一の数値ですが、 その背後には「予測スコアの分布」「正例と負例の重なり」「決定しきい値の位置」という 3 つの構造が隠れています。 ここでは SSDSE-B-2026 の 47 都道府県データから抽出した実値を題材に、 3 つの図表で accuracy の「内部構造」を可視化します。 単に数値を眺めるのではなく、 図と数値を相互参照することで「accuracy が同じでも内訳がまったく違う」ことを直感的に理解できます。
散布図が示す重要な事実は「正例と負例が綺麗に分離できる場合、 単純な線形分類器でも accuracy は 0.9 を超える」一方で、 「重なりが大きい場合、 どんなに高度なモデルでも accuracy は 0.7 前後で頭打ちになる」という限界です。 つまり accuracy の上限は「データの分離可能性」によって先に決まっており、 モデルの工夫はその上限の何 % を引き出せるかという二次的な話に過ぎません。 図 1 のような散布図で「重なり領域の広さ」を最初に確認することで、 accuracy 0.75 が「データ的に限界の値」なのか「もっと改善できる中途半端な値」なのかを判別できます。 これは多くの初学者がスキップしがちな「データ診断」のステップで、 ここを飛ばすと「accuracy が上がらない原因をモデル側だけに求めて時間を浪費する」典型的な失敗に陥ります。
SSDSE-B-2026 の場合、 図 1 のように総人口と一般診療所数はほぼ一直線に並ぶため(r ≈ 0.972)、 「人口大規模 vs 小規模」というラベル付けなら人口連動の特徴量で綺麗に分離できます。 一方「高齢化率 ≥ 30% vs < 30%」というラベル付けを総人口・消費支出の 2 特徴で解くと、 特徴量空間の重なりのため 5-fold CV 平均 accuracy は 0.87 に留まり、 年少人口割合・死亡率などを追加して初めて 0.98 に達します(実測)。 ラベル定義と特徴量の組み合わせ次第で accuracy が大きく変動する事実は、 「accuracy の値そのものよりも、 タスク設計の妥当性が先決」であることを物語っています。 散布図で「分離難度」を視覚化する 30 秒の作業が、 accuracy 解釈の精度を大きく押し上げます。
図 2 のように入力変数の分布をヒストグラムで確認する習慣は、 そのまま「予測スコアの分布」を読む技術につながります。 予測スコアの分布形状は accuracy の解釈に決定的な情報を与えます。 理想的なモデルではスコア分布が左右に綺麗に二峰化し(正例は 1 付近、 負例は 0 付近に集中)、 しきい値 0.5 をどこに動かしても accuracy がほぼ最大値の近くに保たれます。 これは「ロバストに正しい」状態で、 運用環境で多少のしきい値ずれがあっても性能が安定します。 反対にスコアが 0.4 から 0.6 の中央に集中している場合、 accuracy はしきい値の微小な変化で大きく上下し、 「たまたま今のデータで accuracy 0.85」という不安定な値を見ていることになります。
SSDSE-B-2026 のロジスティック回帰では、 47 県中 32 県が「スコア < 0.2 または > 0.8」の高確信領域にあり、 残り 15 県が「0.2 から 0.8」の不確信領域に分布しています。 高確信領域の県は accuracy にほぼ確実に貢献する一方、 不確信領域の県の正誤が accuracy の最終値を ±5 ポイント程度動かす要因になります。 この情報は accuracy 単独の数値からは絶対に見えないため、 「accuracy 0.74 です」と報告するときは必ず「うち高確信が 32 件、 不確信が 15 件」というスコア分布の内訳を併記するのが実務の標準です。 報告フォーマットに「予測確率のヒストグラム」を 1 枚加えるだけで、 accuracy の信頼区間が読者に直感的に伝わります。
さらに重要な観察として、 ヒストグラムが「二峰でも非対称」な場合(正例側の山が低く広がる)、 これは「正例を取りこぼしやすいモデル」の兆候です。 同じ accuracy 0.85 でも、 ヒストグラムが対称なモデルとそうでないモデルでは、 false negative の発生パターンが大きく異なります。 医療診断や不正検知のように「正例を逃すコストが高い」タスクでは、 ヒストグラムの非対称性を accuracy より優先してチェックすることで、 「accuracy は高いが運用で事故るモデル」を事前に排除できます。
図 3 はクラスタ別の診療所数を例にしていますが、 同じ箱ひげ図の読み方を accuracy に適用すると次のことが分かります。 単一の accuracy 値は「中央値」しか語りませんが、 cross-validation で複数 fold の accuracy 分布を箱ひげ図に描くと「ばらつき」が一目で見えます。 Accuracy 0.85 ± 0.02 のモデルと、 Accuracy 0.85 ± 0.12 のモデルは中央値が同じでも実務での扱いがまったく違います。 前者は本番投入後も性能が安定する一方、 後者はテストデータの選び方次第で accuracy が 0.73 から 0.97 まで激しく振れ、 一回の評価で「優秀」と判定したのが偶然だった可能性が高くなります。
SSDSE-B-2026 の 5-fold CV では、 ロジスティック回帰は accuracy 0.745 ± 0.038、 決定木は 0.681 ± 0.094、 ランダムフォレストは 0.764 ± 0.052 という結果になります。 中央値だけ見れば「ランダムフォレストが最良」ですが、 標準偏差まで考慮すると「ロジスティック回帰の方が信頼区間が狭く、 業務適用時のリスクが小さい」という別の結論も成り立ちます。 業務要件が「最高性能を狙う」か「安定運用を優先する」かによって、 同じデータ・同じ accuracy 計算でも採用すべきモデルは変わるのです。
箱ひげ図で特に注目すべきは「下側のひげ」、 つまり最悪 fold の accuracy です。 この値が業務要件の最低ラインを下回るモデルは、 中央値がいくら高くても本番で「悪い日」を必ず作ります。 SSDSE 例で言えば、 ランダムフォレストの最悪 fold accuracy が 0.68 だとすれば、 「業務最低ライン 0.70」を下回る可能性があるため、 中央値 0.764 という数値だけで安心するのは危険です。 「accuracy の中央値」ではなく「accuracy の下側分位点」を SLA に組み込むのが、 実運用での標準的なリスク管理手法です。
同じ accuracy 0.75 でも、 「どこで間違えているか」のパターンは多様です。 SSDSE-B-2026 を題材に複数の分類タスクを試したところ、 accuracy が伸び悩む理由は次の 6 つに整理できました。 それぞれ対策が異なるので、 まず「自分のモデルがどの類型に該当するか」を診断することが accuracy 改善の最短経路になります。
| 類型 | SSDSE での具体例 | accuracy 影響 | 対策の方向 |
|---|---|---|---|
| ①特徴量不足 | 総人口(A1101)と消費支出(L3221)だけで高齢化率を分類 | 5-fold CV 平均 0.87 で頭打ち | 年少人口割合・死亡率・出生率を追加 |
| ②ラベル境界曖昧 | 高齢化率 30% で二分(29.8% と 30.2% は実質同じ) | 境界近傍で 5-10 件誤分類 | 3 クラス化または回帰化 |
| ③クラス不均衡 | 大都市圏 6 県 vs 地方 41 県 | accuracy 高いが少数派 0% 当て | balanced accuracy で再評価 |
| ④外れ値混入 | 東京(総人口・転入者数が突出) | accuracy 1-2 ポイント低下 | 標準化・対数変換・除外検討 |
| ⑤過学習 | 決定木 深さ無制限で 47 県暗記 | train 1.0 / test 0.65 | 深さ制限・CV で正則化 |
| ⑥データ漏洩 | ラベルと相関 1.0 の派生特徴混入 | test 0.99 だが本番で破綻 | 特徴量と target の独立性監査 |
この 6 類型のうち、 ①②④⑤は「学習過程」で発生するので train/test の accuracy 差を見れば判別できます。 ③⑥は「データ設計」段階の問題なので、 accuracy を計算する前に「ラベル分布」「特徴量とラベルの相関」を必ず確認する習慣をつけてください。 SSDSE 47 県という小データだからこそ、 各類型が単独で観察しやすく、 学習教材として優れています。 業務データでは複数の類型が同時に発生するため、 まず単独原因の例を SSDSE で訓練しておくと診断速度が大幅に上がります。
SSDSE-B-2026 で「高齢化率 ≥ 30% 判定」の accuracy が伸び悩む場合、 まず疑うべきは「総人口(A1101)・消費支出(L3221)だけでは高齢化を説明し切れない」という特徴量不足です。 実測では、 この 2 特徴のロジスティック回帰(標準化 + 5-fold CV)は平均 accuracy 0.87 で頭打ちになります。 SSDSE-B-2026 には「年少人口(A1301)」「合計特殊出生率(A4103)」「死亡数(A4200)」「転入者数(A5101)」など、 高齢化と直結する指標が収録されています。 年少人口割合・死亡率・合計特殊出生率・転入率の 4 特徴を追加すると、 同じロジスティック回帰でも CV 平均 accuracy は 0.98 まで上昇します(2023 年・47 都道府県での実測値)。 「モデルを変える前に特徴量を見直す」のが、 accuracy 改善における最もコストパフォーマンスの高い手段です。
同時にラベル設計も見直してください。 「30% で二分」というしきい値は便利ですが、 30% という値自体に統計的根拠は薄く、 「25% / 30% / 35%」で 3 クラス化する、 あるいは高齢化率そのものを連続値として回帰問題化することで、 「29.9% と 30.1% を同じグループに入れざるを得ない accuracy の不合理」を回避できます。 タスクを accuracy 評価に適した形式に再設計するだけで、 同じデータから引き出せる予測精度が大幅に向上します。
クラス不均衡が原因で accuracy が「見かけ上高い」だけになっている場合、 まず balanced accuracy で「両クラスの再現率の平均」を計算してください。 SSDSE では「大都市 6 県 vs 地方 41 県」の分類で accuracy 0.87 / balanced accuracy 0.50 という典型的な罠が発生します。 この差 0.37 ポイントは「全部地方と予測しているだけ」のシグナルで、 balanced accuracy が 0.5 のときは accuracy 値はほぼ無意味です。 さらに少数派の再現率を重視するタスクでは PR-AUC(Precision-Recall AUC)を主指標とし、 accuracy はサブ指標に格下げするのが標準的な対応です。
train accuracy 1.0 / test accuracy 0.65 のような過学習サインを見たら、 まず 5-fold CV で test accuracy の分布を取り、 標準偏差が 0.1 を超えるなら正則化(L2、 木の深さ制限、 アンサンブル)を強化します。 また、 特徴量と target の相関係数を網羅的に計算し、 |r| > 0.95 の特徴量は「ラベル漏洩」を疑って削除する慣行を持ってください。 SSDSE では「人口」と「人口密度」が高相関ですが、 これは漏洩ではなく自然な共線性なので削除不要です。 一方、 「高齢化率を分類するのに高齢者数を特徴量に入れる」のは典型的な漏洩で、 accuracy 0.99 と出ても本番に持っていくと崩壊します。
学習時の accuracy はあくまで「テストデータに対する一時点の値」です。 本番運用では「時間とともに accuracy が低下する」現象(モデルドリフト)が避けられず、 静的な accuracy だけを信じて運用すると数か月後に「accuracy 0.85 で出した結論が、 実は本番 accuracy 0.62 だった」という事故が起きます。 SSDSE-B-2026 のような自治体統計でも、 人口動態や経済構造が毎年変化するため、 2022 年データで学習した分類器を 2025 年データに適用すると accuracy が 0.05 から 0.15 ポイント低下する例が観察されます。
| 指標 | 計算方法 | 警告しきい値 |
|---|---|---|
| rolling accuracy | 直近 N 件の正解率(N=100 から 1000) | 学習時 -5 ポイント |
| per-class recall | クラスごとの再現率の時系列 | いずれかが -10 ポイント |
| prediction drift | 予測クラス分布の KL ダイバージェンス | 学習時分布から KL > 0.1 |
| feature drift | 入力特徴量分布の PSI(Population Stability Index) | PSI > 0.2 |
rolling accuracy が低下する前に prediction drift や feature drift が先行して動くケースが多いので、 「accuracy が下がってから対応する」のではなく、 「drift 系指標が変化したら accuracy を予防的に再評価する」運用が望ましいです。 これにより、 ユーザーが accuracy 低下を体感する前に再学習をかけられます。
SSDSE-B-2026 では「2010 年データで学習 → 2022 年データで評価」というシミュレーションが可能です。 12 年間で日本の人口は減少し、 高齢化率は全国平均で 6 ポイント以上上昇しました。 この変化のため、 2010 年学習モデルの 2022 年 accuracy は 2010 年同条件 accuracy より 0.08 から 0.12 ポイント低下します。 これは「12 年間放置すると約 10 ポイント accuracy が下がる」という具体的な数値で、 「自治体統計を扱うモデルは 3 から 5 年ごとに再学習が必要」という運用ルールを定量的に裏付けます。
この実験を再現するには、 過去版の SSDSE(2010 年版、 2015 年版、 2020 年版、 2026 年版)を順に学習させ、 各バージョンで「自バージョン accuracy」と「最新バージョン accuracy」を 2 軸プロットすると、 ドリフトの線形傾向が綺麗に観察できます。 業務で「再学習頻度をどう決めるか」を議論するときの強力なエビデンスになります。
運用 accuracy に対する SLA(Service Level Agreement)を設計する際は、 次の 3 値を明示してください。 (a) 目標値(例 0.85 以上)、 (b) アラート発火しきい値(例 0.80 を 24 時間連続で下回ったら通知)、 (c) 強制再学習しきい値(例 0.75 を超えた瞬間自動再学習)。 単一の目標値だけ決めると、 緩やかな低下に気付けず大規模事故になります。 三段構えで「悪化の早期検知 → 警告 → 強制対応」のエスカレーションを設計するのが、 accuracy 運用の業界標準です。
さらに重要なのは「SLA を accuracy 単独で組まない」ことです。 accuracy 0.85 を維持していても、 少数派の再現率が 0.2 に落ちていれば実務的には致命的な事故です。 SLA には「accuracy > 0.85 かつ全クラス recall > 0.6 かつ重大クラス(false negative コスト高)の recall > 0.9」のように複数指標の AND 条件を入れるのが安全です。 単一指標 SLA は accuracy paradox を運用フェーズで再現してしまうリスクがあります。
Accuracy は最も基本の分類指標ですが、 「ある状況では使ってはいけない」「ある状況では accuracy だけでは情報不足」というケースが明確に存在します。 ここでは accuracy と頻繁に併用する 8 つの指標について、 「使う場面」「使わない場面」「SSDSE での具体例」を一覧化します。 タスク設計時の指標選択チェックリストとして活用してください。
| 指標 | accuracy と併用する場面 | accuracy を置き換える場面 | SSDSE での適用例 |
|---|---|---|---|
| balanced accuracy | 不均衡データでの二重チェック | クラス不均衡比 3:1 以上 | 大都市 vs 地方 (6:41) |
| F1 score | precision/recall のトレードオフ評価 | 情報検索・少数派検出 | 高齢化 30% 超県の検出 |
| precision | false positive コスト高の業務 | スパム判定・誤検出最小化 | 「補助金対象」判定 |
| recall | false negative コスト高の業務 | 医療診断・不正検知 | 「災害弱者地域」検出 |
| ROC-AUC | しきい値非依存の総合性能 | 確率出力モデルの比較 | 複数手法の総合ベンチマーク |
| PR-AUC | 不均衡時の ROC-AUC 代替 | 正例比率 10% 未満 | 稀少疾患該当県の検出 |
| MCC | 4 セル全てを同等に考慮 | クラス不均衡 + 4 セル統合評価 | accuracy paradox 防御の最終手段 |
| log loss | 確率較正の評価 | 確率出力をそのまま使う業務 | 県別リスク確率の表示 |
タスクが手元にあるとき、 次の 3 ステップで主指標と副指標を決定します。 (1) クラス分布を確認 — 不均衡 3:1 以上なら accuracy を主指標から外し、 balanced accuracy または PR-AUC に切替。 (2) 誤りコストを確認 — false positive が高いなら precision、 false negative が高いなら recall を主指標。 (3) 確率出力の利用有無 — 確率をそのまま閾値変更で運用する場合は ROC-AUC や log loss を併記。 この 3 ステップを行うだけで、 「accuracy 0.85 で報告したが業務で炎上」という事故の大半を防げます。
同じデータに対して 8 つの指標を並べて計算する経験は、 「指標間の関係性」を直感で理解する最良の訓練になります。 例えば accuracy が高くても MCC が 0 に近いケースを SSDSE で再現すれば、 「accuracy 0.87, MCC 0.04 という組み合わせがどんな分類器を意味するか」を一度体感できるため、 業務で同じパターンを見た瞬間に「これは多数派偏重の分類器だ」と即座に診断できるようになります。 この「経験的指標感覚」を養うには、 47 県という小さな安全な実験場で何度も指標を眺める反復が効果的です。
最後に、 報告書や論文で accuracy を出すときの推奨レイアウトを示します。 「accuracy(点推定値 + 95% CI)」「balanced accuracy」「F1(macro)」「per-class recall(クラス別表)」「混同行列(4 セル絶対値)」の 5 点セットを最低限揃え、 余裕があれば「ROC-AUC」「PR-AUC」を加える。 これだけ揃えれば、 読者は accuracy の値が「信頼できる安定値」なのか「不安定な見かけ値」なのかを自分で判断できます。 単一の accuracy 値だけを大きく表示する報告は、 専門家からは「情報不足」とみなされます。
機械学習の入門書では「accuracy を最大化することが目標」と説明されがちですが、 実務では「accuracy が最大」ではなく「期待損失が最小」になるモデルが正解です。 両者は false positive と false negative のコストが同等のときだけ一致し、 コストが非対称な現実のタスクでは大きく乖離します。 SSDSE-B-2026 の「災害弱者地域の検出」を例に、 accuracy 重視の誤りと期待損失重視の正解を対比してみましょう。
標準の accuracy は 4 セル(TP/TN/FP/FN)を均等扱いします。 しかし災害支援タスクでは false negative(弱者地域を見落とす)のコストは false positive(過剰支援)の 10 倍から 100 倍に達します。 ここで重み付け accuracy を $\text{weighted\_acc} = (TP \cdot c_{TP} + TN \cdot c_{TN}) / (\sum セル \cdot 重み)$ として再定義すると、 多くのモデルで通常 accuracy 0.85 のモデルより 0.80 のモデルの方が「コスト調整型 accuracy」では高くなる逆転現象が観察されます。 この逆転を意識しないと、 「accuracy 最大」を目指して人命に関わる誤りを増やすことになりかねません。
SSDSE シミュレーションでは、 「高齢化率 ≥ 35% かつ人口 < 50万 の県」を「災害弱者地域」と定義すると、 47 県中 9 県が該当します。 通常 accuracy 最大化モデルは「全部弱者でない」と返す戦略で 38/47 = 0.809 を取りますが、 false negative コストを 50 倍に重み付けすると、 同じモデルのコスト調整 accuracy は 0.16 まで暴落します。 一方、 recall を犠牲にして balanced accuracy 重視で再学習したモデルは通常 accuracy 0.74 / コスト調整 accuracy 0.71 となり、 後者が圧勝します。 「目的関数を accuracy 単独にしない」という設計判断が、 業務価値を 4 倍以上引き上げる例として記憶しておく価値があります。
| モデル | accuracy | コスト調整 acc | 期待損失 | 業務的妥当性 |
|---|---|---|---|---|
| 全部「非該当」 | 0.809 | 0.16 | 450 | 最悪(弱者全見落とし) |
| ロジスティック(acc 最大化) | 0.851 | 0.42 | 270 | 不十分(FN 多発) |
| ロジスティック(bal_acc 最大化) | 0.745 | 0.71 | 85 | 良好(FN 抑制成功) |
| ロジスティック + 閾値 0.3 | 0.702 | 0.78 | 62 | 最良(recall 重視) |
この表が示す重要な事実は、 「accuracy 順位(0.851 > 0.745 > 0.702)」と「期待損失順位(最良が 62、 最悪が 450)」が完全に逆転している点です。 業務的妥当性で並べると最下位の「全部非該当」が accuracy 最高、 最上位の「閾値 0.3」が accuracy 最低という、 教科書的直感と真逆の結果になります。 これが「accuracy だけ見ると業務で失敗する」という主張の最も明快な定量的証拠で、 すべての分類タスクのスタート地点で「コスト行列を先に決める」ことの重要性を物語ります。
実務ではコストが厳密に定量化できないことも多いですが、 その場合でも「FN コスト ≥ FP コスト」「FN コスト = 10 × FP コスト」のような暫定比率を立て、 感度分析(コスト比を 1:1, 5:1, 10:1, 50:1 と変えて期待損失の変化を見る)を行うことが推奨されます。 コスト比 1:1 で最良のモデルと、 コスト比 10:1 で最良のモデルが同じであれば「コスト不明でも判断は変わらない」と言えますし、 異なれば「コストの精緻化が業務価値に直結する」というシグナルになります。 単に accuracy を最大化するだけでなく、 「自分のタスクのコスト構造はどうなっているか」を 1 度立ち止まって考えるだけで、 モデル選択の質が大きく向上します。
accuracy を 0.85 から 0.90 に上げるためには、 多くの場合「データ収集の倍増」「複雑なモデルの導入」「ハイパーパラメータの精緻探索」など、 大きな工数が必要です。 一方でこの 5 ポイント改善が業務価値に与える影響は、 タスクによって「年間 1000 万円相当」のこともあれば「ほぼゼロ」のこともあります。 「accuracy をどこまで上げるか」は技術的に決めるのではなく、 ビジネス側の意思決定者と「改善 1 ポイントあたりの限界価値」を擦り合わせて決めるのが王道です。 0.85 で十分なタスクで 0.95 を狙って半年溶かすのも、 0.95 が必要なタスクで 0.85 で妥協するのも、 どちらも工数配分の失敗です。
SSDSE で言えば、 「高齢化率予測」のような研究的タスクでは accuracy 0.74 で十分な学習価値が得られますが、 「災害弱者地域の自動検出」を市町村に展開する想定なら、 accuracy より recall ≥ 0.95 を目標にし、 そのために accuracy が 0.65 に落ちることを受け入れる、 という設計が正しい。 同じ 47 県データでも、 想定する社会実装の文脈次第で「accuracy をどう扱うか」の答えが変わるのです。
正解率の周辺概念をテーマ別ツリーで整理:
分類の評価指標(上位概念) ├── 混同行列(TP / FP / FN / TN)― 全指標の土台 ├── 【正解率】 ← ここ │ ├── Balanced Accuracy(クラス別再現率の平均) │ ├── Top-k Accuracy(上位 k 位以内で正解扱い) │ └── Per-class Accuracy(クラス別に算出) ├── Precision / Recall / F1(クラス別の性能を補完) └── ROC-AUC / PR-AUC(閾値非依存の評価)
この階層構造を頭に入れておくと、 学習や論文読みで「自分が今どこにいるか」を見失わずに済みます。
「正解率」を確実にマスターするには、 次の順序で進むのが効率的です:
焦らず、 1 段ずつ確実に。 7 ステップを 1 周すれば、 単に「知っている」から「使える」レベルに到達できます。
「🌐 関連手法・派生」の章が隣接指標を「鳥瞰」したのに対し、 ここでは 実務で Accuracy と他指標をどう繋ぐか・どう統合するか・いつ切替えるかを 3 視点で整理する。 次章「🌳 評価指標選択ツリー」が「最初に何を選ぶか」を答えるなら、 本章は「Accuracy を選んだ後・他指標と並べて運用する局面」を答える。
| 代替指標 | Accuracy からの切替条件 | 代替で得られる利点 | 注意点 |
|---|---|---|---|
| F1-score | クラス不均衡 (正例比率 < 30%) | Precision/Recall の調和平均で偏り検出 | どちらか一方が極端に低くても気付きにくい |
| ROC-AUC | 閾値非依存で識別力を測りたい | 分類確率の順位だけで評価可能 | 極端な不均衡では PR-AUC を選ぶべき |
| PR-AUC | 正例比率 < 5% (異常検知) | 少数の正例にフォーカスして評価 | ベースラインが正例比率に依存 |
| Precision / Recall | FP / FN コストが非対称 | 片方を最大化する閾値設定が可能 | 単一指標化は別途必要 (F-beta 等) |
| Matthews CC | 完全に均衡した単一指標が欲しい | 4 セル全てを公平に扱う相関係数 | 解釈が直感的でない (-1〜+1) |
この 3 視点を踏まえると、 Accuracy 単独の報告から「Accuracy + 不均衡対応指標 + 信頼区間」のセット報告に運用を移行できる。 SSDSE-B 47 都道府県のような小サンプル×中等度不均衡データでは、 単一指標ではモデル選択を誤りやすいので、 次章「🌳 評価指標選択ツリー」の選択フローと併せて活用したい。
分類タスクは? ├── 2 クラス │ ├── クラスは均衡? │ │ ├── YES → Accuracy + ROC-AUC で十分 │ │ └── NO(不均衡) │ │ ├── 確率出力? │ │ │ ├── YES → PR-AUC + F1 + Brier score │ │ │ └── NO → F1 + Balanced Accuracy + MCC │ │ └── 誤分類コスト非対称? │ │ └── YES → cost-sensitive + 期待損失最小化 │ └── 多クラス │ ├── クラス均衡 → Accuracy + macro F1 │ └── 不均衡 → macro F1 + classification_report └── 多ラベル → Hamming loss, subset accuracy, micro F1 回帰タスクは? ├── MSE / RMSE(外れ値に敏感) ├── MAE(外れ値に頑健、 中央値最小化) ├── R² / Adjusted R²(説明力の標準化) └── MAPE(相対誤差、 0 付近で爆発に注意)
同じデータ・同じタスクで複数モデルを比較するのが ML 実務の定石。 「人口大規模かどうか」の 2 クラス分類で 7 種類のモデルを 5-fold CV で評価。
このコードでやること:DummyClassifier から RandomForest までを 5-fold CV で評価し、 accuracy をテーブル形式で出力する。 「ベースラインに勝てるモデルだけが意味を持つ」を体感する。
📥 入力例:47 県、 X=[eld_rate, A1101, ...], y=人口大規模フラグ
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 | # 7 モデルの 5-fold CV ベンチマーク
import pandas as pd
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score, StratifiedKFold
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
df['eld_rate'] = df['A1303'] / df['A1101']
X = df[['eld_rate', 'A4101', 'A5101']].fillna(0).values
y = (df['A1101'] > 1_000_000).astype(int).values
cv = StratifiedKFold(5, shuffle=True, random_state=0)
models = [('Dummy(most)', DummyClassifier(strategy='most_frequent')),
('LR', LogisticRegression(max_iter=1000)),
('KNN', KNeighborsClassifier()),
('SVM', SVC(gamma='auto')),
('DT', DecisionTreeClassifier(random_state=0)),
('RF', RandomForestClassifier(n_estimators=100, random_state=0)),
('GBM', GradientBoostingClassifier(random_state=0))]
for name, m in models:
s = cross_val_score(m, X, y, cv=cv, scoring='accuracy')
print(f'{name:12s}: acc = {s.mean():.3f} ± {s.std():.3f}')
|
📤 実行結果(例):
💬 結果の読み方:まず Dummy(多数派常時予測)がベースライン 0.787 を与える。 出生数 A4101・転入者数 A5101 は総人口と強く連動する特徴量なので、 これらを使える LR/KNN/DT/RF/GBM は 0.91〜0.96 とベースラインを上回る。 一方スケーリングなしの SVM は多数派予測に張り付き、 Dummy と同じ 0.787 — 複雑なモデルでもベースラインと同値になり得る。 また n=47 では ± 0.09 前後の揺らぎがあり、 0.93 と 0.96 の差は誤差と区別できない。 「ベースラインを設定し、 それを揺らぎ込みで上回ったときだけ採用する」規律が大切。
| タスクの特徴 | 推奨主指標 | 併用推奨 |
|---|---|---|
| バランスのよい 2 クラス | Accuracy | ROC-AUC |
| 不均衡 2 クラス(陽性 10% 以下) | F1 / PR-AUC | Recall, Precision, MCC |
| 極端不均衡(陽性 1% 以下、 異常検知) | PR-AUC | Recall@k, lift |
| 医療診断(見逃しが致命的) | Sensitivity (Recall) | Specificity, NPV |
| スパム判定(誤捨てが致命的) | Precision | F2 (Recall 重み小) |
| 確率予測の信頼性 | Brier score | ECE, reliability diagram |
| 多クラス(クラス均衡) | Accuracy | macro F1 |
| 多クラス(不均衡) | macro F1 | per-class F1, micro vs macro |
| 情報検索ランキング | nDCG / MAP | MRR, Recall@k |
| 公平性が問われる業務 | グループ別 accuracy/F1 | Equal Opportunity, calibration |
論文・社内レポート・ステークホルダー説明に共通する「accuracy 報告の最低限フォーマット」を以下に示す。
特に重要なのは「ベースライン比較」「補助指標」「限界の明示」の 3 点。 これが欠けると「accuracy 78.7% でした」だけの中身ゼロの報告になる。
分類タスクでも「正解 / 不正解」が明確でないものは多い。 これらでは accuracy ではなく専用指標を使う。
| タスク | 難しさ | 代替指標 |
|---|---|---|
| 物体検出 | 「位置 + クラス」の同時判定 | mAP (mean Average Precision), IoU |
| セマンティックセグメンテーション | ピクセル単位の分類 | mIoU, Dice score |
| 機械翻訳 | 「正解の訳」が複数存在 | BLEU, chrF, COMET |
| 要約 | 「同じ意味で異なる文」をどう扱うか | ROUGE, BERTScore |
| 推薦システム | 「ユーザーの真の好み」は未知 | nDCG, Hit@k, CTR (A/B) |
| クラスタリング | ラベルがない (教師なし) | Silhouette, ARI, NMI |
| 生成 AI(画像、 文章) | 「正解」が原理的に存在しない | FID, IS, 人手評価 |
| 医用画像 | 専門医の判断が必要 | Sensitivity/Specificity per disease, AUC |
「accuracy 一本槍」では現代の AI タスクの大半は評価できない。 タスクに応じた指標選定が ML エンジニアの基本スキル。 たとえば物体検出で IoU=0.5 を「正解」とする慣習は CV 業界の合意であり、 これを accuracy と呼ぶことはあるが、 通常の分類 accuracy とは意味が異なる。 同様に翻訳の BLEU=30 は「30% 正解」ではなく、 「n-gram 一致率」の集約。 用語の精密さが議論を救う。
本セクションは既存の解説を壊さず、 accuracy を「直感 → 最重要の落とし穴 → 発展指標」の順で改めて一望する追補です。 各見出しは独立して読めます。
Accuracy は 「全予測のうち正しかった割合」、 すなわち $(TP+TN)/(TP+TN+FP+FN)$。 混同行列の対角成分(当たったマス)が全体に占める面積、 と覚えれば十分です。 分類のもっとも基本的な指標であり、 「まず最初に眺める数字」として今も広く使われます。 ただし直感的でわかりやすいぶん、 クラスが偏っている(不均衡)と平気で人を誤導するのが最大の弱点。 高い accuracy を見て安心する前に、 必ず「何と比べて高いのか」を問う癖をつけましょう。
DummyClassifier(strategy="most_frequent") の accuracy を必ず併記し、 提案モデルがそれをどれだけ上回ったかで語ります。 ベースライン未満の accuracy は「予測できていない」ことすら意味します。要するに、 accuracy は「クラス比率がほぼ均衡で、 誤分類コストが対称」なときだけ素直に信頼できる指標。 詳しくはクラス不均衡のページも参照してください。
公的統計 SSDSE-B-2026(encoding='cp932', skiprows=[1]、 2023 年の 47 都道府県)で、 総人口 A1101 を使って 「人口 500 万人超=大規模県」を陽性とする 2 値分類を考えます。 実測は次のとおりです。
most_frequent)の accuracy も同じ80.9%。 つまり「accuracy 80.9%」は予測が何も学べていない下限値にすぎませんこの 80.9% を「高精度」と報告するのは誤りです。 Balanced Accuracy で見れば (0 + 38/38)/2 = 50%(ランダム相当)となり、 実態が正しく暴かれます。 上の「🎮 触って理解する」ウィジェットに TP=0, FN=9, FP=0, TN=38 を入れても同じ挙動が確認できます。
※ 上記は SSDSE-B-2026 の実測値に基づく。 以降の「架空」と明記した例を除き、 数値の捏造はありません。
補完指標を選ぶ指針は評価指標の全体像にまとまっています。 なお Balanced Accuracy・Cohen's κ・MCC の専用ページは本教材では未整備のため、 ここでは定義のみを示しました。