Confusion Matrix
混同行列は、クラスごとにモデルの予測と正解ラベルを集計します。読み方、そこから得られる指標、物体検出における形式を解説します。
混同行列は、分類モデルの予測が正解ラベルとどのように一致するかを数える表です。一方の軸に実際のクラス、もう一方の軸に予測クラスを並べ、各セルにはその組み合わせに該当するサンプル数を記録します。正しい予測は対角線上に入り、誤りはすべて対角線以外の、どのクラスを何のクラスと間違えたかが分かるセルに入ります。そのため、混同行列はモデルの誤りを最初に確認するための標準的な手段であり、正解率、適合率、再現率、F1スコアの算出元でもあります。
2クラス混同行列の読み方#
クラスが2つの場合、行列は4つのセルで構成されます。
- 真陽性(TP): 正例を正例と予測したものです。たとえば、欠陥のある部品を欠陥ありと判定した場合です。
- 偽陽性(FP): 負例を正例と予測したものです。第I種の誤り、または誤警報とも呼ばれます。
- 偽陰性(FN): 正例を負例と予測したものです。第II種の誤り、または見逃しとも呼ばれます。
- 真陰性(TN): 負例を負例と予測したものです。
ほとんどの二値分類指標は、これら4つの件数の比率です。適合率はTP / (TP + FP)、再現率はTP / (TP + FN)、正解率は(TP + TN)を4つすべての合計で割った値です。対角線以外のどちらのセルを重視するかは、用途によって異なります。がん検診では偽陰性を少なくするよう調整し、スパムフィルターでは偽陽性を少なくするよう調整します。
多クラス混同行列#
クラス数がNの場合、行列はN × Nになります。scikit-learnのconfusion_matrixで使われている向きでは、各行が正解クラス、各列が予測クラスです。行を横に見ると、そのクラスのサンプルがどこに分類されたかが分かるため、対角線のセルを行の合計で割ると、そのクラスの再現率になります。列を縦に見ると、そのクラスとして予測されたものの実際の内訳が分かるため、対角線のセルを列の合計で割ると、そのクラスの適合率になります。ツールによっては行列を転置して表示するため、グラフの読み方は軸ラベルで判断してください。
from sklearn.metrics import confusion_matrix
# 10枚の画像の正解ラベルと予測ラベル
y_true = ["cat", "cat", "cat", "dog", "dog", "dog", "dog", "fox", "fox", "fox"]
y_pred = ["cat", "cat", "dog", "dog", "dog", "dog", "cat", "fox", "dog", "fox"]
# ラベルの順序に従い、行は正解クラス、列は予測クラスです
labels = ["cat", "dog", "fox"]
matrix = confusion_matrix(y_true, y_pred, labels=labels)
print(matrix)cat、dog、foxの出力行はそれぞれ[2 1 0]、[1 3 0]、[0 1 2]です。対角線上に10枚中7枚があるため、正解率は0.7です。dog列にはcatとfoxが1枚ずつ含まれるため、dogの適合率は3 / 5 = 0.6です。また、dog行では1枚がcatに分類されているため、dogの再現率は3 / 4 = 0.75です。正規化された行列では、各セルを正解クラスの合計で割るため、対角線上の値がクラスごとの再現率を示し、サイズが大きく異なるクラスを比較できるようになります。
物体検出の混同行列#
物体検出では、検出器が何もない場所にボックスを出力したり、物体を完全に見逃したりするため、背景クラスを追加します。まず、IoU(intersection over union)で予測をラベルとマッチングし、その後に集計します。マッチしたペアはクラスのセルに入り、マッチしなかった予測は背景に対する偽陽性として数えられ、マッチしなかったラベルは背景として予測された偽陰性として数えられます。空の画像領域は数えられないため、背景と背景のセルは空のままとなり、物体検出の行列には真陰性がありません。YOLO26の検証では、背景用に行と列を1つずつ追加した行列を作成し、IoUが0.45を超える予測をラベルとマッチングします。この行列はconfusion_matrix.pngとして保存され、縦軸が予測クラス、横軸が正解クラスになります。
from ultralytics import YOLO
# Load a pretrained YOLO26 nano detector
model = YOLO("yolo26n.pt")
# Validation builds the confusion matrix and saves it as confusion_matrix.png
metrics = model.val(data="coco8.yaml")
matrix = metrics.confusion_matrix.matrix # rows: predicted class, columns: true class
# 80 COCO classes plus one background row and column
print(matrix.shape)
# Class 0 is "person": correct detections and people the model missed
print(f"Person TP: {matrix[0, 0]:.0f}, missed: {matrix[-1, 0]:.0f}")形状は(81, 81)で、最終行にはどの予測ともマッチしなかったラベル付きの人物が集計されます。
混同行列と関連ツールの違い#
- ROC曲線: 判定しきい値ごとに1つの点を示します。各点は、そのしきい値での混同行列を真陽性率と偽陽性率に要約したものです。
- 平均適合率(mAP): 検出の主要なスコアです。すべての信頼度レベルにおける同じTPとFPの判定から算出されますが、どのクラス同士が混同されたかは示しません。
- 正解率: 行列を1つの数値に圧縮したもので、対角線上の合計を全体の合計で割った値です。データセットの95%が負例の場合、「負」と常に予測するモデルは正解率95%を記録しますが、混同行列を見ると真陽性は0件です。










