🔖 キーワード索引
#分類評価#Precision#Recall#不均衡データ#harmonic mean#macro F1
「f1 score」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「f1 score」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
f1 score統計分析SSDSE-B-2026前提条件適用範囲落とし穴関連手法Python 実装検証方法
これらのキーワードは「f1 score の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
💡 30秒で分かる結論
🍰 まずはやさしく
2つの指標をまとめた点数のようなものです。
予測の正しさを公平に測るために使います。
スマホのアプリが正しく動くか確かめる時に便利です。
この章ではF1スコアの結論を短くまとめます。
F1スコア:PrecisionとRecallの調和平均
- $F_1 = 2\,PR/(P+R)$。 Precision と Recall の調和平均。
- クラス不均衡データで Accuracy より信頼できる指標。
- 値域 0〜1、 1 が完璧。 一方が極端に低いと F1 も低くなる。
- 多クラスでは macro/micro/weighted のバリエーション。
💡 F1 にまつわるトリビア
- F1 という名前の「1」は $\beta = 1$ の特例を示す。 「No.1 の指標」ではない。
- F-measure を体系化した Van Rijsbergenは情報検索の父と呼ばれる。
- F1 は 順位不変ではない:同じ Precision/Recall でも閾値で変わる。
- 多クラス F1 を
average=None で各クラス個別に取得できる。 マイノリティ診断に便利。
- F1 はベイズ的に $\beta=1$ のもとで両者の幾何平均と近似できる (実用的目安)。
- Cohen's Kappa との関係:均衡データでは Kappa ≈ F1 - 0.5 程度の経験則がある。
- F1 の「サンプリング誤差」は $\sqrt{p(1-p)/n}$ で近似 (p=F1 値, n=サンプル数)。 報告時の参考値。
📍 文脈ボックス
🍰 まずはやさしく
AIなどの性能を測るための物差しです。
分析の結果がどれくらい正しいかを知るために使います。
部活のデータ分析などで結果を評価する時に役立ちます。
この章ではF1スコアの全体像について学びます。
この用語は 評価指標 カテゴリに属します。 関連する別称・略号:F1。
論文・実務レポートで F1スコア が登場したら、 まず本ページの「30秒で分かる結論」と「直感で掴む」を読めば、 その文脈で何を言っているか把握できます。
本ページでは「f1 score」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。
「f1 score」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。
🎨 直感で掴む
🍰 まずはやさしく
正解率だけでは見えない落とし穴を教える道具です。
偏ったデータでも正しく評価するために使います。
ごく一部の人だけが当てはまる予測をする時に便利です。
この章ではF1スコアを直感的に理解します。
47 都道府県の中から「医療費が全国平均を上回る都道府県」を 2 クラス分類で予測したいとする。 SSDSE-B-2026 の I6111_保健医療費 を閾値で 2 値化し、 ロジスティック回帰で予測した結果、 47 都道府県中 30 件を Positive と予測。 うち実際に Positive だったのは 25 件 (= TP=25, FP=5)、 残り 17 件 (Negative 予測) のうち 2 件が本当は Positive (= FN=2)、 15 件は正しく Negative (= TN=15)。
正解率 (Accuracy) = (25+15)/47 ≒ 0.85。 一見良さそうだ。 だが — Positive 例が極端に少ない(不均衡データ)場合、 「すべて Negative」と答えるだけで Accuracy はいくらでも上がってしまう。 そこで Precision (適合率) と Recall (再現率) をセットで見る。 Precision = TP/(TP+FP) = 25/30 ≒ 0.833 「Positive と言ったうちどれだけ本当か」。 Recall = TP/(TP+FN) = 25/27 ≒ 0.926 「本当の Positive をどれだけ拾えたか」。
Precision と Recall は トレードオフ関係にある (閾値を厳しくすれば Precision↑ Recall↓)。 これを 1 つの値に圧縮した 調和平均が F1 スコア。 F1 = 2·P·R/(P+R) = 2·0.833·0.926/(0.833+0.926) ≒ 0.877。 算術平均 0.880 とほぼ同じだが、 どちらか一方が極端に小さいと F1 は大きく下がるのがミソ。 たとえば P=0.99, R=0.01 なら算術平均 0.50 だが F1 = 0.0198。 これが「Kaggle・医療診断・スパム検出で正解率より F1 が重視される」理由だ。
身近な例え:レストランレビューの「★3 つ」評価
あるレビューサイトで「料理の質」と「サービス速度」だけを評価するとする。 もしレストランが「料理 5/5、 サービス 1/5」だったらどう? 料理は最高だが「30 分も待たされて出てくる絶品料理」は、 多くの客には不満。 算術平均は 3.0 で「ふつう」だが、 体感は「★1」。 F1 は調和平均なので、 こちらに近い数値(≒1.67)を返してくれる。 「両方が良いときだけ高い」── これが F1 の哲学だ。
SSDSE-B-2026 想定:「医療費上位県」予測の閾値変化
| 閾値 | TP | FP | FN | Precision | Recall | F1 |
| 0.30 (緩い) | 27 | 15 | 0 | 0.643 | 1.000 | 0.783 |
| 0.50 (中央) | 25 | 5 | 2 | 0.833 | 0.926 | 0.877 |
| 0.70 (厳しい) | 20 | 1 | 7 | 0.952 | 0.741 | 0.833 |
| 0.90 (超厳しい) | 10 | 0 | 17 | 1.000 | 0.370 | 0.540 |
F1 は閾値 0.50 で最大となる。 これは「Precision と Recall の良いバランス点」を示している。 ROC 曲線・PR 曲線で最適閾値を選ぶときの参考指標として実務でよく使う。
F1 を実務で「裏切らずに」使う 3 つのコツ
- クラス不均衡を確認:少数派クラスを Positive にする。 majority を Positive にすると F1 が不当に高くなる
- 多クラス時は macro / weighted を明示:sklearn の
f1_score(y, y_pred, average='macro') を必ず指定
- 業務コスト非対称なら Fβ を採用:FN が致命的なら F2、 FP が致命的なら F0.5 を選ぶ
🔬 数式を言葉で読み解く
数式に出てくる記号の意味を 1 つずつ確認しましょう。
- TP
- True Positive。 正と予測し正解。
- FP
- False Positive。 正と予測し誤り (偽陽性)。
- FN
- False Negative。 負と予測し誤り (偽陰性)。
- Precision
- 正と予測したうちの正解率。
- Recall
- 本物の正のうち正と予測した率。
🔬 数式を言葉で読み解く(深掘り)
先の「記号を読み解く」を、 F1スコア の固有事情に即して 500 字以上で詳説する。 ここを読めば、 数式 1 行の裏にある設計判断と歴史的経緯が見えるはずだ。
TP (True Positive) = 「Positive と予測し、 実際も Positive」。 医療例なら「肺炎と診断し、 実際に肺炎」。 FP (False Positive) = 「Positive と予測したが、 実際は Negative」(α エラー / 第一種の過誤)。 FN (False Negative) = 「Negative と予測したが、 実際は Positive」(β エラー / 第二種の過誤 / 見逃し)。 TN (True Negative) = 「Negative と予測し、 実際も Negative」。 Precision $= TP/(TP+FP)$ は「Positive と予測したうち本当に Positive」の割合 → 無実の人を陽性と判定しない力。 Recall $= TP/(TP+FN)$ は「実際 Positive のうち拾えた」割合 → 見逃さない力。 F1 $= 2PR/(P+R)$ は両者の 調和平均で、 算術平均と違い「片方が極端に小さい」ことを許さない。 つまり F1 = 0.8 は「Precision と Recall がともに 0.8 付近で揃っている」ことを示し、 「Precision=1.0, Recall=0.67 で F1=0.8」と「Precision=0.67, Recall=1.0 で F1=0.8」は同値とみなす設計。 数学的には F-beta スコア $F_\beta = (1+\beta^2)PR/(\beta^2 P + R)$ の $\beta=1$ 特例で、 $\beta=2$ なら Recall 重視、 $\beta=0.5$ なら Precision 重視に調整できる。
📌 数式は 暗記対象ではなく検算ツール。 「結果が変だ」と感じたとき、 「この記号は本来こういう意味だから、 ここの値はおかしい」と 逆引きできる状態が、 中級者と上級者の差を生む。
🧪 SSDSE-B-2026 ハンズオン
本サイトの標準データ SSDSE-B-2026(47 都道府県 × 約 100 列、 独立行政法人統計センター提供) を使い、 F1スコア の概念を 実コードで体感する。 取得経路は data/raw/SSDSE-B-2026.csv(リポジトリ同梱)。
上記の 47 都道府県・医療費 2 値分類の例を、 そのまま scikit-learn で再計算する。 次のステップで TP/FP/TN/FN → Precision/Recall → F1 を順に求め、 classification_report 出力と一致することを確認する。 また F1 のマクロ平均・マイクロ平均・重み付き平均の違いも触れる。
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) I5102(一般診療所数) L3221(消費支出(二人以上の世帯)) L322106(保健医療費(二人以上の世帯))
北海道 5,092,000 3,403 296,888 15,491
東京都 14,086,000 14,894 341,320 18,166
沖縄県 1,468,000 928 251,222 11,686
…(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | # SSDSE-B-2026 で「医療費が全国平均超」を 2 値分類し、 F1 を測る
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_val_predict
from sklearn.metrics import classification_report, f1_score, precision_recall_curve
# I6111・A2301・I5215 は SSDSE-B-2026 に無い。実在する列に置き換える。
# 医療費 → L322106 保健医療費(二人以上の世帯)
# 説明変数 → A1101 総人口 / L3221 消費支出 / I5102 一般診療所数
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()] # 最新年度の 47 行
y = (df['L322106'] > df['L322106'].mean()).astype(int)
X = df[['A1101', 'L3221', 'I5102']].values
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
y_pred = cross_val_predict(LogisticRegression(max_iter=1000), X, y, cv=cv)
print(classification_report(y, y_pred, digits=3))
print('macro-F1 =', f1_score(y, y_pred, average='macro'))
print('weighted-F1 =', f1_score(y, y_pred, average='weighted'))
# 閾値最適化
proba = cross_val_predict(LogisticRegression(max_iter=1000), X, y, cv=cv, method='predict_proba')[:, 1]
p, r, th = precision_recall_curve(y, proba)
f1_curve = 2*p*r/(p+r+1e-9)
best = f1_curve.argmax()
print(f'best threshold = {th[best]:.3f}, F1 = {f1_curve[best]:.3f}')
|
📌 動かないときは: (1) data/raw/SSDSE-B-2026.csv がリポジトリに存在するか、 (2) encoding='cp932'・skiprows=[1] でヘッダーが正しく読めているか、 (3) 列名が SSDSE 公式の最新版と一致しているかを df.columns.tolist() で確認。
🧮 実値で計算してみる
TP=80, FP=20, FN=10 の例。
STEP 1
Precision
$P = 80/(80+20)=0.80$.
STEP 2
Recall
$R = 80/(80+10)=0.889$.
STEP 3
F1 計算
$F_1 = 2 \cdot 0.80 \cdot 0.889 / (0.80+0.889) = 0.842$.
STEP 4
解釈
F1=0.84 はまずまず良好。
🧮 数式に値を入れて手で計算する: F1 = 2·P·R/(P+R)
合成データで Precision と Recall から F1 を計算する。
Step 1: 混同行列要素
TP=60, FP=15, FN=20
Precision = TP/(TP+FP) = 60/75 = 0.80
Recall = TP/(TP+FN) = 60/80 = 0.75
Step 2: F1
F1 = 2·0.80·0.75/(0.80+0.75)
= 1.2 / 1.55
≈ 0.774
Step 3: 重み調整 F_β
F_β = (1+β²)·P·R/(β²·P + R)
β=2 (Recall 重視): F2 = 5·0.6/(3.2+0.75) = 3/3.95 ≈ 0.759
β=0.5 (Precision 重視): F0.5 = 1.25·0.6/(0.2+0.75) ≈ 0.789
🐍 Python で再現
| tp, fp, fn = 60, 15, 20
p = tp/(tp+fp)
r = tp/(tp+fn)
f1 = 2*p*r/(p+r)
print(f"P={p}, R={r}")
print(f"F1 = {f1:.3f}")
|
📤 実行結果
P=0.8, R=0.75
F1 = 0.774
💬 手計算 (Step 2) 0.774 と Python 出力が完全一致。
🎮 触って理解する
下のパネルで Precision(適合率)と Recall(再現率)を動かすと、
F1(調和平均)と算術平均がリアルタイムに計算・可視化されます。
色つきの正方形はドラッグ/タップで操作でき、背景色はその点の F1 の高さ(赤=低い、緑=高い)を表します。
スライダーでも同じ値を動かせます。片方だけ 0 に近づけると、算術平均は下がりきらないのに F1 だけが急落する——
この「両方が良くないと高くならない」性質を体感してください。
背景色 = その (P, R) での F1(赤=低 / 緑=高)
🧭 この操作で分かること(直感)
- 対角線上(P≒R)では F1 ≒ 算術平均。両者がそろっているときだけ両方式は一致します。
- 端(片方が 0 付近)に寄せると背景は一気に赤くなり、F1 が急落。例:P=0.99, R=0.01 → 算術平均 0.50 に対し F1 ≒ 0.020。調和平均は「小さい方」に強く引っ張られます。
- F1 の等高線が原点付近で密(=勾配が急)になるのが見えます。少数派クラスの取りこぼしが F1 に大きく効く理由です。
⚠️ よくある落とし穴
- 算術平均で代用しない:P と R を単純平均すると、片方が壊滅していても「そこそこ」の値が出てしまい、モデルの欠陥を見逃します。F1(調和平均)はそれを罰します。
- 多数派を Positive にしない:F1 は Positive クラスの定義に依存します。少数派(検出したい側)を Positive に置くのが原則です。
- 閾値を固定した 1 点の値であることを忘れない:F1 は特定の判定閾値での値。AUC のような閾値非依存の指標とは性質が違います。
🚀 発展:Fβ スコアで重みを変える
F1 は P と R を対等に扱いますが、業務では片方が重要なこともあります。一般化した
Fβ スコア $F_\beta = (1+\beta^2)\,PR/(\beta^2 P + R)$ を使うと、
$\beta=1$ で F1、$\beta>1$(例 F2)で Recall 重視(見逃しを嫌う医療検査など)、
$\beta<1$(例 F0.5)で Precision 重視(誤警告を嫌うスパム判定など)に切り替えられます。
上のパネルで P と R を固定したまま「もし β を上げたら?」を想像すると、Recall の低さがより強く効くようになる、と読み替えられます。
🔗 関連ページ:
Precision(適合率) ・
Recall(再現率) ・
混同行列 ・
クラス不均衡 ・
正解率(Accuracy) ・
ROC 曲線 ・
AUC。
(PR 曲線・Fβ の専用ページは未整備のため本文内の解説を参照してください。)
🐍 Python 実装
最小実装の例。 SSDSE のような実データに対して、 まずはコピペで動かしてみるのが理解の早道です。
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) A1303(65歳以上人口) A4103(合計特殊出生率)
北海道 5,092,000 1,681,000 1.06
東京都 14,086,000 3,205,000 0.99
沖縄県 1,468,000 350,000 1.6
…(全 47 行)
| from sklearn.metrics import f1_score, classification_report
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
y_true = (df['A1303'] / df['A1101'] >= 0.30).astype(int) # 高齢人口/総人口 が 30% 以上
y_pred = (df['A4103'] <= 1.40).astype(int) # 合計特殊出生率が低い県を高齢化と予測
print('F1:', f1_score(y_true, y_pred))
print(classification_report(y_true, y_pred))
|
🐍 Python 実装(応用編)
先の Python 実装は最小例だった。 ここでは F1スコア の本格的な実務シナリオに即した、 もう一段難易度を上げたコードを示す。 そのままコピペで動くよう、 SSDSE 系の実データパスを直書きで残してある。
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) I510120(一般病院数) I5102(一般診療所数) L3221(消費支出(二人以上の世帯)) L322106(保健医療費(二人以上の世帯))
北海道 5,092,000 464 3,403 296,888 15,491
東京都 14,086,000 588 14,894 341,320 18,166
沖縄県 1,468,000 76 928 251,222 11,686
…(全 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 | # 47 都道府県 + 学校教員 SSDSE-A-2025 を絡めた多クラス分類で F1 を測る例
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, cross_val_predict
from sklearn.metrics import classification_report, f1_score, ConfusionMatrixDisplay
import matplotlib.pyplot as plt
# I6111・A2301・I5215 は SSDSE-B-2026 に無い。実在する列に置き換える。
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()] # 最新年度の 47 行
# 保健医療費を 3 クラスに離散化(低・中・高)
df['target'] = pd.qcut(df['L322106'], q=3, labels=['low', 'mid', 'high'])
features = ['L3221', 'I5102', 'I510120', 'A1101']
X = df[features].fillna(df[features].median()).values
y = df['target'].values
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
y_pred = cross_val_predict(RandomForestClassifier(n_estimators=200), X, y, cv=cv)
print(classification_report(y, y_pred, digits=3))
# クラスごとの F1
for avg in ('macro', 'micro', 'weighted'):
print(avg, '-F1 =', f1_score(y, y_pred, average=avg))
# 混同行列を可視化
fig, ax = plt.subplots(figsize=(5, 4))
ConfusionMatrixDisplay.from_predictions(y, y_pred, ax=ax)
plt.tight_layout()
print('混同行列でクラスごとの偏りを確認')
|
📌 このコードのポイント: (1) 引数化せず実データパスを直書きで読みやすさ優先、 (2) 集約・結合・型最適化など F1スコア 関連の典型処理を一気通貫で示す、 (3) print() で各ステップの結果を確認できる。
🧭 用語クロスリンク集
F1スコア と関わりの深い用語を、 一画面で巡回できるよう チップ形式で並べた。 「これも知っておきたい」と思った瞬間にクリックして、 元のページに戻ってくる ── ジャストインタイム学習の理想的な使い方。
📌 これらはすべて html/glossary/ 配下の実在ページにリンクしているので、 リンク切れの心配はない。
🗂 用語の階層・派生・対立関係
F1スコア を中心に、 上位概念・並列概念・派生概念・対立概念の 4 区分で整理。 学術論文を読むときの「この用語はこの分野のどこに位置するか」を直感的に把握できる。
⚠️ よくある落とし穴
この用語を使うときに陥りがちな失敗パターン。 経験者ほどここに 1 度はハマっています。
❌ Macro vs Micro の取り違え
クラス不均衡では Macro F1 (クラス平均) が公平。
❌ 単一閾値依存
閾値で F1 は変動。 PR-AUC も併用。
❌ Negative クラス無視
F1 は通常 positive クラスのみ。 両方見るなら macro。
❌ Recall が極端に重要な場面
医療など FN が致命的な領域では F2 を使う (Recall 重視)。
⚠️ もっと深い落とし穴
上のセクションの 4 つに加えて、 F1スコア 固有の実務でハマる典型をさらに 4 つ。 経験 5 年以下のエンジニア・研究者はほぼ全員、 ここのいずれかで 1 度は事故を起こしている。
❌ マクロとマイクロの混同
macro = クラスごと F1 を単純平均(マイノリティ重視)、 micro = 全 TP/FP/FN を集計 (= Accuracy と同等になることが多い)。 報告時に必ず明記。
❌ クロスバリデーション fold ごとの分散
F1 = 0.82 ± 0.05 と分散が大きい場合、 1 fold の良さは偶然。 StratifiedKFold で各 fold のクラス比を維持。
❌ ゼロ除算(全 Negative 予測)
TP=FP=0 で Precision の分母 0。 sklearn は zero_division=0 で F1=0、 warn で警告。 業務的にはモデル失敗のシグナル。
❌ マルチラベル分類での F1
ラベル「がん/高血圧/糖尿病」のように複数同時 True がある場合、 sample-averageか label-averageか明記。 average='samples' 等。
🌐 関連手法・派生
この用語を理解したら、 自然と気になる発展トピック・派生手法を紹介します。
🌐 $F_\beta$
Precision と Recall の重み調整。
🌐 Macro F1
クラスごと F1 の単純平均。
🌐 Micro F1
全体の TP/FP/FN を足してから計算。
🌐 Weighted F1
クラスサイズで重み付け平均。
🌐 多言語・呼称・略号一覧
英語論文・中国語ドキュメント・他言語チームと協業するときに役立つ、 F1スコア の各言語呼称と関連略号。
| 分類 | 呼称・略号 |
| 日本語 | F1 スコア/F 値/F1 値/F1 測度 |
| 英語 | F1 Score / F1 Measure / F-measure / F-beta Score |
| 中国語 | F1 分数 / F1 值 / F1 度量 |
| ドイツ語 | F1-Score / F1-Maß |
| フランス語 | score F1 / mesure F |
| プログラミング用語 | f1_score (sklearn) / F1Score (Keras) / torch.nn.functional 直接実装 |
| 略号 | F1, F-beta, F2, F0.5 |
| 関連略号 | AUC-PR (Precision-Recall AUC), AUC-ROC, MCC (Matthews Correlation Coefficient) |
📌 国際会議の発表や論文翻訳の際、 微妙な訳語の違いで読者の理解が変わる。 上記の正式名称を押さえておくと安全。
🛠 主要ツール・ライブラリ比較表
F1スコア を実装するときに選択肢になる主要ツール・ライブラリの強み・弱みを 7〜8 件まとめた。
| ツール | 強み | 弱み・注意点 |
| sklearn | f1_score 標準実装 / 多クラス対応 | 閾値最適化は別途 |
| Keras / TF | F1Score / バッチ計算 | 全体集計には注意 |
| PyTorch (torchmetrics) | F1Score / GPU 計算 | 依存ライブラリ要 |
| imbalanced-learn | geometric_mean_score 等の代替指標も | メイン用途は再サンプリング |
| XGBoost | eval_metric='aucpr' 等 | F1 は直接非対応 |
| LightGBM | metric='binary_logloss' + 後処理 | 同上 |
| Pycaret | AutoML / F1 で自動選択可能 | 拡張性は限定的 |
📌 ツール選びは「組織の既存スタック」「予算」「学習曲線」「規模」の 4 軸で決める。 「最新だから」では選ばないこと。
🎬 ケーススタディ:実務での F1スコア
教科書を超えて、 F1スコア が実プロジェクトでどう使われ、 どこで詰まり、 どう解決するかを実例ベースで描く。 仮想だが現実に近いシナリオで、 「自分が同じ立場ならどうするか」を考えながら読んでほしい。
背景:医療系スタートアップで「胸部 X 線画像から肺炎陽性を 2 値分類するモデル」を本番運用する。 訓練データ 10,000 枚、 陽性率 8%。 PoC では F1=0.82 を達成したが、 病院での運用テストで「実用上問題が多い」と現場医師から指摘。 何が起きたか。
問題 1:偽陰性が多い (見逃しが致命的)。F1=0.82 の内訳は Precision=0.91, Recall=0.75。 つまり「陽性と予測したものは正確だが、 25% の陽性は見逃す」。 医療では 見逃し (FN) のコストが誤検知 (FP) より遥かに高いので、 この設計は不適切。
解決 1:評価指標を F1 から F2 (β=2、 Recall 重視) に変更。 訓練目的関数も BCEWithLogitsLoss(pos_weight=12) で陽性クラスを 12 倍重視 (1/陽性率 ≈ 12)。 結果:Recall=0.92, Precision=0.78, F2=0.88。
問題 2:閾値固定 0.5 が業務に合わない。医師が「念のため」と確認できるなら、 多少の誤検知 (FP) は許容できる。 だが閾値 0.5 だと「明確に陽性」しか拾わず、 Recall が伸びない。
解決 2:precision_recall_curve で「Recall ≥ 0.95」を制約条件として Precision を最大化する閾値を探索。 結果:閾値 0.32 で Recall=0.96, Precision=0.65 を達成。 「ハイ感度モード」と命名し、 「ロー感度モード (閾値 0.7)」と切替可能に。
問題 3:cross-validation 間で F1 のバラツキ大。5-fold で F1 が 0.75〜0.88、 標準偏差 0.05。 たまたま良い fold で報告していた可能性。
解決 3:RepeatedStratifiedKFold(n_splits=5, n_repeats=10) で 50 fold の平均と 95% CI を報告 (F2=0.85 ± 0.04)。 fold 間のバラツキは「データ自体のノイズ」と「モデルの不安定さ」の合算なので、 ensemble + temperature scaling で安定化。
教訓:F1 は便利な単一指標だが、 (i) 業務インパクトに非対称性があれば F-beta を選ぶ、 (ii) 閾値最適化を必ず行う、 (iii) cross-validation で信頼区間を報告する、 (iv) Precision-Recall 曲線で全体像を見る — の 4 点をセットで運用するのが現代の標準。 「F1 = 0.82」だけ報告して終わりは 素人スキル。
🔗 関連用語 (前提・並列・発展)
この用語と直接結びつく前提・並列・発展用語を 3 区分で整理。 学習順序の参考にどうぞ。
📘 前提(先に押さえたい)
F1 を計算する前に必須となる土台概念。 分類モデルの出力と混同行列の見方が無いと F1 の意味が掴めない。
🔗 分類
F1 は分類モデルの主要指標。
🔗 混同行列
F1 の元データ(TP/FP/FN)
🔗 適合率
F1 の構成要素
🔗 再現率
F1 のもう一方の構成要素
🤝 並列(同じ階層で比較する)
F1 と同じく「分類モデルを 1 つの数値で評価する」立場の指標群。 用途に応じて使い分ける。
🔗 偽陰性
F1 の Recall に効く誤り。
🔗 正解率
F1 との対比指標
🔗 交差エントロピー
分類の損失関数
🔗 Softmax
確率出力でクラスを決定
🚀 発展(次の一手)
F1 を一通り理解したら、 モデル改善や学習設計の文脈に視野を広げる。
🔗 過学習
F1 が訓練で高く検証で低い症状
🔗 正則化
過学習の対策
🔗 学習率
学習挙動と F1 への影響
🔗 関連用語 (深掘り 12 件)
上記 3 区分に加えて、 F1スコア から派生的に学ぶと体系が完成する用語のサマリ。 すべて当サイト内のページに直リンクするので、 リンク切れ無く周遊できる。
🎓 深掘り(さらに:3 シナリオ × 3 誤解 × 5 意思決定)
ここまで「F1 = 調和平均」「不均衡データでの強み」「閾値依存性」を押さえた。 続けて、 実コンペや業務で F1 をどう報告するか・どう改善するかを 3 シナリオで具体化する。 そして 「F1 が高ければ完璧か?」「マクロ/マイクロどっち?」「閾値固定で良いか?」の 3 つの誤解を整理、 最後に Precision 重視か Recall 重視か F1 で妥協か の意思決定 5 段。
シナリオ A:研究室での卒論:偽陰性が痛い医療診断
「胸部 X 線画像から肺炎陽性を 2 クラス分類する。 陽性 5%・陰性 95% の不均衡データで、 偽陰性 (本当は肺炎なのに見逃す) を絶対避けたい」という卒論テーマ。 Accuracy 95% は「全部陰性と答える」だけで達成できるので無意味。 F1 スコアと特に Recall を重視する。 classification_report(y_true, y_pred) で各指標を確認、 さらに precision_recall_curve で「Recall ≥ 0.95 を維持しつつ Precision を最大化」する閾値を選ぶ。 F1 だけ見ると Precision と Recall がバランス取れた点に最適化されるが、 医療では Recall に重み付けした F2 スコアを使うのが定石、 という発展も書ける。
シナリオ B:企業インターン:A/B テストの分類モデル比較
本番のスパム検出モデル v1 (F1=0.78) と新モデル v2 (F1=0.82) を比較する。 ただし v1 は Recall=0.95、 v2 は Recall=0.70 で、 v2 は F1 こそ高いが 見逃しが増える。 ステークホルダーに F1 だけ報告すると「v2 採用しよう」となるが、 ビジネス要件(顧客のスパム被害最小化)的には v1 が正解。 本ページの「マクロ/マイクロ/重み付き」セクションを引いて classification_report の正しい読み方を共有することが、 インターンの価値そのものになる。
シナリオ C:論文を読んでつまずく:Kaggle 上位解の F1
Kaggle Discussion で「我々は macro-F1でリーダーボード 3 位を取った」と書かれていた。 本ページに飛び、 「macro-F1 はクラスごとの F1 を単純平均する → 少数クラスにも重みを与える」と理解。 元の議論に戻ると、 著者が「マイノリティクラスへの SMOTE オーバーサンプリング」を提案している理由が一気に腑に落ちる。
よくある誤解 3 連続
「F1 が高ければモデルとして完璧」
F1 は Positive クラスの性能しか見ない。 Negative の Precision/Recallは無視される。 多クラス分類なら macro-F1を、 業務インパクトの非対称性があるなら F2 / F0.5を併用する。
「Precision と Recall の算術平均で十分」
算術平均は両者の差を打ち消してしまう (P=1, R=0 で 0.5 になる)。 調和平均は 小さい方に強く引っ張られるので、 「両方バランス良いか」を厳しく判定できる。
「閾値は 0.5 で固定」
不均衡データや業務要件があるなら、 precision_recall_curve で 業務最適閾値を選ぶ。 0.5 はロジスティック回帰の理論的中央であって、 業務最適とは限らない。
意思決定フレーム:状況別 5 段
| 状況 | 推奨アクション |
| 偽陽性が痛い (スパム判定) | ✅ Precision 重視。 F0.5 や閾値↑ で運用 |
| 偽陰性が痛い (癌検出) | ✅ Recall 重視。 F2 や閾値↓ で運用 |
| クラス不均衡 99:1 以上 | ⚠️ F1 単独でなく PR-AUCも併用、 macro-F1でマイノリティ評価 |
| 多クラス分類 | ✅ クラスごとの F1 → macro / weighted-F1で全体評価 |
| 業務 KPI が金額 | ❌ F1 ではなく 期待コスト (FP cost × FP + FN cost × FN) で評価 |
🔍 近接概念との比較(深掘り)
先の汎用テーブルに加えて、 F1スコア と 正解率 (Accuracy) / AUC-ROC を 6 つの観点で具体的に対比する。
| 観点 | F1スコア | 正解率 (Accuracy) / AUC-ROC |
| 対象 | Positive クラスへの当てやすさ | Accuracy: 全クラスの一致率、 AUC: 全閾値での識別性能 |
| 計算式 | 2·P·R/(P+R) (P/R の調和平均) | Accuracy: (TP+TN)/N、 AUC: ROC 曲線下面積 |
| 不均衡対応 | 強い (Negative 多数を無視) | Accuracy: 弱い、 AUC: 強い |
| 閾値依存 | あり (0.5 か業務閾値) | Accuracy: あり、 AUC: 無し |
| 解釈 | 1 が最高、 0 が最低、 0.5 は無作為に等しい場合あり | Accuracy: 比率、 AUC: 順位的識別力 |
| 典型用途 | スパム判定、 医療異常検知、 Kaggle 2 値分類 | Accuracy: 均衡データ、 AUC: モデル比較 |
📌 使い分けの一行ヒント:本ページ「💡 30 秒で分かる結論」の要件と上の表の 観点 6 つを突き合わせれば、 ほぼ全ての実務シーンで「どちらを選ぶか」即断できる。
📖 体系的解説:F1スコア を 5 つの観点で掘り下げる
ここからは F1スコア を、 教科書・論文・実務の境界を行き来しながら、 5 つの観点で深く解説する。 中級者以上を想定し、 「30 秒結論」「直感」では触れなかった 設計判断と歴史に踏み込む。
1. なぜ調和平均なのか — 算術・幾何・調和の比較
2 つの値 $a, b$ に対し、 算術平均 $\frac{a+b}{2}$、 幾何平均 $\sqrt{ab}$、 調和平均 $\frac{2ab}{a+b}$ がある。 大小関係は 算術 ≥ 幾何 ≥ 調和、 一致するのは $a=b$ のときのみ。 つまり 2 つの値が乖離するほど、 調和平均は小さくなる。 F1 が調和平均を採用するのは、 Precision と Recall が乖離している時に厳しい評価をしたいという設計思想だ。
数値例:$P=0.9, R=0.1$ のとき、 算術=0.5、 幾何≒0.3、 調和≒0.18。 「片方が極端に低い」モデルを 0.5 のように見せかけてはいけない、 という哲学。 一方、 $P=R=0.8$ のとき、 算術=0.8、 幾何=0.8、 調和=0.8 で全て一致。 「両者揃っているなら平均と一致する」性質も持つ。
2. F-beta:Precision と Recall に重みを付ける
F1 の一般形が $F_\beta = (1+\beta^2) \cdot \frac{P \cdot R}{\beta^2 \cdot P + R}$。 $\beta=1$ なら F1 (両者対等)。 $\beta=2$ なら F2で Recall を重視 (癌検出など見逃しが致命的なケース)。 $\beta=0.5$ なら F0.5で Precision を重視 (スパム判定で誤検知を避けたいケース)。
$\beta$ の選び方は業務インパクトのコストで決まる。 偽陰性 (見逃し) のコストが偽陽性 (誤検知) の $\beta^2$ 倍なら $F_\beta$ が最適。 たとえば癌見逃しの社会的コストが誤診の 4 倍なら $\beta = 2$。 これを cost-sensitive learningと呼ぶ。 単純な F1 だけ報告するのは「すべてのコストが対称」と暗黙に主張していることに等しい。
3. macro / micro / weighted の使い分け
多クラス分類で F1 を集約する 3 方式:
macro-F1 = $\frac{1}{K}\sum_k F_1^{(k)}$ — 各クラスの F1 を単純平均。 マイノリティクラスも対等に評価。
micro-F1 = 全クラスの TP/FP/FN を合算してから F1。 多クラス全体での Accuracy に等しくなる (二乗対角の場合)。
weighted-F1 = $\sum_k w_k F_1^{(k)}$、 $w_k$ はクラスのサポート数比例。 サンプル数が多いクラスを重視。
使い分けの目安:(i) クラス間で評価重要度が同じ → macro、 (ii) クラス頻度に比例して評価したい → weighted、 (iii) 全体の正解数ベースで見たい → micro。 報告時に必ず明記しないと、 「F1 = 0.8」が macro なのか micro なのかで意味が全く違う。
4. F1 vs AUC-ROC vs AUC-PR の選択
F1 は閾値固定 (通常 0.5) での点評価。 業務運用時の実際の挙動を反映。 AUC-ROC は全閾値での Recall vs 1-Specificity の曲線下面積。 「順位的識別力」を表すが、 不均衡データでは過大評価しがち。 AUC-PR (Precision-Recall AUC) は全閾値での Precision vs Recall。 不均衡データに頑健で、 Negative が圧倒的多数のときに推奨される。
医療診断や異常検知のように Positive が 1〜5% しかない問題では、 AUC-ROC は 0.95 でも実用性が低いことがある。 一方 AUC-PR は同じデータで 0.3 程度に下がり、 「実は思ったほど良くない」が見える。 報告時は AUC-ROC と AUC-PR の両方を出し、 業務閾値での F1 を併記するのが説得力ある書き方。
5. F1 を改善する 5 つの実務テクニック
(1) 閾値最適化:precision_recall_curve で F1 最大の閾値を探す。 0.5 固定は捨てる。
(2) クラス重み付け:class_weight='balanced' でマイノリティクラスを重視。
(3) リサンプリング:SMOTE / ADASYN でマイノリティを増やす、 RandomUnderSampler でマジョリティを減らす。
(4) アンサンブル:Bagging で分散を、 Boosting でバイアスを減らす。 XGBoost / LightGBM の scale_pos_weight を活用。
(5) 特徴量エンジニアリング:Positive クラスを区別する強い特徴量があれば F1 は劇的に改善。 ドメイン知識が決め手。
これらを段階的に試し、 各施策が Precision と Recall のどちらをどれだけ動かしたかを classification_report で確認しながら進めるのが定石。 F1 だけ見て「上がった!」で終わらせず、 内訳を理解することが上達への近道。
📚 関連グループ教材・さらに学ぶには
このサイト内
- 論文一覧に戻る — F1スコア を実際に使った再現論文をハンズオン形式で読む
- 関連用語ページ — このページの「🔗 関連用語」から派生
- 用語集トップ — 全用語を一覧で確認
- 概念マップ — 用語間の関係を視覚化
推奨書籍・教材
- 『統計学入門』(東京大学出版会)― 日本語統計入門の定番。 評価指標 の基礎が押さえられる。
- 『Pythonによるデータ分析入門』(Wes McKinney、 O'Reilly)― pandas 作者による実装ガイド。
- 『機械学習のエッセンス』(加藤公一、 SBクリエイティブ)― ML 基礎を Python で実装しながら学ぶ。
- 『因果推論の科学』(Judea Pearl、 文藝春秋)― 相関と因果の違いを徹底解説。
オンライン教材
- scikit-learn 公式ドキュメント — 機械学習の標準実装。
- StatQuest (YouTube) — 統計概念を直感的に解説。
- Coursera / edX — 体系的なオンライン講座。
- SSDSE 公式 — 本サイトで使う公的データの提供元。
困ったときは
- データの可視化 (散布図・ヒストグラム・箱ひげ図) で全体像を把握
- サンプルサイズ・欠損・外れ値を確認
- 適用条件 (前提) が満たされているか診断
- 類似研究での標準的な手法を確認
- 結果を複数手法でクロスチェック
📜 歴史的背景と学習の位置づけ
F1スコア は 評価指標 の領域で発展してきた概念です。 ここでは大まかな歴史的背景と、 なぜこの概念が必要になったのかを整理します。 用語が「降ってきた」のではなく、 現実の問題を解くために順番に編み出されたものだと知ると、 学習の納得感が違います。
なぜこの概念が生まれたか
データ分析や AI を実務で使うと、 「単純な数式」「直感だけのモデル」では太刀打ちできない場面が必ず出てきます。 F1スコア は、 そうした実務的な課題を整理し、 共通言語として定式化したものです。 そのため、 教科書だけで完結する話ではなく、 使う場面と使わない場面を見極めることが何より重要になります。
学習の位置づけ
- 初学者:まず「30秒で分かる結論」「直感で掴む」だけ読めば、 論文に出てきたときに「あ、 あれね」と分かります。
- 中級者:数式と Python 実装をセットで覚え、 自分の手元データに適用できる状態を目指します。
- 上級者:落とし穴と派生手法を理解し、 場面に応じた使い分け・改良ができることが目標です。
🔍 近接概念との比較
同じ 評価指標 カテゴリにある近接概念と、 F1スコア はどう違うのか? 混同しがちなポイントを整理します。
| 観点 | F1スコア | 近接概念 |
| 目的 | 主に F1スコア 固有の課題 (本文参照) | 近接概念は関連はするが目的が異なる (本文の「関連手法・派生」参照) |
| 前提条件 | 本文「前提・落とし穴」参照 | 手法ごとに前提が異なるため要確認 |
| 出力 | 数値 / 確率 / 集合など (上記公式参照) | 同じ入力に異なる粒度の出力を返すことが多い |
| 適用場面 | 本文「いつ使うか」参照 | 同じ問題でも視点が異なる手法を組み合わせるのが定石 |
| 計算コスト | 用途範囲に応じて妥当な水準 | 精度と引き換えにコストが増える派生がある |
📌 使い分けの原則: まずは本ページの定義を押さえ、 次に「🌐 関連手法・派生」「🔗 関連用語」のリンクから近接概念を確認し、 自分の問題に対してどれを使うか意識的に選ぶことを習慣にしてください。
❓ よくある質問 (FAQ)
本サイトの教材を読み進めるなかで、 受講者からよく質問される項目をまとめました。
Q1. F1スコア を覚えるべき優先度は?
A. 論文を読んだり、 業務で類似の分析に出会うときに必ず登場します。 「30秒で分かる結論」までは押さえておけば、 都度本ページを参照しながら作業すれば十分です。 全暗記は不要、 引き出しに入れておく感覚で OK。
Q2. 数式が苦手だが大丈夫?
A. 大丈夫。 まず「直感で掴む」「実値で計算してみる」を読み、 そのあと「定義・数式」に戻ると、 記号の意味が腑に落ちます。 数式は 後追い で構いません。 重要なのは、 結果の数字を見たときに、 何を意味するか言葉で説明できることです。
Q3. Python が動かないときは?
A. まず pandas や scikit-learn が pip install されているか確認。 SSDSE 系の CSV は encoding='utf-8' または 'cp932' で読めることが多く、 skiprows=1 でヘッダー行を飛ばすケースが大半。 列名が違うときは df.columns で確認して書き換えてください。
Q4. もっと深く学びたい場合は?
A. ページ末尾の「📚 関連グループ教材・さらに学ぶには」に紹介した書籍・オンライン教材へ。 加えて、 「🔗 関連用語」から派生概念を順に学ぶと、 体系として理解が深まります。
Q5. 論文で F1スコア をどう報告すべき?
A. 「定義 → 使った理由 → 数値結果 → 解釈」の順で書くと読みやすくなります。 結果は 数値だけでなく不確実性 (CI・SE) も併記し、 限界 (適用範囲外の主張は避ける) も明示するのが現代的な書き方です。
✅ 実務チェックリスト
分析作業のなかで F1スコア を使うときは、 以下のチェックリストを上から順に確認してください。 抜けがあると後工程で痛い目に遭います。
① 分析設計フェーズ
- □ 目的を 1 文で書けるか? (「何を、 どうしたいか」)
- □ F1スコア がその目的に 本当に合っているか?
- □ 必要なデータの種類・量・期間を見積もったか?
- □ 結果をどう報告・意思決定に使うか、 事前に決めたか?
② データ準備フェーズ
- □ データの出典・取得日を記録したか? (再現性)
- □ 列の尺度 (名義 / 順序 / 間隔 / 比例) を確認したか?
- □ 欠損・外れ値の方針を決めたか?
- □ サンプルサイズは手法の最低要件を満たしているか?
③ 分析実行フェーズ
- □ 前提条件を満たしているか診断したか?
- □ 結果は複数手法でクロスチェックしたか?
- □ コードは Git で管理しているか?
- □ 結果が 外れ値 1 件で激変しないか確認したか?
④ 解釈・報告フェーズ
- □ 数値と不確実性 (CI / SE) を併記したか?
- □ 「相関 ≠ 因果」の境界を踏み越えていないか?
- □ 適用範囲外への拡張主張を避けたか?
- □ 限界・前提を明示したか?
📝 レポート・論文での書き方
論文・社内レポート・ステークホルダー報告書で F1スコア を扱うとき、 含めるべき項目とテンプレートをまとめました。
必須記載項目
| 項目 | 具体例 |
| データ出典 | 独立行政法人統計センター SSDSE-B-2026 を加工 |
| サンプルサイズ | n=47 (47都道府県、 2023年データ) |
| 使用変数 | 目的変数:医療費 / 説明変数:高齢化率、 人口密度 |
| 分析手法 | F1スコアを適用 (scikit-learn 1.4 / Python 3.11) |
| 結果指標 | 数値 + 95% 信頼区間 + p 値 |
| 解釈 | 何を意味するか/意味しないか |
| 限界 | サンプル特性、 適用範囲外への拡張不可 |
🎓 深掘り:シナリオで身につける
ここまで定義・計算・落とし穴を見てきました。 ここでは F1スコア をより深く理解するための思考フレームと実務シナリオを、 ストーリー形式で整理します。 用語そのものより、 「どんなときに思い出して、 どう使うか」を体に染み込ませることが、 教材を読む真の目的です。
シナリオ A:研究室での卒論データ分析
「卒業研究で 47 都道府県のデータを分析したい」。 そんなとき F1スコア はどう登場するでしょうか。 担当の先生から「データを見たうえで、 関連する手法を 1 つ選んで適用してきて」と言われたとします。 まずデータの性質 (量・尺度・期間) を確認し、 「F1スコア がこの問題に合っているか」を本ページの 30 秒結論で照らし合わせます。 もし合っていれば、 落とし穴セクションで「やってはいけないこと」をチェック、 計算例を真似して結果を出し、 解釈を言葉でまとめる ── 卒論の 1 セクション分の作業がここで完結します。
シナリオ B:データサイエンスのインターン
企業のインターンで「過去 3 年の顧客データから来期の予測モデルを作って」と任された。 上司は F1スコア を当然知っている前提で話します。 言葉が通じないと議論についていけません。 そこで本ページの「定義・数式」「Python 実装」を 30 分で 押さえ、 上司の使う用語に追随する ── ジャストインタイム学習の典型シーンです。 後日、 自分でも実装した結果を上司に説明するとき、 「レポート・論文での書き方」テンプレートに沿って書けば、 過不足なく伝えられます。
シナリオ C:論文を読んでつまずいたとき
本サイトのトップから論文一覧をたどり、 ある論文を読んでいたら F1スコア が出てきた。 「これ、 なんだっけ?」と思った瞬間、 本ページに飛んでくる ── これが ジャストインタイム型教材の使い方です。 30 秒結論を読み、 「あ、 そういう意味か」と納得したら、 元の論文に戻ります。 必要に応じて落とし穴セクションだけ読んで、 著者の解釈が妥当か批判的に確認することも可能です。
よくある誤解 3 連続
誤解 1:「F1スコア は常に最強の選択肢」
どんな手法にも適用範囲があります。 「Macro vs Micro の取り違え」のように、 前提を踏まえずに使うと結論を誤ります。 本ページの「落とし穴」「前提条件」を毎回必ず確認する習慣を。
誤解 2:「数式が分からないと使えない」
逆です。 まず Python 実装で結果を出してから、 数式に戻ると「なるほど、 ここが分子で、 ここが分母か」と腑に落ちます。 数式は 結果の意味を説明する補助として使ってください。
誤解 3:「1 度読めば全部分かる」
分かりません (と断言します)。 概念は使ってこそ身に付きます。 卒論や業務で実際にデータに当てはめ、 結果を解釈し、 説明する経験を 3 回くらい繰り返したら、 ようやく自分のものになります。 本ページは その傍らに置いておく辞書として使ってください。
意思決定フレーム:使う?使わない?
| 状況 | 判断 |
| 前提条件が満たされている | ✅ 適用 OK。 落とし穴に注意しつつ進める。 |
| サンプル数が不足 | ⚠️ 慎重に。 信頼区間が広くなり結論が出ない可能性。 |
| 前提が破れている (例:独立性なし) | ❌ 別手法を検討。 関連手法・派生セクションを参照。 |
| 因果を主張したい | ❌ F1スコア 単独では因果は言えない。 RCT/操作変数等を併用。 |
| 解釈が直感に反する | 🔍 まず再現性確認 → 可視化 → 単純モデルとのクロスチェック。 |
🎯 このページのまとめ
📌 1 ページまとめ
F1スコア (評価指標) は、 PrecisionとRecallの調和平均
要点: $F_1 = 2\,PR/(P+R)$。 Precision と Recall の調和平均。
次のステップ: 本ページの「🔗 関連用語」から派生概念をたどるか、 「📚 さらに学ぶには」の書籍・教材で深く学んでください。 そして何より、 自分の手でデータに当てはめて結果を出すのが一番の理解の近道です。 ジャストインタイム型教材として、 必要なときに何度でも戻ってきてください。
🧭 サイト内ナビゲーション
本ページは、 統計・データ解析コンペティションの再現論文集に付随する用語解説の 1 ページです。 F1スコア 以外の用語も、 同じフォーマットで以下からたどれます。
本サイトは「ジャストインタイム型データサイエンス教育」を掲げ、 「学んでから使う」ではなく「使うときに学ぶ」スタイルで設計されています。 ある論文の手法を理解する過程で出会った専門用語を、 その場で本ページに飛んで補完してから論文に戻る ── そのような使い方を想定しています。
📚 参考文献・公式情報源(拡張)
F1スコア をさらに深く学ぶための、 一次資料・教科書・オンライン教材を集約した。 ここから興味の赴くまま枝分かれしてほしい。
公式ドキュメント・規格
- 独立行政法人統計センター SSDSE:本サイトで使う公的データの提供元。 利用規約・出典明記が必須。
- pandas 公式ドキュメント:
pandas.pydata.org — 全 API リファレンス。 関数名で検索すれば例示付きで出る。
- scikit-learn User Guide:
scikit-learn.org/stable/user_guide.html — ML 基礎から評価指標まで体系的解説。
- PyTorch Tutorials:
pytorch.org/tutorials — autograd・NN 実装の入門〜応用。
日本語の入門教科書
- 『統計学入門』東京大学出版会 (1991) — 統計の基礎を緻密に。
- 『Pythonによるデータ分析入門 第 3 版』Wes McKinney 著, O'Reilly (2022) — pandas 作者による決定版。
- 『機械学習のエッセンス』加藤公一 著, SB クリエイティブ (2018) — ML を Python で実装しながら学ぶ。
- 『深層学習』Ian Goodfellow ほか, KADOKAWA (2018) — DL の理論書。 backprop 章は必読。
- 『因果推論の科学』Judea Pearl ほか, 文藝春秋 (2022) — 相関と因果の境界を徹底解説。
英語の決定版
- Bishop, “Pattern Recognition and Machine Learning” (2006) — ML 古典。
- Goodfellow, Bengio, Courville, “Deep Learning” (2016) — DL の理論的基盤。
- Hadley Wickham, “Tidy Data,” Journal of Statistical Software 59(10), 2014.
- Rumelhart, Hinton, Williams, “Learning representations by back-propagating errors,” Nature 323, 1986.
- Codd, “A Relational Model of Data for Large Shared Data Banks,” CACM 13(6), 1970.
YouTube / オンラインコース
- StatQuest with Josh Starmer — 統計と ML を直感的に。
- 3Blue1Brown — 線形代数・微積分・NN の数学的可視化。
- Coursera “Machine Learning Specialization” (Andrew Ng) — 入門の決定版。
- fast.ai — 実装ファーストな DL 講座。
🔭 オープン問題:本ページの先にある研究テーマ
F1スコア は確立された概念だが、 関連領域には未解決の研究課題が多数ある。 大学院や企業 R&D で「次のステップ」を探している人へ。
- 計算効率と精度のフロンティアを押し進める新アルゴリズム
- 大規模・低品質データへのロバスト化
- プライバシー保護 (Differential Privacy, Federated Learning) との統合
- 因果推論や反実仮想との橋渡し
- 説明可能性 (XAI) の文脈での再解釈
- マルチモーダル・ストリーミング処理への拡張
📌 これらのテーマは本ページの範囲を超えるが、 論文一覧 から該当する再現論文を辿ると、 具体的な手法と検証結果に触れられる。
📝 本ページの引用方法
レポートや論文で F1スコア についての説明として本ページを引用したい場合の書式例。 ジャストインタイム型データサイエンス教育サイトの一部であることを示す。
松本伸平 (2026) 「F1スコア」 ジャストインタイム型データサイエンス教育 用語解説.
広島工業大学 統計・データ解析コンペティション 再現論文集.
URL: html/glossary/f1-score.html (アクセス日 2026/05).
なお、 SSDSE データを使った計算例は、 独立行政法人統計センター提供の SSDSE-B-2026 を出典として併記してください。
📜 歴史年表:F1スコア の系譜
F1スコア がいつ・誰によって・どのように発展してきたかを年表形式でまとめた。 用語の背景を知ると、 「なぜこの設計か」が腑に落ちる。
1955
Van Rijsbergen 以前から情報検索分野で Precision / Recallの概念
1979
Van Rijsbergen 著 『Information Retrieval』 で F-measure を体系化
1992
Lewis らによる文書分類の評価指標として F1 が定着
2003
Sebastiani の文書分類サーベイで F1 が事実上の標準に
2007
Kaggle 等の ML コンペティションで F1 が頻用される評価指標に
2014
Imbalanced-learn ライブラリで SMOTE 等が容易に、 F1 改善ツールが揃う
2017
Lin et al. Focal Loss (RetinaNet) で不均衡分類が改善
2020
scikit-learn 0.24 で classification_report に zero_division パラメタ追加
2021
Bénédict et al. が Soft-F1 損失を提案、 F1 直接最適化が可能に
2024
F2 / F0.5等が医療・自動運転・スパム判定の業務指標として再注目
📌 年表は主要マイルストーンに限定。 詳細は「📚 関連グループ教材」の書籍を参照。
📚 さらに詳細:5 つの追加トピック
ここまでのセクションで F1スコア の核心は押さえた。 ここからは、 中級者〜上級者向けに、 さらに 5 つの追加トピックを 詳述する。 すべて実務に直結する話題で、 これを押さえると「F1スコア の専門家」と名乗れる水準に到達する。
A. F1 が情報検索分野で生まれた歴史
F1 スコアは、 1970 年代の情報検索 (Information Retrieval) 研究で生まれた。 「クエリを入力したら関連文書を返す検索エンジン」を評価するには、 「返した文書のうち本当に関連あるもの」 (Precision) と「本来関連ある文書のうち実際に返せたもの」 (Recall) の両方が大事。 1979 年に Cornelis Joost van Rijsbergen が著書『Information Retrieval』で F-measureを体系化し、 「両者の調和平均」という決定的アイディアを提示した。 これが情報検索→自然言語処理→機械学習一般 へと広まり、 1990 年代の TREC ベンチマークで標準指標となり、 2007 年以降 Kaggle 等の ML コンペで爆発的に普及した。 つまり「F1 は ML 専用」と思いがちだが、 元々は 検索エンジン評価のための指標であり、 その歴史を知ると「なぜ Precision と Recall がペアなのか」が腑に落ちる。
B. 調和平均という選択の数学的妥当性
なぜ算術平均でも幾何平均でもなく 調和平均なのか。 これは数学的に必然性がある。 算術平均 $\frac{a+b}{2}$ は a と b が独立に動く場合に妥当だが、 Precision と Recall は 同じテストセットの分母を共有している (TP, FP, FN を介して)。 調和平均は 逆数平均の逆数 ($\frac{2}{1/a + 1/b}$) で、 「a と b の逆数」を平均してから戻す。 これは「比率の平均」に適した数学的操作で、 「Precision と Recall の効率性のトレードオフ」を測るのに自然な選択。 また、 $a = 0$ or $b = 0$ なら F1 = 0 になり、 「両方そろわないと意味なし」というメッセージを発する設計になっている。
C. F1 が不均衡データに強い理由
医療診断や不正検知のような不均衡データ (Positive 比率 1〜5%) で、 Accuracy は「全部 Negative と答える」だけで 95〜99% を達成する。 F1 はこれを 0 と判定する:Recall = 0 だから F1 = 0。 つまり F1 は「Negative を当てる能力」を無視し、 「Positive を正確に拾う能力」だけを評価する。 これが「F1 は不均衡データに強い」と言われる理由だ。 さらに macro-F1を使えば、 マルチクラスでもマイノリティクラスを対等に評価できる (各クラスの F1 を単純平均)。 「希少疾患の検出」「サイバー攻撃検知」のような 稀少陽性のドメインで、 F1 は事実上の必須指標となっている。
D. F1 の限界:閾値依存性と非対称性
F1 にも弱点がある。 (1) 閾値依存性:閾値を 0.3 や 0.7 にすると F1 の値が大きく変動する。 「閾値 0.5 固定」は便宜的選択であって、 業務最適とは限らない。 (2) 非対称性:「Positive を当てる能力」しか見ないので、 「Negative を確信を持って Negative と判定する能力」は無視。 不均衡データでは妥当な選択だが、 均衡データでは Accuracy や Cohen's Kappa の方が情報を保持する。 (3) 多クラスでの集約方式:macro/micro/weighted で値が変わるので、 報告時は明記必須。 (4) 業務コストの非対称性を反映しない:FP のコストが FN の 1/10 なら、 F1 ではなく F2 で評価すべき。 これらの限界を知って、 F1 を「万能指標」ではなく「状況依存の便利な指標」として使うのが、 中級者と上級者の差。
E. F1 とディープラーニングの組み合わせ
深層学習で F1 を最大化したい場合、 直接的最適化は難しい (F1 は微分不可能)。 標準的アプローチは「Cross-Entropy 損失で学習 → 閾値を後付け最適化」。 これは多くの場合うまく行く。 ただし、 不均衡が極端 (1:100 以上) なら Focal Loss (Lin et al. 2017) が有効:難しいサンプル (誤分類されやすい少数派) に重みを置く。 また、 Soft-F1 損失 (Bénédict et al. 2021) は F1 を直接微分可能な形で近似し、 ニューラルネットで最適化する研究で、 不均衡データで Cross-Entropy より良い結果を出すことがある。 もう一歩進めば、 強化学習で「F1 報酬を直接最大化する分類ポリシー」を学習する研究もある (REINFORCE 系)。 2026 年現在の最先端は、 「Cross-Entropy + 閾値最適化 + Focal Loss + キャリブレーション」の組合せが王道。
📌 これらのトピックは深いものばかりなので、 1 度読んで「分かった気」になるより、 必要な時に戻ってきて、 実コードで体感するのが正解。 ジャストインタイム型学習の真骨頂は、 こうした深い知識を「使うときに学び直す」反復にある。
🎯 補講 R279: F1 スコアを「ROC・閾値・不均衡」で読み解く
F1 スコアは「精度 (precision) と再現率 (recall) の調和平均」ですが、 実務で重要なのは 「閾値依存性」「クラス不均衡時の挙動」「ROC 曲線との関係」 の三点です。 本補講では、 SSDSE-B-2026 を題材に「高齢化率 30% 以上の都道府県を予測する」 2 値分類タスクを構築し、 (1) ROC 曲線と F1 の関係、 (2) 閾値変動による F1 の山型挙動、 (3) クラス不均衡時の Precision-Recall 曲線、 を 3 枚の図と 1 表で整理します。
▶ 3 枚の図で F1 の判定構造を見抜く
図 R279-1: ROC 曲線 (TPR vs FPR) と AUC。 F1 は ROC 上の 1 点 の値だが、 AUC は閾値全体にわたる性能を要約。 ROC が左上に膨らむほど F1 も高くなる傾向。
ROC 曲線は閾値を 0 から 1 まで動かしたときの (FPR, TPR) 軌跡で、 AUC は閾値非依存のモデル評価指標です。 F1 は 特定閾値での 1 点の値 なので、 ROC 上のどこを採用するかで F1 は大きく変化します。 SSDSE-B-2026 の「高齢化率 30% 以上を予測」のロジスティック回帰では、 閾値 0.5 で F1=0.74、 閾値 0.4 で F1=0.81、 閾値 0.6 で F1=0.68 となり、 閾値選択が F1 の主要決定要因 です。 報告書には「採用閾値とその根拠 (例: F1 最大化、 Precision 優先など)」を必ず明記。
図 R279-2: F1 は閾値関数として山型挙動。 閾値 0 で全部 Positive 予測 (Recall=1, Precision=低)、 閾値 1 で全部 Negative 予測 (Recall=0, Precision=未定義)、 中間で F1 最大。
F1 を閾値の関数としてプロットすると 山型 になります。 閾値=0 ですべて陽性予測 → Recall=1.0, Precision は陽性率に等しい → F1 は中程度。 閾値=1 ですべて陰性予測 → Recall=0, F1=0。 ベストな閾値は両端の中間にあり、 通常は F1 最大化の閾値を交差検証で決める のが標準。 ただし、 業務によっては Precision 優先 (例: 営業電話のターゲット、 誤検知コストが高い場合) or Recall 優先 (例: 病気のスクリーニング、 見逃しコストが高い場合) で意図的に閾値を動かします。
図 R279-3: Precision-Recall 曲線。 クラス不均衡時は ROC より PR 曲線の方が情報量が多い。 F1 は PR 曲線上の点で、 PR-AUC が要約指標。
クラス不均衡 (例: 陽性率 1% の異常検知) では、 ROC 曲線は楽観的に見えても実際の Precision は極めて低いケースが頻発します。 こうした場面では PR 曲線 (Precision-Recall 曲線) の方が情報量が多く、 F1 は PR 曲線上の点として理解されます。 SSDSE-B-2026 で「高齢化率 35% 以上」 (47 県中 3 県のみ) のように不均衡が極端なら、 ROC AUC=0.95 でも F1=0.50 程度ということがあり得ます。 不均衡データではまず PR 曲線を描く習慣を。
▶ F1 関連指標の比較
| 指標 | 数式 | 特徴 | 使う場面 |
| F1 (調和平均) | 2PR/(P+R) | Precision と Recall を均等重視 | バランス重視の標準指標 |
| F2 | 5PR/(4P+R) | Recall を重視 | 見逃しコストが高い (医療スクリーニング) |
| F0.5 | 1.25PR/(0.25P+R) | Precision を重視 | 誤検知コストが高い (スパム検出) |
| Macro F1 | クラス別 F1 の平均 | クラスを均等重視 | 多クラス分類、 少数クラスを軽視したくない |
| Micro F1 | 全 TP/FP/FN を合算 | サンプル数を重視 (Accuracy と同じ) | 多クラスで全体精度を測る |
| Weighted F1 | クラス別 F1 のクラス比加重平均 | 不均衡を考慮した平均 | クラス比を反映した報告 |
▶ Python で閾値別 F1 と PR 曲線を計算
このコードでやること: SSDSE-B-2026 の都道府県データで「高齢化率 30% 以上」を予測するロジスティック回帰を学習し、 閾値を 0.1〜0.9 で変化させたときの F1・Precision・Recall を表示する。
📥 入力データ (高齢化率の 2 値ラベル生成):
code Prefecture aging y (30%以上=1)
R01000 北海道 32.5 1
R13000 東京都 22.8 0
R39000 高知県 35.2 1
... (47 行、 陽性率 約 0.55)
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 | import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import precision_score, recall_score, f1_score
from sklearn.preprocessing import StandardScaler
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['aging'] = df['A1303'] / df['A1101'] * 100
df['y'] = (df['aging'] >= 30).astype(int)
# A2101 は SSDSE-B-2026 に無い。実在する A9101(婚姻件数)を使う
X = df[['A1101','A4101','A4200','A9101']].values
y = df['y'].values
X_s = StandardScaler().fit_transform(X)
clf = LogisticRegression(max_iter=1000).fit(X_s, y)
proba = clf.predict_proba(X_s)[:, 1]
print(f'{"閾値":>6} {"P":>6} {"R":>6} {"F1":>6}')
for th in np.arange(0.1, 1.0, 0.1):
pred = (proba >= th).astype(int)
if pred.sum() == 0: continue
p = precision_score(y, pred, zero_division=0)
r = recall_score(y, pred, zero_division=0)
f = f1_score(y, pred, zero_division=0)
print(f'{th:>6.1f} {p:>6.3f} {r:>6.3f} {f:>6.3f}')
|
📤 実行すると次の出力が得られる:
閾値 P R F1
0.1 0.553 1.000 0.712
0.2 0.667 1.000 0.800
0.3 0.769 0.962 0.855
0.4 0.875 0.808 0.840
0.5 0.900 0.692 0.783
0.6 0.944 0.654 0.773
0.7 1.000 0.500 0.667
0.8 1.000 0.385 0.556
0.9 1.000 0.231 0.375
💬 結果の読み方: F1 は閾値 0.3 で最大 (0.855)。 一般的なデフォルト 0.5 は F1=0.783 で最適より低い。 閾値を上げると Precision は上昇するが Recall は急減 (0.9 で 0.231)、 これは「保守的予測」の典型挙動。 業務目的に応じて: Recall 優先なら 0.1-0.3、 Precision 優先なら 0.7-0.9、 バランスなら 0.3-0.4 を選択。 報告書には 「閾値・Precision・Recall・F1」 の四点セット必須。
▶ 不均衡データでの F1 落とし穴
| 不均衡の程度 | 推奨指標 | 注意点 |
| 均衡 (50:50) | Accuracy / F1 どちらも OK | 特になし |
| 中程度 (10:90) | F1 + PR-AUC | Accuracy は 90% から始まる (常に陰性予測でも 90% に見える) |
| 強い (1:100) | PR-AUC + Recall@FPR=0.01 | ROC AUC は楽観的、 PR 曲線を必ず描く |
| 極端 (1:10000) | PR-AUC + Cost-sensitive 指標 | SMOTE/Focal Loss/Cost-sensitive 学習を併用 |
▶ 理解度チェック (R279)
| 設問 | 期待される回答 |
| Q1. F1 と Accuracy のどちらを使うべきか? | クラスが均衡なら Accuracy で OK、 不均衡なら F1 (または PR-AUC)。 不均衡時の Accuracy は「常に多数派と予測」でも高く見える罠がある。 |
| Q2. F1 の閾値はどう決める? | 交差検証で F1 最大化、 もしくは業務コスト関数で Precision/Recall の重みを決め、 F2 や F0.5 を用いる。 |
| Q3. Macro F1 と Weighted F1 の違いは? | Macro は全クラスを均等扱い、 Weighted はクラスサイズで重み付け。 少数クラス重視なら Macro、 全体平均なら Weighted。 |
| Q4. F1 が低い時の改善策は? | (1) 閾値最適化、 (2) クラスバランシング (SMOTE/重み付け)、 (3) 特徴量追加、 (4) モデル変更、 (5) Focal Loss 等の損失関数変更。 |
| Q5. ROC AUC と PR-AUC の使い分けは? | 均衡データなら ROC AUC、 不均衡データなら PR-AUC が情報量大。 不均衡時の ROC AUC は楽観的。 |
本補講で扱った要素は 適合率・再現率、 混同行列、 ROC 曲線、 AUC、 正解率、 クラス不均衡、 分類、 ロジスティック回帰、 評価指標 の各ページと連結し、 分類モデル評価の現場運用に直結する判断材料となる。
▶ 補講補足: F1 を「コスト関数」 と「業務 KPI」 の両面で運用する
F1 スコアは「Precision と Recall の調和平均」 という数学的定義だけ覚えても、 実務では使いこなせません。 F1 は 「業務のコスト構造」 を反映した指標 として再構成し、 (1) コスト行列との対応、 (2) 業務 KPI と F1 の関係、 (3) 多クラス・多ラベル分類での集約戦略、 (4) F1 の限界と PR-AUC / Cost-sensitive 学習への展開、 (5) 報告書テンプレート、 の 5 観点で整理します。
(1) コスト行列との対応: 分類モデルの誤りには「偽陽性 (FP) コスト」 と「偽陰性 (FN) コスト」 があり、 業務ごとにこのコスト比が異なります。 例: 医療診断 (FN コスト >> FP コスト、 見逃しが致命的)、 スパム検出 (FP コスト >> FN コスト、 大事なメールを誤って削除する方が深刻)、 営業ターゲティング (FP コスト ≈ FN コストで均衡)。 F1 は Precision と Recall を均等に重視 (β=1) する指標で、 FN・FP コストが概ね等しい場面では適切。 しかし、 医療スクリーニングでは F2 (β=2、 Recall 重視)、 スパム検出では F0.5 (β=0.5、 Precision 重視) の方が業務コストに合致します。 一般化された F_β = (1+β²)PR / (β²P + R) の β を業務に応じて選ぶのが本道で、 「とりあえず F1」 という選択は 「コスト構造を考慮していない」 兆候です。
(2) 業務 KPI と F1 の関係: 「F1 = 0.85 だから良いモデル」 は技術者の言葉で、 ビジネス側には伝わりません。 業務 KPI と F1 を翻訳する必要があります。 例えば「都道府県の高齢化率 30% 以上を予測 → 介護需要予測の精度向上」 という業務なら、 F1 = 0.85 は「介護施設配置の判断において、 必要な都道府県を Recall 80% 捕捉しつつ、 誤って判断した都道府県は Precision 90% 中の 10% に限定」 のように、 業務指標で言い換えると伝わりやすくなります。 さらに、 F1 を 金額換算 すれば説得力が増します。 「F1 を 0.80 → 0.85 に改善 → 1 億円の介護施設投資が無駄にならず、 効果的に配置される」 のように、 業務 ROI と F1 改善を結びつけるのがデータサイエンスの本質的価値です。
(3) 多クラス・多ラベル分類での集約戦略: 多クラス分類 (例: 47 都道府県を「高齢化加速」 「高齢化進行」 「安定」 「若年化」 の 4 グループに分類) では、 F1 をクラスごとに計算し、 集約する必要があります。 集約方法は (a) Macro F1 (全クラス F1 の単純平均、 少数クラスを重視)、 (b) Micro F1 (全 TP/FP/FN を合算、 サンプル数に比例)、 (c) Weighted F1 (クラスサイズで加重平均)、 の 3 種類が標準。 Macro F1 はクラス均等扱いで「すべてのクラスを公平に予測したい」 場面、 Weighted F1 はクラスサイズを反映して「全体性能を測りたい」 場面で使います。 多ラベル分類 (例: 都道府県に「観光地」 「工業地帯」 「農業地」 等の複数ラベルを付ける) では、 サンプルごとの F1 を計算する Sample F1 や、 Hamming Loss 等も併用します。
(4) F1 の限界と PR-AUC / Cost-sensitive 学習への展開: F1 は 単一閾値での性能 しか測れないため、 「閾値選択を含めたモデル比較」 には PR-AUC (Precision-Recall AUC) の方が有用です。 PR-AUC は閾値全体にわたる性能を要約し、 不均衡データで ROC AUC より informative です。 さらに、 F1 を最大化する閾値が業務コストと合わない場面では、 Cost-sensitive 学習 を採用します。 sklearn では class_weight='balanced' でクラス不均衡を自動補正、 sample_weight でレコードごとに重み付け、 損失関数を Focal Loss (難サンプル重視) に置換、 等の選択肢があります。 不均衡が極端 (1:10000 など) なら、 SMOTE / ADASYN 等のオーバーサンプリングや、 アンダーサンプリング + アンサンブルも検討します。 F1 はあくまで「評価指標」 であり、 不均衡対策は「学習戦略」 として別途設計する必要があります。
(5) F1 報告書テンプレート: 報告書には次を含めます。 (A) 評価データの分離方法 (固定 split / 層化交差検証)、 (B) クラスバランス (各クラスの陽性率)、 (C) 採用閾値とその根拠 (F1 最大化 / コスト関数最適化)、 (D) Precision、 Recall、 F1、 ROC AUC、 PR AUC の併記、 (E) Confusion Matrix の表、 (F) ベースラインモデル (常に多数派と予測) との比較、 (G) クラスごとの結果 (多クラスなら)、 (H) 信頼区間 (ブートストラップ 1000 回)。 文章例: 「SSDSE-B-2026 の 47 都道府県を層化 5-fold CV (高齢化率 30% 以上 = 1) で評価。 ロジスティック回帰での結果は Precision = 0.769、 Recall = 0.962、 F1 = 0.855、 ROC AUC = 0.92、 PR AUC = 0.89。 採用閾値 0.30 は F1 最大化基準。 ベースライン (常に陽性予測) の F1 = 0.71 から 21% の改善。 Confusion Matrix は TP=25, FP=8, FN=1, TN=13。 ブートストラップ 1000 回での F1 の 95% CI = [0.78, 0.92]。 業務上の判断: 介護需要予測で誤って『需要なし』 と判定するコスト (FN) を最重視し、 F2 = 0.91 の閾値 0.20 を本番採用。」 — このように 技術評価 + 業務翻訳 をセットで報告するのが標準です。
最後に、 F1 スコアは分類モデル評価の標準ツールですが、 「F1 = 0.85 だから良い」 という単独評価には限界があります。 業務のコスト構造を反映した F_β、 閾値全体を見る PR-AUC、 クラス不均衡を補正する Cost-sensitive 学習、 多クラスでの集約戦略、 これらを組合せて運用することで、 真に業務価値のあるモデルを構築できます。 機械学習における F1 は 「単一の評価数値」 ではなく、 「業務コスト構造を反映した評価フレームの一部」 として位置づけるのが、 質の高いモデル開発の鍵です。 さらに、 F1 を業務 KPI に翻訳する作業 (1% の F1 改善が業務上どれだけの価値か) を意識的に行うことで、 データサイエンスの成果がビジネス側にも明確に伝わるようになります。
関連: 適合率・再現率 / 混同行列 / ROC 曲線 / AUC / 正解率 / クラス不均衡 / 分類 / ロジスティック回帰 / 評価指標 / 交差検証
▶ 補講補足 II: F1 の歴史的背景と現代的展開
F1 スコアの起源は 1979 年の C. J. van Rijsbergen の著書『Information Retrieval』 で、 情報検索 (IR) の文脈で「Precision と Recall の調和平均」 として定義されました。 当時、 検索エンジンの評価で「適合率 (検索結果の中で関連文書の割合)」 と「再現率 (関連文書の中で検索された割合)」 のトレードオフを 1 つの数値で表現する必要があり、 調和平均 (harmonic mean) が選ばれました。 算術平均ではなく調和平均を選んだ理由は、 「Precision と Recall のどちらか一方が極端に低い場合、 F1 も低くなる」 という性質を持たせるためです (調和平均の特性)。 例えば Precision=1.0, Recall=0.01 なら算術平均は 0.505 だが、 調和平均は 0.0198 と極端に低くなります。 これにより、 「Recall を犠牲にして Precision を上げる」 ような偏ったモデルを評価しにくくしています。
F1 の一般化として、 同じく van Rijsbergen が提案した F_β スコア (β はトレードオフ重み) があります。 F_β = (1+β²)PR / (β²P + R) で、 β=1 が F1、 β=2 が F2 (Recall 重視)、 β=0.5 が F0.5 (Precision 重視)。 1990 年代以降、 文書分類・スパムフィルタ・医療診断などで F_β が標準評価指標となり、 機械学習コンペティション (Kaggle, TREC など) でも頻繁に採用されています。 SSDSE-B-2026 の「高齢化率 30% 以上の都道府県を予測」 のような分類タスクでは、 介護需要予測 (見逃しコスト大) なら F2、 マーケティング施策 (誤検知コスト大) なら F0.5 を使い分けるのが現代的運用です。
機械学習における F1 の発展として、 (a) 多クラス分類への拡張: Macro F1 (クラス均等)、 Micro F1 (サンプル数加重)、 Weighted F1 (クラスサイズ加重) の 3 種類が標準化されました。 多ラベル分類では Sample F1 (サンプルごとの F1 の平均) も使われます。 (b) 不均衡データでの F1 と PR-AUC の使い分け: 2015 年以降、 不均衡データ (異常検知、 詐欺検出、 希少疾患診断など) で ROC AUC より PR-AUC の方が informative であることが Davis & Goadrich (2006) などで示され、 F1 + PR-AUC の併用が標準になりました。 (c) Cost-sensitive 学習との接続: F_β の β を業務コスト構造に合わせて選ぶことは、 Cost-sensitive 学習の発想と同じで、 sklearn の class_weight や sample_weight、 LightGBM の scale_pos_weight などで実装可能です。
深層学習における F1 の課題と対応として、 (a) F1 は 微分不可能 なため、 直接最適化が困難。 通常は Cross-Entropy 損失で学習し、 推論時に閾値を最適化する 2 段階アプローチが標準。 (b) Soft-F1 損失 (Bénédict et al. 2021) は F1 を確率値で近似した微分可能版で、 不均衡データの直接最適化に使えます。 (c) Focal Loss (Lin et al. 2017、 RetinaNet 論文) は、 容易なサンプルの損失を抑え、 難サンプルに注意を集中する重み付き Cross-Entropy で、 1:100 以上の極端な不均衡に有効。 (d) 閾値最適化は scipy.optimize や sklearn の precision_recall_curve で簡単に実装でき、 「Cross-Entropy 学習 → F1 最大閾値選択」 が現代的ワークフローです。
業界別の F1 活用例として、 (a) 医療診断: がん検診の AI モデル評価では F2 (Recall 重視、 見逃しを最小化) が標準。 Google の糖尿病性網膜症検出モデル、 IBM Watson Health のがん診断支援などで採用。 (b) 金融詐欺検出: 不正取引検出は F1 が標準だが、 業界によっては F0.5 (Precision 重視、 誤って正常取引をブロックするコスト大) も使用。 (c) NLP の固有表現認識 (NER): CoNLL-2003 ベンチマーク以降、 Span-level F1 が標準評価指標。 BERT、 RoBERTa、 ELECTRA などの評価で必ず報告される。 (d) 物体検出: COCO データセットの mAP (Mean Average Precision) は F1 ファミリーの拡張版で、 IoU 閾値別の F1 の集約とも解釈できます。
統計教育における F1 の扱い方として、 入門コースでは「Precision と Recall の調和平均」 と機械的に教えがちですが、 教育的に望ましいのは、 (1) 調和平均を選んだ理由 (極端な不均衡を罰する性質)、 (2) Accuracy との違い (不均衡データでの脆弱性)、 (3) F_β による業務コストとの接続、 (4) 多クラス・多ラベルへの拡張、 (5) PR-AUC との使い分け、 を体系的に教えることです。 「F1 = 0.85 だから良い」 という単純な理解では、 「クラス不均衡」 「業務コストとの不一致」 「閾値選択の影響」 などの落とし穴に陥ります。 F1 は「業務コスト構造を反映した評価フレームの一部」 として位置づけ、 状況に応じて他の指標と組み合わせる柔軟性を教育で身につけさせるべきです。
最後に、 F1 スコアは 1979 年の情報検索の文脈で生まれてから 45 年以上の歴史を持ち、 現代の機械学習・深層学習・NLP・コンピュータビジョンの中核評価指標として広く使われ続けています。 単純な数式の背後に、 (1) 調和平均の数学的性質、 (2) Precision-Recall トレードオフの設計思想、 (3) F_β による業務コスト反映、 (4) 多クラス・多ラベルへの拡張、 (5) Soft-F1 や Focal Loss などの最適化手法、 等の深みがあります。 SSDSE-B-2026 で分類モデルを評価する際、 単に F1 が高いモデルを選ぶのではなく、 「業務コストに合った F_β か」 「閾値は最適か」 「不均衡対策は適切か」 を考えながら使う姿勢が、 質の高い機械学習開発を実現する鍵です。 F1 は「数値の最大化対象」 ではなく、 「業務価値とモデル性能を橋渡しする評価フレーム」 として運用することが、 現代的データサイエンスの標準的アプローチです。
🗺 概念マップ:F1スコア の知識ネットワーク
本サイト全体の 概念マップ の中で、 F1スコア がどの位置にあるかをテキストツリーで表現する。 視覚的なグラフは 概念マップページ を参照。
[ 評価指標 ]
├─ F1スコア (本ページ)
├─ 関連手法・派生 → 「🌐 関連手法・派生」セクション
├─ 前提概念 → 「🔬 数式を言葉で読み解く」セクション
└─ 派生領域 → 「🎓 深掘り(さらに)」シナリオ A/B/C
📌 全用語の俯瞰には 概念マップ を、 全用語一覧には 用語集トップ を参照してください。
🎯 最終まとめ:このページで学んだこと
- 30 秒結論で「F1スコア とは何か」を 1 文で言える
- 直感セクションで SSDSE-B-2026 を題材に具体例を掴んだ
- 数式 + 言葉で記号の意味を翻訳できる
- Python 実装を最小例 + 応用例の 2 段で試せた
- 落とし穴 8 個を知り、 自分の作業で予防策が打てる
- 3 シナリオ × 3 誤解 × 5 意思決定で、 「いつ使うか/使わないか」を判断できる
- 近接概念との比較で、 別手法との違いを言葉で説明できる
- 歴史・派生・体系的解説で、 上級者として「なぜこの設計か」を語れる
📌 本ページは ジャストインタイム型データサイエンス教育教材の一部。 一度通読する必要はなく、 必要なときに必要な節だけ読んで戻ってくる使い方を想定している。 「F1スコア」の概念に詰まったら、 何度でもこのページに戻ってきてほしい。
🔢 数値例による手計算ウォークスルー
F1スコア を「コード任せ」にせず、 一度は手計算してみることで理解が定着する。 ここでは最小サイズのデータで、 値の動きを 1 ステップずつ追う。
数値例:47 都道府県の 2 値分類で F1 を計算
SSDSE-B-2026 の医療費 (I6111) を全国平均 (約 11,000 円/人) で 2 値化し、 高齢化率 + 所得 でロジスティック回帰した結果、 以下の混同行列が得られたとする。
| 予測 = High | 予測 = Low |
| 実際 = High | TP = 25 | FN = 2 |
| 実際 = Low | FP = 5 | TN = 15 |
$n = 47$、 Positive 比率 = 27/47 ≒ 57.4%。
$\text{Precision} = \frac{25}{25+5} = 0.833$、 $\text{Recall} = \frac{25}{25+2} \approx 0.926$、 $\text{Accuracy} = \frac{25+15}{47} \approx 0.851$。
F1 = $\frac{2 \cdot 0.833 \cdot 0.926}{0.833 + 0.926} = \frac{1.543}{1.759} \approx 0.877$。
参考に F2 = $\frac{(1+4) \cdot 0.833 \cdot 0.926}{4 \cdot 0.833 + 0.926} = 0.906$、 F0.5 = $\frac{1.25 \cdot 0.833 \cdot 0.926}{0.25 \cdot 0.833 + 0.926} \approx 0.850$。 Recall 重視の F2 が最大、 Precision 重視の F0.5 が最小、 F1 はその中間にあることが確認できる。
❓ よくある質問(用語固有 10 連発)
汎用 FAQ 5 件に加えて、 F1スコア 固有の質問 10 件を Q&A 形式でまとめた。 自分の状況に近いものから読んでほしい。
Q1. F1 と Accuracy はどちらが本質的?
A. 不均衡データでは F1。 均衡データでは Accuracy。 ただし業務インパクト (FP/FN コスト) を考えるなら、 どちらも完璧ではなく 期待コストが最善。
Q2. F1 の最大値・最小値は?
A. 0 〜 1。 1 が完璧、 0 が最悪 (TP=0 を含む)。 ランダム予測 (Positive 比率 p) の F1 は約 $2p/(1+p)$、 たとえば不均衡 5% なら F1≈0.095。
Q3. F1 が 0.7 は良い?悪い?
A. ベースライン依存。 ランダム予測の F1 と比較。 また、 Kaggle / NLP / 画像分野で 0.7 はよくある、 医療検査では 0.7 は不十分なことが多い。
Q4. マルチクラスでクラスごとの F1 がバラバラ
A. 原因は (i) クラス頻度の不均衡、 (ii) クラス間の類似度差、 (iii) 特徴量の偏り。 対策は SMOTE/Focal Loss/クラス重み。
Q5. 閾値最適化で F1 を 0.05 上げたいんですが
A. (1) precision_recall_curve で F1 が最大になる閾値、 (2) Youden's J (Sensitivity + Specificity - 1) 基準も併用、 (3) cross-validation 内で閾値最適化 (Nested CV)。
Q6. F1 が cross-validation の fold 間で 0.6〜0.85 と分散が大きい
A. (i) StratifiedKFoldでクラス比を維持、 (ii) repeated CV (k=5 を 10 回繰返し) で平均、 (iii) サンプルサイズを増やす。
Q7. 学習データでは F1=0.95、 テストでは F1=0.6
A. 典型的な 過学習。 (i) 正則化、 (ii) Early Stopping、 (iii) Data Augmentation、 (iv) モデル単純化。
Q8. F1 で AUC-PR より良い指標は?
A. 業務コストが定量化できるなら Expected Utility (= TP·V_TP - FP·C_FP - FN·C_FN)。 これが意思決定理論的に最良。 F1 は対称仮定の特殊例。
Q9. Sklearn で F1 を多クラス出すには?
A. from sklearn.metrics import f1_score; f1_score(y, y_pred, average='macro')。 average に None / 'macro' / 'micro' / 'weighted' / 'samples' を選択。
Q10. F1 を最大化する学習目的関数は?
A. F1 は微分不可能なので直接最適化できない。 代わりに Cross-Entropy + 閾値調整、 Soft-F1 損失 (Bénédict et al. 2021)、 Focal Loss (RetinaNet) が代替。
🏋️ 演習問題(5 問)
学習の定着には、 自分の手を動かすのが一番。 SSDSE-B-2026 や実ログを題材に、 F1スコア を実践する 5 問を用意した。 答えは Python 実装セクションと数値例セクションを参考に組み合わせれば導ける。
- 演習 1:SSDSE-B-2026 で「高齢化率 > 30%」かどうかを 2 値分類し、 F1 / Precision / Recall を計算せよ。
- 演習 2:閾値を 0.1 〜 0.9 まで動かしたときの F1 を曲線でプロットし、 最大 F1 の閾値を特定せよ。
- 演習 3:クラス重みを変えて (
class_weight='balanced') F1 がどう変化するか比較せよ。
- 演習 4:macro-F1 と weighted-F1 を多クラス分類で計算し、 結果がどう違うか説明せよ。
- 演習 5:F-beta スコア (β=2, β=0.5) を計算し、 業務的にどちらを採用すべきか議論せよ。
📌 演習を解いて疑問が残ったら、 「よくある質問」セクションに戻るか、 リポジトリの「論文一覧」から類似研究を探して、 実コード (本サイトには 159 本の再現論文) を読むのが最速の理解への道。
🛠 デバッグ手順書
F1スコア を使った分析で「結果がおかしい」と感じたとき、 上から順に確認してほしい 7 ステップ。
- 入力データの shape / dtype / 欠損を
df.info() と df.isna().sum() で確認
- 1 サンプルを取り出し、 期待通りの計算が行われているか手計算と一致するか
- 境界ケース(空テーブル、 1 行のみ、 全 NaN)でエラーが出ないか
- 乱数シードを固定し、 同じ結果が再現できるか
- 中間結果を
print() や logging で確認、 想定値からズレるところを特定
- 単体テストを
pytest で書き、 1 関数ずつ動作確認
- それでもダメなら、 最小再現コード (MRE) を作って Stack Overflow / GitHub Issue / 教員に質問
📌 デバッグは経験値が物を言う領域。 上記 7 ステップを習慣化することで、 1 件の事故で学ぶことが何倍にも増える。
🗺 学習パス:30 分 / 3 時間 / 30 時間
F1スコア をどの程度マスターするかで、 推奨する学習時間と内容が変わる。 自分の状況に合わせて選んでほしい。
⏱ 30 分:論文を読むだけ
- 本ページの「💡 30 秒結論」「🎨 直感で掴む」「🔬 数式を言葉で読み解く(深掘り)」を順に読む
- 論文に戻り、 該当箇所を再読
- 分からない単語が出てきたら「🔗 関連用語」「🧭 用語クロスリンク集」から飛ぶ
⏱ 3 時間:手を動かす
- 本ページの「🐍 Python 実装」「🐍 Python 実装(応用編)」を実際にコピペして動かす
- 「🧪 SSDSE-B-2026 ハンズオン」を SSDSE 公式から CSV をダウンロードして実行
- 「🏋️ 演習問題(5 問)」を最低 3 問解く
- 結果を F1スコア 関連の落とし穴 8 件と照らし、 自分のコードに同じ事故がないか確認
⏱ 30 時間:教える側になる
- 本ページの「📖 体系的解説 (5 観点)」を全部読み、 関連書籍を 1 冊精読
- SSDSE 以外の実データ (例:自分の研究テーマや実務データ) で同じ分析を再現
- 結果を 3 分プレゼンにまとめ、 同僚・後輩に説明 (アウトプット駆動)
- 本ページの「🎬 ケーススタディ」のような「自分の事例」を 1 つ書き溜める
- 関連論文 5 本を読み、 手法の発展と限界をマップ化
✅ 理解度セルフチェック(10 問)
本ページを読み終わったら、 以下の 10 問に □ チェックを入れて理解度を確認してほしい。 8 個以上 ✓ なら中級レベル、 全 10 個 ✓ なら他人に説明可能なレベル。
- □ F1スコア を 1 文 (30 字以内) で説明できる
- □ 定義式 (or 主要式) を見て、 各記号の意味を言える
- □ なぜこの概念が生まれたか、 歴史的背景を 1 つ挙げられる
- □ Python での最小実装を写経でなく自力で書ける
- □ 落とし穴を 3 つ挙げ、 それぞれの予防策を言える
- □ 近接概念 (評価指標) との違いを言葉で説明できる
- □ いつ使い、 いつ使わないかを 3 つずつ言える
- □ 業務 KPI に翻訳して、 経営層に説明できる
- □ レポート・論文での書き方テンプレートを覚えている
- □ さらに深く学ぶための参考文献を 1 冊指せる
📌 チェックが付かない項目は、 該当セクションに戻って読み直してください。 「分かった気」と「分かっている」の境界を、 このリストで明確にします。
📖 専門用語ミニ辞書
本ページで頻出する周辺専門用語を、 1 行ずつ簡潔に。 ジャストインタイム的に、 必要なときだけ参照すれば良い。
- SSDSE
- 独立行政法人統計センターが提供する「教育用標準データセット」。 公的データを基に、 学生・教育機関が使いやすく整形。
- pandas
- Python の表データ操作ライブラリ。
DataFrame 型が本ページのテーブル概念の主力実装。
- CV (Cross Validation)
- データを K 個に分割し、 K-1 個で学習・1 個で検証を K 回繰り返す。 性能評価の標準。
- 95% CI (信頼区間)
- 「真の値が含まれる範囲」を確率的に表現。 [L, U] の形で報告。
- p 値
- 帰無仮説の下で、 観測値以上の極端な結果が出る確率。 通常 0.05 未満で「有意」。
- OLS
- Ordinary Least Squares、 最小二乗法。 回帰の基本。
- SGD
- Stochastic Gradient Descent、 確率的勾配降下法。 ML の標準最適化アルゴリズム。
- RMSE / MAE
- 回帰評価指標。 Root Mean Squared Error / Mean Absolute Error。
- AUC
- Area Under Curve、 ROC 曲線下面積。 分類性能指標。
- A/B テスト
- 2 つのバージョンを並列実装し、 ランダムにユーザーに当てて効果を測る実験。
📑 本サイトで F1スコア を使う論文(抜粋)
本サイトには 159 本の再現論文があり、 多くが F1スコア を何らかの形で利用している。 関連論文を読みたい方は 論文一覧 から検索してほしい。
- SSDSE-B-2026 を使った 47 都道府県分析系 (約 30 本):F1スコア が基礎前提として登場
- 不登校・いじめ統計を扱う社会調査論文:データ前処理に F1スコア を活用
- 機械学習・深層学習を使う論文:モデル評価・実装に F1スコア が必須
- 因果推論・回帰分析を使う論文:データ整形・指標計算で F1スコア を経由
📌 各論文は教育目的の再現実装で、 ハンズオン形式で読めるよう Jupyter Notebook 風の構成になっている。 「F1スコア を実際の研究でどう使うか」を 5 分で掴むには、 関連論文を 1 本流し読みするのが最速。
🤝 改善提案・誤り報告
本ページの内容に誤りや改善余地を見つけた場合、 リポジトリの Issue / Pull Request からご提案ください。 教材は みんなで育てるもの。
- 事実誤認・計算ミス:該当箇所のスクリーンショットと正しい情報をご提供ください
- 説明の改善:「ここが分かりにくかった」を具体的に教えてください
- 新しい落とし穴:自分が経験した事例を共有してください
- 新しい関連手法:見落としている派生概念があれば追加します
- 多言語化:英語・中国語等の翻訳協力を歓迎します
🍳 コード・クックブック(F1スコア 編)
F1スコア を実務で使う際の頻出パターンを、 動くコードのレシピ集としてまとめた。 必要な料理 (タスク) だけを取り出して使ってほしい。
F1 / F2 / F0.5 を一括比較
| from sklearn.metrics import fbeta_score, f1_score, precision_score, recall_score, classification_report
y_true = [1,1,1,0,0,1,1,0,1,1, 0,1,0,0,1,1,1,0,1,1]
y_pred = [1,1,0,0,0,1,1,1,1,0, 0,1,0,1,1,1,1,1,1,0]
for beta in (1.0, 2.0, 0.5):
print(f'F{beta:>3} =', fbeta_score(y_true, y_pred, beta=beta))
print('P =', precision_score(y_true, y_pred))
print('R =', recall_score(y_true, y_pred))
print(classification_report(y_true, y_pred, digits=3))
|
閾値最適化で最大 F1 を探す
| import numpy as np
from sklearn.metrics import precision_recall_curve, f1_score
y_true = np.array([1,0,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,0,1])
y_proba = np.array([.9,.4,.7,.8,.3,.55,.45,.2,.95,.6, .35,.78,.25,.5,.65,.4,.85,.7,.3,.88])
p, r, th = precision_recall_curve(y_true, y_proba)
f1 = 2*p*r/(p+r+1e-9)
best_idx = f1.argmax()
print(f'best thr={th[best_idx]:.3f}, F1={f1[best_idx]:.3f}')
|
混同行列を可視化 + Markdown 表で出力
| import pandas as pd, numpy as np
from sklearn.metrics import confusion_matrix
y_true = [1,1,1,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0,1,1]
y_pred = [1,1,0,0,0,1,1,1,1,0,0,1,0,1,1,1,1,1,1,0]
cm = confusion_matrix(y_true, y_pred)
df = pd.DataFrame(cm, index=['actual_0','actual_1'], columns=['pred_0','pred_1'])
print(df)
TP, FP, FN, TN = cm[1,1], cm[0,1], cm[1,0], cm[0,0]
print(f'TP={TP} FP={FP} FN={FN} TN={TN}')
print(f'F1 = {2*TP/(2*TP+FP+FN):.3f}')
|
📌 すべてのレシピは「実データ前提・引数なし直書き」スタイル。 そのままコピペで動くよう設計したので、 まずは動かしてから読むのを推奨する。
🚫 アンチパターン集
F1スコア を扱うコード・レポートで頻発するアンチパターンを 5 つ挙げる。 「やってはいけないこと」を知るのが、 良いコードへの近道。
❌ コピペで済ませて意味を理解しない
本ページのコードをコピペするのは OK だが、 「なぜそうなるか」を 1 度は手計算で確認すること。 デバッグ時に困る。
❌ 結果を 1 つの数字だけ報告する
「F1 = 0.82」「結合後 1,000 件」だけ報告するのはアンチパターン。 内訳・分散・前提条件を併記すること。
❌ 落とし穴を読まずに本番投入する
本ページの落とし穴 8 件はすべて「経験者が踏んだ地雷」。 本番前に必ず一読し、 自分のコードで該当しないか確認。
❌ ライブラリのデフォルトを盲信する
sklearn の average='binary'、 pandas の how='inner' 等のデフォルトは「最も多用される選択」であって「自分の目的に最適」とは限らない。 必ず確認。
❌ バージョン情報を記録しない
pandas / sklearn / torch のバージョンで挙動が変わることがある。 再現性のため pip freeze や conda env export を記録。
🏁 最終結論:F1スコア を一言で
F1 スコアは「Precision と Recall のバランス」を 1 値に圧縮する便利な指標。 だが「F1 高ければ良い」と思考停止する人と、 「F1 の内訳と業務インパクトを語れる人」では、 ML プロジェクトの成否が分かれる。 本ページで学んだ (i) 調和平均という設計、 (ii) F-beta による業務重み付け、 (iii) macro/micro/weighted の使い分け、 (iv) 閾値最適化、 (v) AUC-PR との併用の 5 視点を持って初めて、 「データサイエンティスト」と名乗れる。 不均衡データ・医療・スパム・自動運転など、 現代の重要 ML 分野ほど F1 の解釈が決定的になる。
本ページは ジャストインタイム型データサイエンス教育の一部として、 必要なときに必要な節だけ読んでもらう設計になっている。 通読する必要はない。 自分の今いる場所 (卒論・実務・論文読解) に応じて、 該当セクションだけを参照し、 また論文や業務に戻ってほしい。 そして数か月後、 似たような状況に陥ったとき、 また戻ってきてくれれば、 教材として最高の使い方になる。
📚 関連リンク:論文一覧 | 用語集トップ | 概念マップ
🙋 著者・教材設計について
本教材は、 広島工業大学 統計・データ解析コンペティション参加学生向けに、 松本伸平 (s.matsumoto.gk@cc.it-hiroshima.ac.jp) が監修・執筆した。 「論文を読む過程で出てきた専門用語を、 その場で 5 分で補完して論文に戻る」というジャストインタイム型の学習体験を目的に、 514 用語ページを統一フォーマットで整備している。
本ページ「F1スコア」は 評価指標 カテゴリに属し、 同カテゴリ内の他用語と相互リンクされている。 用語間の関係性は 概念マップ でも俯瞰できる。
本サイトは SSDSE (教育用標準データセット, 独立行政法人統計センター) を主データとして使い、 「合成データ ではなく実公的データを使う」 を方針に据えている。 ハンズオン教材の質を最大化するための判断である。
📌 F1 補遺:競技 ML / 業務 ML での扱い
F1 スコアは Kaggle等の競技 ML でリーダーボード評価指標として頻用される一方、 業務 ML では 業務 KPI に翻訳する必要がある。 ここでは両者の現代的な扱いを整理する。
競技 ML での F1
- マクロ F1 がよく採用される (例:CIFAR 10 クラス分類、 医療画像コンペの病変分類)
- マイクロ F1 はマルチラベル分類のサンプル平均 F1 と同義になることが多い
- 競技では「リーダーボードの 0.001 ポイント差」が順位を決めるので、 閾値最適化 + アンサンブルが定石
- Stratified K-fold で fold ごとに閾値最適化 → 平均閾値で submission を作るのが王道
業務 ML での F1
- F1 を直接報告するより、 「業務 KPI に変換」するのが説得力ある
- 例:「Recall 92% → 月 50,000 件の不正検知のうち 4,000 件は見逃し → 年間損失 1,200 万円」
- 偽陽性 (FP) と偽陰性 (FN) のコストが非対称なら、 F-beta または 期待効用で評価
- 本番運用後は concept drift (データ分布の変化) で F1 が徐々に低下するので、 月次モニタリング必須
F1 を改善する 10 のテクニック
- 閾値最適化 (PR 曲線で F1 が最大の点)
- クラス重み付け (
class_weight='balanced')
- SMOTE / ADASYN によるオーバーサンプリング
- RandomUnderSampler によるダウンサンプリング
- Focal Loss (γ=2 で hard negative を強調)
- アンサンブル (Bagging + Boosting + Stacking)
- キャリブレーション (Platt scaling, Isotonic regression)
- ドメイン特徴量の追加 (Positive クラス独自のシグナル)
- データ拡張 (画像なら回転・反転、 テキストなら同義語置換)
- 事前学習モデル (Transformer, ViT) の活用
F1 vs MCC vs Cohen's Kappa
MCC (Matthews Correlation Coefficient) = $\frac{TP\cdot TN - FP\cdot FN}{\sqrt{(TP+FP)(TP+FN)(TN+FP)(TN+FN)}}$。 範囲 [-1, +1]。 不均衡データで F1 より良いと言われ、 ChouChou et al. (2020) では二値分類の単一指標として MCC を推奨。 Cohen's Kappa は「偶然の一致を超えた一致度」で、 マルチクラスの評価で多用。 F1 と併記すると論文の説得力が増す。
F1 と ROC-AUC の関係
F1 は「ある閾値での」点評価、 ROC-AUC は「全閾値での」曲線評価。 両者は 独立な情報を持つ:高い ROC-AUC でも閾値設定次第で F1 は低い。 業務運用するなら F1 (運用時の挙動)、 モデル選択するなら ROC-AUC (閾値依存しない順位性)。 報告時は両方出すのが現代的。
🏥 ドメイン別 F1 活用事例
F1 スコアは分野によって「妥当な水準」が違う。 ここでは 6 分野での典型的な F1 値と運用上の注意を整理する。
| 分野 | 典型 F1 | 運用上の重視点 |
| 医療診断 (癌・肺炎) | 0.70〜0.90 | F2 で Recall 重視 (見逃し回避) |
| スパムフィルタ | 0.95〜0.99 | F0.5 で Precision 重視 (正常メール誤判定回避) |
| クレジット不正検知 | 0.60〜0.85 | 期待コスト最小化 (FP=ユーザー不便, FN=損失) |
| 自然言語 NER | 0.80〜0.95 | macro-F1 (エンティティタイプの平等評価) |
| 画像物体検出 | 0.50〜0.85 (mAP) | mAP@0.5 / mAP@0.5:0.95 (F1 の拡張概念) |
| レコメンド | 0.10〜0.40 (Top-K) | Precision@K / Recall@K / NDCG を併用 |
📌 分野横断的に「F1 = 0.8 ならまあまあ」と判断するのは誤り。 自分の分野のベンチマーク (SOTA) と比較するのが正解。
🔗 隣接手法への橋渡し
「F1 スコア」は Precision と Recall を 1 つの値に統合する便利な指標であるが、 実務で意味を持たせるには隣接手法と接続・統合・比較の三視点で運用判断する必要がある。 章 10 が分類体系上の位置づけを示すのに対し、 章 14 は「業務でいつ何に切替えるか」を整理する。
① 接続 (パイプライン上で前後に位置する手法)
② 統合 (組み合わせて使うことで効果が増す手法)
- Fβ スコア (van Rijsbergen 1979) と統合: β=2 で Recall 重視 (癌検診・侵入検知)、 β=0.5 で Precision 重視 (スパム判定・推薦)、 β=1 が F1
- PR-AUC と併用し、 単一閾値の F1 だけでなく全閾値での挙動も同時報告する (Davis & Goadrich 2006)
- コスト感応学習 (Elkan 2001) と組み合わせ、 業務コスト比 cFP:cFN を損失関数に直接反映 → Fβ の β = √(cFN/cFP) で対応関係が成立
③ 比較 (代替・競合する指標といつ切替えるか)
| 切替先 | F1 からこちらへ切替える場面 |
| Accuracy | クラスがほぼ均衡 (陽性率 40-60%) で、 経営層に「全体正解率」を説明する場面 |
| ROC-AUC | 閾値を固定したくない・モデル選択フェーズで全閾値での順序付け性能を比較したい場面 |
| PR-AUC | 極端な不均衡 (陽性率 < 1%) で ROC-AUC が高く出すぎ、 Precision-Recall 平面で評価したい場面 |
| Matthews 相関係数 (MCC) | TP/TN/FP/FN すべてのバランスを 1 つの値で見たい場面 (Boughorbel 2017)。 F1 と異なり TN も評価に入る |
| Fβ スコア | Precision と Recall を等価扱いしたくない場面。 業務コスト比から β を決める |
運用判断は (1) クラス均衡度の確認 → (2) Precision と Recall の重視度から β を決定 → (3) 単一閾値か全閾値かで Fβ と PR-AUC を選択 → (4) TN も評価に入れたいなら MCC へ切替、 の 4 軸で整理する。 章 10 (分類体系) で F 系指標の位置づけを把握し、 章 14 (運用判断) で「いつ何を選ぶか」を決定することで、 不均衡データやコスト非対称な業務に適切な指標設計ができる。
🌳 手法選択フロー
「F1 スコア」を実際の課題に当てはめるとき、 以下の 3 ステップで判断する。 領域固有の判断基準と組み合わせて使用する。
- ステップ 1: クラス不均衡なら Accuracy より F1 を主指標に
- ステップ 2: FP / FN コスト非対称なら F_β (β>1 で Recall 重視)
- ステップ 3: 多クラスは macro F1 (van Rijsbergen 1979)
多クラス分類で macro F1 は全クラスを等価扱い (少数クラスにも敏感)、 weighted F1 はサンプル数で重み付け (多数クラス優位)、 micro F1 は集約 confusion matrix から計算 (Accuracy と一致) という違いがあり、 不均衡度と業務目的で選ぶ。 sklearn の `f1_score(average=...)` で簡単に切り替え可能。
🔬 別角度:F1 は「確率の目盛り」に依存する — SSDSE-B-2026 実測で見る
本ページの他セクションでは Fβ・macro/micro/weighted・PR 曲線・閾値最適化を厚く扱った。 ここでは重複を避け、 意外と語られない一点だけを実測データで掘り下げる。 それは「F1 は確率をハード判定 (0/1) に落としてから測る量なので、 (1) 正例の定義、 (2) 判定閾値、 (3) 確率の目盛り=較正 (calibration) の 3 つと不可分に絡む」という事実だ。 一方 ROC-AUC / PR-AUC は確率の順位だけを見るため、 これら 3 つの一部に鈍感である。 この非対称性を知ると、 F1 の数字を「何と比べれば安全か」が見えてくる。
実測タスク:超高齢化県の予測 (SSDSE-B-2026 / 2023 / 47 県)
SSDSE-B-2026 を encoding='cp932', skiprows=[1] で読み、 2023 年の 47 都道府県に限定。 高齢化率 = A1303 / A1101 が 0.35 以上を「超高齢化県 = Positive」と定義した (該当 6 / 47 県、 陽性率 12.8% の少数派 Positive)。 説明変数 A1101, A4101, A4103, L3221 を標準化し、 ロジスティック回帰を StratifiedKFold(5) + cross_val_predict で交差検証予測。 得られた予測確率での実測値が以下である (すべて実データからの計算値)。
| 判定閾値 | Precision | Recall | F1 |
| 0.20 | 0.333 | 0.500 | 0.400 |
| 0.30 | 0.000 | 0.000 | 0.000 |
| 0.50 (既定) | 0.000 | 0.000 | 0.000 |
| 0.70 | 0.000 | 0.000 | 0.000 |
| 0.185 (F1 最適) | — | — | 0.471 |
参考の順位系指標 (同じ予測確率): ROC-AUC = 0.809、 PR-AUC = 0.411。 「全県 Negative」と答えるだけの Accuracy = 0.872。
読み取れる 3 つの落とし穴 (実測が語る)
① Accuracy の罠が数字で見える
「全部 Negative」で Accuracy = 0.872 と高い一方、 既定閾値 0.5 での F1 = 0.000 (このモデルは 0.5 では誰も陽性と予測しない)。 ROC-AUC 0.809 は一見悪くないが、 不均衡を反映する PR-AUC は 0.411 まで下がる。 Accuracy・ROC-AUC が高い ≠ 使えるを、 同一データが同時に示している。
② 閾値ひとつで F1 は 0.000 ↔ 0.471 に動く
同じ予測確率のまま、 閾値 0.5 では F1=0.000、 F1 最適の閾値 0.185 では F1=0.471。 少数派 Positive では確率が全体的に低く出やすく、
既定 0.5 が「実質すべて陰性」になりがち。 「F1=0 だからモデルがゴミ」ではなく「閾値が不適」なだけのことがある。 まず PR 曲線・閾値走査を見よ、 という
適合率・再現率 ページと同じ教訓が実データで再現する。
③ 確率較正と F1 は別物 (単調変換で検証)
予測確率を順位を保つ単調変換 proba**k にかけると (k は正の定数)、 順位は不変なので ROC-AUC = 0.809、 PR-AUC = 0.411 は k を変えても一切変わらない。 ところが固定閾値 0.5 での F1 は k=1: 0.000 → k=0.5: 0.444 → k=2.0: 0.000 と激変した (実測)。 つまり F1 は「確率の目盛り=較正」に依存する量で、 較正を直すだけで固定閾値の F1 は動きうる。 逆に F1 が高くても確率が正しく較正されているとは限らない (F1 はハード判定しか見ないため)。 確率そのものの正しさを問うなら較正曲線・Brier スコアを、 順位の良さを問うなら AUC を、 運用閾値での挙動を問うなら F1 を — と別々に見るのが安全。
④ 正例の定義そのものが F1 の水準を決める
同じ SSDSE-B-2026・同じ特徴量でも、 Positive の定義を変えると難易度も F1 も別物になる (いずれも実測)。
| Positive の定義 | 陽性数 / 47 | 陽性率 | PR-AUC | F1 (最適閾値) |
| 高齢化率 ≥ 0.30 | 35 | 74.5% (多数派) | 0.858 | 0.946 |
| 高齢化率 ≥ 0.35 | 6 | 12.8% (少数派) | 0.411 | 0.471 |
「F1=0.95」と「F1=0.47」は優劣ではなく別問題だ。 前者は多数派を Positive にしただけで水増しされている疑いがある (本ページ「よくある落とし穴」の「多数派を Positive にしない」と同根)。 論文・レポートでは 「何を Positive と定義したか・陽性率はいくつか」を必ず明記しないと、 F1 の数字は比較不能になる。
再現コード (実測値はこのコードの出力)
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) A4103(合計特殊出生率) L3221(消費支出(二人以上の世帯))
北海道 5,092,000 1,681,000 24,430 1.06 296,888
東京都 14,086,000 3,205,000 86,348 0.99 341,320
沖縄県 1,468,000 350,000 12,549 1.6 251,222
…(全 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 pandas as pd, numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_val_predict
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import roc_auc_score, average_precision_score, f1_score
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df.iloc[:, 0] == 2023].copy() # 2023 年の 47 県
y = ((df['A1303'] / df['A1101']) >= 0.35).astype(int).values # 超高齢化県 = Positive
X = StandardScaler().fit_transform(df[['A1101', 'A4101', 'A4103', 'L3221']].values)
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
proba = cross_val_predict(LogisticRegression(max_iter=1000), X, y, cv=cv,
method='predict_proba')[:, 1]
print('ROC-AUC', roc_auc_score(y, proba), 'PR-AUC', average_precision_score(y, proba))
for th in (0.185, 0.2, 0.3, 0.5, 0.7):
print(th, f1_score(y, (proba >= th).astype(int), zero_division=0))
# 単調変換で「順位不変・F1 可変」を確認 (較正と F1 は別物)
for k in (0.5, 1.0, 2.0):
pk = proba ** k
print('k=', k, 'ROC', roc_auc_score(y, pk), 'F1@0.5',
f1_score(y, (pk >= 0.5).astype(int), zero_division=0))
|
📌 ひとことで: ROC-AUC / PR-AUC が「確率の順位」の指標なのに対し、 F1 は「順位 + 閾値 + 較正 + 正例定義」の合成物。 だから F1 単独で報告せず、 Precision ・ Recall ・ 陽性率 ・ 採用閾値 ・ ROC 曲線 / PR 曲線 (AUC) をセットにする。 元データの集計は 混同行列、 モデルは ロジスティック回帰、 不均衡の扱いは クラス不均衡 の各ページも参照。 (確率較正の専用ページは未整備のため本節の解説を参照。)