【機械学習入門 第4回】モデルの性能評価!正解率・混同行列でAIの「実力」を正しく測ろう

「モデルの正解率が95%って出たけど、これって本当に『良いモデル』ってこと?」
「モデルがどんな間違い方をしているのか、詳しく知る方法はないの?」
「『混同行列』って言葉を聞いたけど、何が分かるの?」

こんにちは! AI・機械学習探検隊、隊長のPythonistaです! 前回の第3回では、アヤメの品種を予測する「分類」モデルを、ロジスティック回帰とk近傍法という2つのアルゴリズムで構築しましたね。そして、モデルの性能を測る簡単な指標として「正解率」を見ました。

しかし、機械学習の世界では、単に正解率が高いだけでは「良いモデル」とは言えない場面がたくさんあります。今回の第4回では、モデルの性能をより深く、そして多角的に評価するための「モデル評価」の技術を徹底解説します。具体的には、

  • なぜ正解率だけでは不十分なのか?
  • モデルの間違い方を詳細に分析する「混同行列 (Confusion Matrix)」
  • 混同行列から導かれる重要な指標「適合率 (Precision)」「再現率 (Recall)」

といった、よりプロフェッショナルな評価方法を学んでいきます。モデルの真の実力を見抜くための「診断スキル」を身につけ、信頼できるAI開発者への一歩を踏み出しましょう!


1. 準備:ライブラリのインポートと前回のモデルの再構築

今回も、Scikit-learnやPandas、Matplotlibを使います。評価のために、前回作成したアヤメの分類モデルを再度準備しましょう。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Scikit-learnから必要なモジュールをインポート
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# スタイルの設定
sns.set_theme(style="white")
plt.rcParams['font.family'] = 'IPAexGothic' # 日本語フォント設定

# データの準備とモデルの訓練 (前回のおさらい)
iris = load_iris()
X = iris.data
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)

model = LogisticRegression(max_iter=200)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

このy_test(実際の正解ラベル)とy_pred(モデルの予測ラベル)を比較することで、モデルの性能を評価していきます。


2. 正解率(Accuracy)の落とし穴:不均衡データの問題

まず、正解率がなぜ万能ではないのかを理解しましょう。正解率は「全データのうち、正しく予測できたデータの割合」です。直感的で分かりやすい指標ですが、大きな落とし穴があります。

それは「不均衡データ (Imbalanced Data)」の問題です。

例えば、100人の患者のうち99人が「健康」、1人が「病気」というデータセットがあったとします。この時、どんな患者が来ても常に「健康です」とだけ予測する、全く役に立たないモデルを考えてみましょう。このモデルの正解率はどうなるでしょうか? 99人の健康な人は正しく予測できるので、なんと正解率は99%になってしまいます!

このように、各クラスのデータ数に大きな偏りがある場合、正解率だけを見てしまうと、モデルの性能を完全に見誤ってしまう危険性があるのです。そのため、私たちは「モデルがどのような間違いをしているのか」を詳しく見る必要があります。


3. モデルの診断書:混同行列 (Confusion Matrix)

モデルがどのような予測をし、どのような間違いをしたかを詳細にまとめた表が「混同行列(こんどうぎょうれつ)」です。分類モデルの評価において、これ以上ないほど重要なツールです。※混同行列については数学の景色を参照ください。分かりやすい解説があります。

3.1. 混同行列の見方

混同行列は、行に「実際のクラス」、列に「予測したクラス」を取り、各セルにデータの個数をプロットしたものです。

  • True Positive (TP): 実際にPositiveのものを、正しくPositiveと予測した数。
  • True Negative (TN): 実際にNegativeのものを、正しくNegativeと予測した数。
  • False Positive (FP / タイプ1エラー): 実際にNegativeのものを、間違ってPositiveと予測した数。「オオカミ少年」タイプの間違い。
  • False Negative (FN / タイプ2エラー): 実際にPositiveのものを、間違ってNegativeと予測した数。「見逃し」タイプの間違い。

理想的なモデルは、対角線上のTPとTNの数が多く、それ以外のFPとFNの数が0に近くなります。

3.2. Scikit-learnで混同行列を作成・可視化する

confusion_matrix()関数で混同行列を計算し、Seabornのheatmap()で可視化すると非常に分かりやすくなります。

# 混同行列を計算
cm = confusion_matrix(y_test, y_pred)
print("\n--- 混同行列 ---")
print(cm)

# 混同行列をヒートマップで可視化
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
            xticklabels=iris.target_names,
            yticklabels=iris.target_names)
plt.title('混同行列 (Confusion Matrix)')
plt.xlabel('予測したクラス')
plt.ylabel('実際のクラス')
plt.show()


