【知らないとやばい】ROCカーブ・PRカーブの使い分け

## 今更ながらROC・PRカーブの使い方わかってる？
深層学習を使っているメーカー研究者のももてぃ（仮）です:cherry_blossom:
論文を読んでいると、ROCカーブやPRカーブを使った評価結果がたくさん出てきますね。
これらを使って、モデルの良し悪しを評価することが多いと思いますが、きちんと解釈できているでしょうか？
基本的なことだからこそ、改めて確認していきたいと思います！

### 1. この記事を読んで得られること
・ROC、PRカーブの意味が理解できる。
・ROC、PRカーブの解釈の仕方がわかる。
・プロットするためのコードがわかる。

### 2. ROCカーブとPRカーブの定義
###### ROCカーブ

ROCカーブは、横軸に偽陽性率(False positive rate)、縦軸に真陽性率(True positive rate)と横軸にプロットしたグラフです。
![ROC (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650630/fd526737-56d7-bbdf-72bc-67e3df474598.png)

**カットオフを変えていき、どれだけTPとFPを切り分けられているか？を可視化した評価方法です。** 例えばこんなイメージ。
<img width="300" alt="graph" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650630/02c17f3a-75a7-2118-5db9-0b04a975e7b5.png">

True positive rateは、Posiを正しくPosiに分類できた割合、
$$
\text{True positive rate (TPR)} = \frac{\text{TP}}{\text{TP + FN}}
$$
そして、False positive rateは、Negaを誤ってPosiに分類された割合です。
$$
\text{False positve rate (FPR)} = \frac{\text{FP}}{\text{FP + TN}}
$$
<img width="230" alt="hyou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650630/ff832df8-edea-4fa8-02c7-d4194e9b2410.png">　

ROC曲線の下の領域（曲線とx軸の間の面積）をAUCと呼びます。AUCはモデルの性能を要約した数値で、1に近いほど性能が高いと言えます。

###### PRカーブ
じゃあPRカーブは？というと、横軸にRecall（再現率）、縦軸にPrecision（適合率）をプロットしたグラフです。
![PR_size64_auc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650630/532eadf0-3236-6d18-155b-0744f830747a.png)

ここで、Recallは、posiのうちどれだけ正しく予測できたかの割合。実は、TPRと同じ（別の名前で同じ定義じゃないんかい、という）
$$
\text{Recall (再現率)} = \frac{\text{TP}}{\text{TP + FN}}
$$
Precisionは、posiと予測されたうちどれだけposiがあるかの割合。
$$
\text{Precision (適合率)} = \frac{\text{TP}}{\text{TP + FP}}
$$
<img width="230" alt="hyou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650630/a6f3a042-0f45-4c12-f909-3df84fe09481.png">　
ROCカーブでは、例えば、TPRとFPRの母数に大きな偏りがあっても両方とも割合として計算するため、その偏りを考慮することができません。不均衡なデータを取り扱う際に、そもそものposiの数が少なければ、仮にすべてをnegaと判定しても影響が少なくなってしまいます。こういう場合にPRカーブと併せて評価することが特に重要です！

### 3. 実装
最後に、以下のようなコードでプロットできます。ご参考ください。
```
from sklearn import metrics
import matplotlib.pyplot as plt

fpr, tpr, thresholds = metrics.roc_curve(true_labels, probs)
auc = metrics.auc(fpr, tpr)
plt.plot(fpr, tpr, label='ROC curve (area = %.3f)'%auc)
plt.plot(np.linspace(1, 0, len(fpr)), np.linspace(1, 0, len(fpr)), label='Random ROC curve (area = %.2f)'%0.5, linestyle = '--', color = 'gray')
plt.legend()
plt.title('ROC curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.grid(True)
plt.show()

precision, recall, thresholds = metrics.precision_recall_curve(true_labels, probs)
auc_pr = metrics.auc(recall, precision)
plt.plot(recall, precision, label='PR curve(area=%.3f)'%auc_pr)
plt.legend()
plt.title('PR curve')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.grid(True)
plt.show()
```
### 4. 実際のケース
実際に、ROCカーブとPRカーブを2つのモデルで比較してみました。
青のモデルの方がROCカーブでもPRカーブでも性能が良いことがわかります。
ちなみに、多クラス分類のROCカーブでは、着目しているクラスの確率を用いてカットオフを変えていき、2クラス分類と同様にROC、PRカーブをプロットすることができます。

<img width="250" alt="hyou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650630/4f142e3d-5cb1-b7bd-89ac-f2086133dc1e.png">　

<img width="250" alt="hyou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650630/7bb3e1d8-28c8-ec4d-0fe5-b6d4cede93b3.png">　

###### 補足：疑問点
多クラス分類のROCを描く場合、カットオフによってクラスに該当するか否かを決めていますが、通常多クラス分類ではソフトマックスで一番確率が高いものを該当クラスとして採用しますよね。
これって矛盾しないのでしょうか？わかる方がいたら是非教えてください..！