0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

令和7年秋期 応用情報技術者試験 問3 解説(ROC曲線とAUCをアニメーションで理解する)

0
Posted at

1. 問題と解答

AIにおける機械学習において,2クラス分類モデルの評価方法の一つであるROC曲線で用いられる偽陽性率の説明として,最も適切なものはどれか。ここで,分類されるデータには正しいものと間違っているものが含まれるものとする。

ア "間違い"と予測したデータのうち,実際は"正しい"データの割合

イ 実際に"間違い"であるデータに対し,誤って"正しい"と予測したデータの割合

ウ 実際に"間違い"であるデータに対し,正しく"間違い"と予測したデータの割合

エ 全データのうち,実際に正しく予測できなかったデータの割合

解答: イ

解答の考え方

偽陽性率(FPR)は「実際は Negative(間違い)であるデータのうち、誤って Positive(正しい)と予測された割合」。見分けるポイントは 分母が「実際のクラス」基準になっているか どうか。

選択肢 分母(母集団) 分子 判定
予測が「間違い」とされたデータ そのうち実際は「正しい」 分母が予測結果基準 → FPRではない
実際が「間違い」のデータ そのうち誤って「正しい」と予測 分母・分子とも条件一致 → FPR(正解)
実際が「間違い」のデータ そのうち正しく「間違い」と予測 これはTNR(特異度)の定義
全データ そのうち予測を誤ったもの これはError Rate(誤り率)の定義

ア・ウ・エはそれぞれ別の指標(分母が予測基準/特異度/誤り率)の定義になっており、正しく「実際のクラス=間違い」を分母に取っているイだけがFPRの定義と一致する。

2. 基礎概念と公式

2クラス分類(正しい/間違い、陽性/陰性)の結果は次の4パターンに分かれる。

実際 予測 名称
正しい 正しい TP(真陽性)
正しい 間違い FN(偽陰性)
間違い 正しい FP(偽陽性)
間違い 間違い TN(真陰性)

ここから作れる代表的な指標は以下の通り。

指標 公式 意味(実際の母集団を基準に)
TPR 真陽性率 / Recall / Sensitivity TP / (TP + FN) 実際が正のうち、正しく見つけられた割合
FNR 偽陰性率 FN / (TP + FN) 実際が正のうち、見逃した割合
TNR 真陰性率 / Specificity TN / (TN + FP) 実際が負のうち、正しく判定できた割合
FPR 偽陽性率 FP / (TN + FP) 実際が負のうち、誤って正と判定した割合
Precision 適合率 TP / (TP + FP) 正と予測したうち、実際に正だった割合
NPV 陰性的中率 TN / (TN + FN) 負と予測したうち、実際に負だった割合
Accuracy 正解率 (TP + TN) / (TP + TN + FP + FN) 全データのうち判定が正しかった割合
Error Rate 誤り率 (FP + FN) / (TP + TN + FP + FN) 全データのうち判定を誤った割合
F1-score 2TP / (2TP + FP + FN) Precision と Recall の調和平均

覚えておくと便利な関係

TPRとFNRは「実際が正」という同じ母集団を分母にしているので、足すと必ず1になる。

TPR + FNR = TP/(TP+FN) + FN/(TP+FN) = 1

同様に、TNRとFPRは「実際が負」という同じ母集団が分母なので、これも足すと1になる。

TNR + FPR = TN/(TN+FP) + FP/(TN+FP) = 1

つまり FPR = 1 − TNRFNR = 1 − TPR と言い換えられる。

ROC曲線はこのFPRとTPRを軸にとったグラフ:

横軸 = FPR = FP / (FP + TN)
縦軸 = TPR = TP / (TP + FN)

一言でまとめると、FPRは「実際に負である集団の中でどれだけ誤って正と判定したか」、TPRは「実際に正である集団の中でどれだけ正しく言い当てたか」 を表す指標。分母が常に「実際のクラス」であることさえ覚えれば、分母が予測結果基準になっている選択肢に惑わされずに済む。

3. 参考資料:ROC曲線とAUCのアニメーション

出典: ROC curve, AUCを視覚的に理解する animation付き (Qiita, @kenmatsu4)
コード全体: Gist: matsuken92/05c2bc24c9edf83334b0

しきい値と分類