このグラフでは、対角線上に予測が正しかったデータの数が、それ以外のセルに予測が間違ったデータの数が表示されます。今回のアイリスデータセットでは、ほとんど(または全て)のデータが対角線上にあり、非常にうまく分類できていることが一目で分かりますね。


4. 混同行列から導かれる重要な評価指標

混同行列を元に、正解率よりもさらに詳細な性能評価指標を計算することができます。特に重要なのが「適合率」と「再現率」です。

4.1. 適合率 (Precision)

適合率 = TP / (TP + FP)
これは、「モデルがPositiveと予測したものの中で、実際にPositiveだったものの割合」を示します。適合率が高いということは、モデルの「Positive」という予測の信頼性が高いことを意味します。
例: 迷惑メールフィルターで、迷惑メールと判定されたメールの中に、本当に迷惑メールである割合。適合率が低いと、重要なメールまで迷惑メールフォルダに入ってしまいます(FPが多い)。

4.2. 再現率 (Recall / Sensitivity)

再現率 = TP / (TP + FN)
これは、「実際にPositiveであるもの全体の中で、モデルがどれだけ正しくPositiveと予測できたかの割合」を示します。再現率が高いということは、「見逃し」が少ないことを意味します。
例: 病気の診断で、実際に病気である患者の中から、正しく「陽性」と診断できた割合。再現率が低いと、病気の人を見逃してしまいます(FNが多い)。

4.3. F1スコア (F1-Score)

適合率と再現率は、多くの場合トレードオフの関係にあります(適合率を上げようとすると再現率が下がり、その逆も然り)。F1スコアは、適合率と再現率の調和平均を取り、この2つの指標をバランス良く評価するための指標です。1に近いほど良いモデルとされます。

4.4. `classification_report`でまとめて確認!

これらの指標を一つ一つ計算するのは大変ですが、Scikit-learnにはclassification_report()という便利な関数があり、各クラスの適合率、再現率、F1スコアをまとめて表示してくれます。

# 分類レポートを表示
report = classification_report(y_test, y_pred, target_names=iris.target_names)
print("\n--- 分類レポート (Classification Report) ---")
print(report)

実行結果 (例):

--- 分類レポート (Classification Report) ---
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        15
  versicolor       1.00      1.00      1.00        15
   virginica       1.00      1.00      1.00        15

    accuracy                           1.00        45
   macro avg       1.00      1.00      1.00        45
weighted avg       1.00      1.00      1.00        45

このレポートを見れば、モデルが各クラスに対してどれくらい良い性能を持っているかを詳細に把握することができます。


5. なぜ訓練データとテストデータを分けるのか(再確認)

ここで、改めてtrain_test_splitの重要性を再確認しましょう。今回計算したこれらの評価指標は、全てモデルが学習中に一度も見ていない**テストデータ (X_test, y_test)** に対して計算しました。

もし、訓練データ (X_train, y_train) で性能を評価してしまうと、モデルは「答えを知っている」状態なので、非常に高いスコアが出てしまいます。これは、単に訓練データを「丸暗記」しているだけで、新しい未知のデータに対しては全く役に立たないモデル(これを**過学習 Overfitting** と言います)である可能性を見抜けません。

テストデータで評価することは、モデルの真の「実力」=「汎化性能」を測るための、機械学習における絶対的なルールなのです。


まとめと次回予告

今回は、機械学習入門シリーズの第4回として、構築したモデルの性能を正しく評価するための重要な手法を学びました。

  • 単純な正解率 (Accuracy) だけでは不十分な場合があること(特に不均衡データ)。
  • モデルの予測と実際の結果を詳細に比較する混同行列 (Confusion Matrix) の見方と作り方。
  • より詳細な性能評価指標である適合率 (Precision)再現率 (Recall)、そしてそのバランスを取ったF1スコア
  • これらをまとめて表示してくれる便利なclassification_report()
  • モデルの真の実力(汎化性能)を測るための、訓練データとテストデータへの分割の重要性。

モデルを構築するスキルと同じくらい、そのモデルを正しく評価するスキルは重要です。これらの指標を理解することで、あなたは「なぜこのモデルが良いのか(悪いのか)」を他者に説明できる、より信頼される分析者になることができます。

さて、これで私たちは、データの準備から、モデルの構築、そして評価まで、機械学習プロジェクトの一連の基本的な流れを全て学びました!

次回、第5回(実践編・入門編最終回)では、いよいよこれまでの全ての知識を総動員します!簡単なデータセットを使い、**データの前処理からモデル構築、そして今回学んだ様々な指標を使った詳細な評価まで、一気通貫のミニプロジェクト**に挑戦します。あなたの機械学習スキルを確かなものにするための、集大成となる回です。お楽しみに!

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

これで迷わない!WindowsでPython環境構築する一番やさしい方法 #0

【Python標準ライブラリ完結!】11の冒険をありがとう!君のPython力が飛躍する「次の一歩」とは? 🚀