AI学習ノートの第7回。
前回はTitanicデータセットを使って、初めて機械学習モデル(ロジスティック回帰)を学習させた。
今回はその続きとして、モデルの評価方法について学習した。
機械学習を始めたばかりの頃は「Accuracyが高ければ良いモデル」と考えがちだが、実際にはそれだけでは不十分であることが分かった。
今回もChatGPTを講師兼壁打ち相手として活用しながら学習を進めた。
今回の学習内容
- Accuracy(正解率)の理解
- Confusion Matrix(混同行列)の読み方
- Precision
- Recall
- F1 Score
- predict_proba()
- ロジスティック回帰の重み(係数)の確認
まずはロジスティック回帰を実行
前回作成したモデルを利用して予測を実行した。
from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score model = LogisticRegression(max_iter=1000) model.fit(X_train, y_train) y_pred = model.predict(X_test) acc = accuracy_score(y_test, y_pred) print(acc)
実行結果。
0.8044692737430168
約80.4%の正解率となった。
最初は「80%も当たるのか」と思ったが、ここで重要なのは「その80%の中身」である。
Confusion Matrix(混同行列)を確認する
from sklearn.metrics import confusion_matrix cm = confusion_matrix(y_test, y_pred) print(cm)
結果。
[[92 13] [22 52]]
表にすると以下のようになる。
| 予測:死亡(0) | 予測:生存(1) | |
|---|---|---|
| 実際:死亡(0) | 92 | 13 |
| 実際:生存(1) | 22 | 52 |
つまり、179件中144件を正しく予測していた。
Accuracyは単純に以下で計算される。
(92 + 52) / 179 = 0.804
この時点で、「Accuracyとは単に正解数の割合である」という理解ができた。
Accuracyだけでは危険な理由
ここは個人的にかなり勉強になった。
例えば1000件のデータがあり、990件が正常、10件が異常だったとする。
このときモデルが全件を「正常」と予測した場合でも、Accuracyは99%になる。
しかし異常データを1件も発見できていない。
実務で考えると全く使えないモデルである。
つまり、Accuracyだけ見て判断してはいけない。
Precision・Recall・F1 Scoreを確認する
from sklearn.metrics import classification_report print(classification_report(y_test, y_pred))
結果。
precision recall f1-score support
```
0 0.81 0.88 0.84 105
1 0.80 0.70 0.75 74
accuracy 0.80 179
```
macro avg 0.80 0.79 0.79 179
weighted avg 0.80 0.80 0.80 179
Recallとは?
Recallは「実際に生存した人をどれだけ見つけられたか」を表す。
今回の場合、生存者は74人いた。
そのうち52人を正しく生存と予測できている。
つまりRecallは約70%となる。
医療診断や不正検知など、「見逃し」が致命的なケースではRecallが重要になる。
Precisionとは?
Precisionは「生存すると予測した人のうち、本当に生存した割合」である。
今回は80%だった。
営業リストや広告配信など、無駄撃ちを減らしたい場合はPrecisionが重要になる。
predict()とpredict_proba()の違い
これも初学者が混乱しやすいポイントだと思う。
y_prob = model.predict_proba(X_test) print(y_prob[:10])
結果。
[[0.92148847 0.07851153] [0.76415872 0.23584128] [0.85396987 0.14603013] [0.11098318 0.88901682] ... ]
最初は何を表しているのか分からなかった。
実はこれは以下を意味している。
| 列 | 意味 |
|---|---|
| 1列目 | 死亡確率 |
| 2列目 | 生存確率 |
例えば
[0.11 0.89]
なら「89%の確率で生存」と予測していることになる。
predict()はこの確率を見て、最終的に0か1へ変換しているだけである。
ロジスティック回帰の重みを確認する
モデルの中身も確認してみた。
print(model.coef_) print(model.intercept_)
結果。
[[-0.92465179 2.63055403 -0.03123084 0.00363259 -0.23670432]] [1.84040515]
使用している特徴量は以下。
features = [
"Pclass",
"Sex",
"Age",
"Fare",
"FamilySize"
]
気付いたこと
Sexの係数が圧倒的に大きい。
今回の前処理では、
male = 0 female = 1
としているため、女性であることが生存に大きくプラスに働いていることが分かる。
また、Pclassはマイナスになっている。
TitanicではPclassの値が小さいほど上級客室なので、上級客室の乗客ほど生存しやすいという傾向を学習できているようだ。
単にモデルを動かすだけでなく、「モデルが何を学習したか」を読む視点が重要だと感じた。
今回の学び
- Accuracyだけではモデル評価は不十分
- Confusion Matrixで誤判定の内容を確認できる
- PrecisionとRecallは目的によって重要度が変わる
- predict()は確率を0/1へ変換した結果
- predict_proba()でモデルの自信度を確認できる
- coef_を見ると特徴量の影響度をある程度把握できる
機械学習の学習を始める前は「モデルを作ること」が目的だと思っていた。
しかし実際には、モデルを評価し、結果を解釈し、改善していくことの方が重要だと感じ始めている。
次回はStandardScalerによるスケーリングを学習する予定である。
特徴量の単位を揃えることで、係数の解釈やモデル性能がどう変わるのか確認していきたい。