検査数値のような1次元の値を使って「病気 / 健康」を判定する場面を考える。判定にはしきい値を1つ設定し、例えば「検査数値が27未満なら病気、27以上なら健康」のように分類する。元記事の数値例(しきい値27)を上の混同行列に当てはめると:

  • TPR(真陽性率)= 0.909(病気の人の91%を正しく「病気」と判定)
  • FNR(偽陰性率)= 0.091(残り9%の病気の人を誤って「健康」と判定)
  • FPR(偽陽性率)= 0.280(健康な人の28%を誤って「病気」と判定)
  • TNR(真陰性率)= 0.720(残り72%の健康な人を正しく「健康」と判定)

病気群・健康群それぞれの検査数値の分布(正規分布)を考えると、しきい値 x における

  • TPR = 病気群の分布の累積分布関数(しきい値より「陽性側」の累積確率)
  • FPR = 健康群の分布の累積分布関数(同上)

に対応する。つまり密度曲線を積分した累積分布曲線(CDF)の値そのものが TPR / FPR になる。

ROC曲線の描き方

しきい値を表す縦線(識別境界)を左から右へ動かしていくと、その位置ごとに (FPR, TPR) が1組決まる。この (FPR, TPR) を横軸=FPR, 縦軸=TPR の平面上にプロットし、しきい値を動かした軌跡を線でつなぐと ROC曲線 になる。

roc_curve_animation.py の「密度曲線・累積曲線・ROC曲線を同時表示」するアニメーション(1)は、まさにこの「動いている縦線 → 累積曲線上の点 → ROC曲線上の点」という対応関係を、静止画では伝わりにくい部分を動きで見せている。

density, cumulative, ROC curve animation

AUC(Area Under the Curve)

ROC曲線の下側の面積を AUC と呼ぶ。

  • 2群の分布が完全に分離している(判別が完璧)→ ROC曲線は左上の角に張り付き、AUC → 1
  • 2群の分布が完全に重なっている(判別能力なし、ランダム判定と同じ)→ ROC曲線は対角線 y = x に一致し、AUC = 0.5
  • 元記事の数値例では AUC ≈ 0.867953

何がAUCを決めるか

元記事は、2つの要因がAUC(=判別性能)を左右することをアニメーションで示している。

  1. 平均の差:2群の分布の平均が離れているほど重なりが減り、ROC曲線が左上にシフトしてAUCが上がる(アニメーション 2:平均 μ1 を 10→30 と動かして分布2の平均に近づける)

    moving mean animation

  2. 分散の差:分布の広がり(標準偏差)が小さいほど重なりが減り、同様にAUCが上がる(アニメーション 3:標準偏差 σ1 を 5→0.5 と縮めていく)

    changing variance animation

    43 と同じ動きにAUCの数値も表示したもの。

    changing variance with AUC animation

まとめると、2つの分布が「離れているか」「尖っているか(分散が小さいか)」がそのままROC曲線の形=判別性能を決める、というのがこの記事の核心的な主張。

アニメーション一覧

# 内容 何を動かすか
1 密度曲線・累積曲線・ROC曲線を同時表示 判定しきい値 x
2 分布1の平均が分布2に近づく 平均 μ1 (10→30)
3 分布1の分散が分布2に近づく 標準偏差 σ1 (5→0.5)
4 3と同じだが ROC曲線のタイトルに AUC を表示 標準偏差 σ1 + AUC値

ファイル構成

  • roc_curve_animation.py — 上記4つのアニメーションを再現する実行可能スクリプト(元記事のコードを1本にまとめたもの)

実行方法

pip install matplotlib numpy scipy pillow
python roc_curve_animation.py 1     # output/ROC_curve1.gif
python roc_curve_animation.py 2     # output/ROC_curve2.gif
python roc_curve_animation.py 3     # output/ROC_curve3.gif
python roc_curve_animation.py 4     # output/ROC_curve_auc.gif
python roc_curve_animation.py all   # 4つまとめて生成

output/ サブフォルダに .gif が出力される(動作確認済み。output/ 内の4つのgifは上記のREADME内プレビューにも使われているもの)。

元記事のコードからの変更点

元のコードをそのまま動かすには2つの外部依存があり、環境によっては動かないので置き換えた。

  1. writer='imagemagick'PillowWriter
    元記事は GIF 保存に ImageMagick の外部バイナリを使用している。ImageMagick が未インストールの環境でも動くように、matplotlib 標準搭載の PillowWriter(Pillow ライブラリのみに依存)に変更。
  2. sklearn.metrics.aucnumpy.trapz
    AUC計算(アニメーション4)にscikit-learnを使っていたが、台形則によるAUC計算は numpy.trapz だけで完結するため、scikit-learn依存を無くした。計算結果は同じ。

それ以外のロジック(分布のパラメータ、描画内容、フレーム数など)は元記事のまま。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?