from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_true=y_test, y_pred=y_pred)**0.5
print("RMSE: {:,.2f}".format(rmse))
観測値と予測値の差分絶対値の平均
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_true=y_test, y_pred=y_pred)
print("MAE: {:,.2f}".format(mae))
モデルで説明されている目的変数の変動の説明できる割合
from sklearn.metrics import r2_score
r2 = r2_score(y_true=y_test, y_pred=y_pred)
print("R-squared: {:,.2f}".format(r2))
from sklearn.metrics import confusion_matrix
def CM(y_true, y_pred):
M = confusion_matrix(y_true, y_pred)
out = pd.DataFrame(M, index=["Obs Paid", "Obs Default"], columns=["Pred Paid", "Pred Default"])
return out
threshold = 0.5
y_pred_prob = rf.predict_proba(X_test)[:,1]
y_pred = (y_pred_prob > threshold).astype(int)
CM(y_test, y_pred)
全体のデータの中で正しく分類できたTP とTN
がどれだけあるかという指標。高いほど性能が良い。
Positive と分類されたデータ(TP + FP)の中で実際にPositive
だったデータ(TP)数の割合。この値が高いほど性能が良く、間違った分類が少ないということを意味する。
取りこぼし無くPositive なデータを正しくPositive
と推測できているかどうか。この値が高いほど性能がよく、間違ったPositive
の判断が少ないということ。別の言い方をすれば本来Positive
と推測すべき全データの内、どれほど回収できたかという指標。
取りこぼし無くNegative なデータを正しくNegative
と推測できているかどうか。この値が高いほど性能がよく、間違ったNegative
の判断が少ないということ。別の言い方をすれば本来Negative
と推測すべき全データの内、どれほど回収できたかという指標。
実際にはPositive であるサンプルの内、Negative
であると判定されたクラスの割合。この値が低いほど性能が良い。
実際にはNegative であるサンプルの内、Positive
であると判定されたクラスの割合。この値が低いほど性能が良い。
from sklearn.metrics import precision_score, recall_score, accuracy_score
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
accuracy = accuracy_score(y_test, y_pred)
print("Precision: {:0.1f}%, Recall: {:.1f}%, Accuracy: {:0.1f}%".format(100*precision, 100*recall, 100*accuracy))
ROC曲線とはFPRFPR(偽陽性率)に対するTPRTPR(真陽性率)をプロットしたもの
FPRFPRが低い状態でありながらTPRTPRが高いというのが理想的
疾患あり | 疾患なし | |
検査:陽性 | 真陽性(A) | 偽陽性(B) |
検査:陰性 | 偽陰性(C) | 真陰性(D) |
真陽性率 = A / (A+C) ← 感度
真陰性率 = B / (B+D) ← 1 - 特異度
Y軸に【1-特異度】X軸に【感度】をプロットしたものをROC曲線という
検査基準を厳しくして、少しのウイルス量で陽性と判断するとほとんどの人が当てはまることになり、
感度は1に近づく。一方で、特異度は低く0に近くなる。
検査基準をだんだん緩めること(カットオフ値を徐々に上げる)で、ウイルス量がある程度ないと陽性と判断されなくなる。
←感度の低下。
一方で、疾患ありの中で陽性になる人が少なるなるので、感度は徐々に下がる。つまり特異度が徐々に上がる。
でたらめな検査であれば45度の直線。有効な検査であれば45度の線から左上に放たれた曲線となる。
from sklearn.metrics import roc_curve
fpr, tpr, ths = roc_curve(y_test, y_pred_prob)
fig, ax = plt.subplots(figsize=(8,5))
ax.plot(fpr, tpr)
ax.set_title('ROC curve', fontsize=16)
ax.set_xlabel('False positive rate', fontsize=14)
ax.set_ylabel('Recall, true negative rate', fontsize=14)
ax.grid();
つまり、precisionが高い状態でありながら(確からしさを担保しながら)recallもできるだけ高い(網羅もできている)というのが理想的です。
fig, ax = plt.subplots(figsize=(8,5))
ax.plot(precs, recs)
ax.set_title('Precision-recall curve', fontsize=16)
ax.set_xlabel('Precision', fontsize=14)
ax.set_ylabel('Recall', fontsize=14)
ax.set_xlim(0.3,0.7)
ax.grid();
ROC曲線とPR曲線のどちらを使えばよいのか、という話ですが一般的には不均衡データの場合(negativeの数がpositiveの数よりも圧倒的に多い等)はPR曲線を使い、それ以外はROC曲線を使用するのがよいとされています。
インバランスデータ(著しくPositiveに対してNegativeが多いデータ)に使われます。異常検知問題のデータセットはほとんどがこういう場合です。異常がPositive、正常がNegativeになります。