【データサイエンスクイズ】ROC曲線とPR曲線がどうなるか分かりますか？

**※以下を読み込んでおいてください。**

```python
import numpy as np
from matplotlib import pyplot as plt
from scipy import stats
from sklearn.metrics import (PrecisionRecallDisplay, RocCurveDisplay,
                             average_precision_score, precision_recall_curve)
``` 


# クイズです！第1問！

データ数が1万件の二値分類で、真値の前半5000件が陰性、後半5000件が陽性とします。

```python
num_total = 10000
num_one = 5000
y_true = [0] * (num_total - num_one) + [1] * num_one
```

予測値は[0,1]のランダムな連続値の予測とします。

```python
y_pred = np.random.uniform(low=0.0, high=1.0, size=(num_total,))
```

このとき、ROC曲線はどうなるでしょうか？

```python
def show_roc_curve(y_true, y_pred):
    RocCurveDisplay.from_predictions(
        y_true,
        y_pred,
        color="darkorange",
    )
    plt.plot([0, 1], [0, 1], "k--", label="chance level (AUC = 0.5)")
    plt.axis("square")
    plt.xlabel("False Positive Rate")
    plt.ylabel("True Positive Rate")
    plt.title("ROC Curve")
    plt.legend()
    plt.show()
```

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/8d2c301e-a8bb-4b0b-bb26-e60cbfc8756c.png">

傾き1の（ほぼ）直線になります（オレンジ色の線）。ROC-AUCは0.5になります。

</details>

では、PR（Precision-Recall）曲線はどうなるでしょうか？

```python
def show_pr_curve(y_true, y_pred):
    precision, recall, thresholds = precision_recall_curve(y_true, y_pred)
    average_precision = average_precision_score(y_true, y_pred, average="micro")

    display = PrecisionRecallDisplay(
        recall=recall,
        precision=precision,
        average_precision=average_precision
    )
    display.plot(color="darkorange")
    _ = display.ax_.set_ylim([-0.05, 1.05])
    display.ax_.legend(loc="best")
    display.ax_.set_title("PR Curve")![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/3de376e3-6f88-5a2a-5b27-7a03bc8f1038.png)

    plt.show()
```

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/bae315fd-1858-7075-f449-f186df4961fc.png">

しきい値を1.0にすると全部陰性と予測するので定義的にPrecisionは1.0。しきい値を下げ始めると、ランダム予測なのでPrecisionは下がります。ランダム予測なので、陽性予測の数が少ないうちはばらつきが大きく、Precisionがかなり小さくなる場合もあります。さらにしきい値を下げていくと、ランダム予測なので、Precisionは全体の陽性の割合に近づいていきます。今は陽性の割合は50%なので、ランダムに予測すれば予測したうちの50%が正解になるはずです。

二値分類の予測は0と1が排他的なので、しきい値を下げていけばRecallは増加します。したがって、Recallは1.0に近づきつつ、Precisionは0.5を保つような曲線になります。

RP-AUCは（ほぼ）0.5になります。

</details>

# では第2問！

データ数が1万件の二値分類で、真値の前半9000件が陰性、後半1000件が陽性とします。予測値は[0,1]のランダムな連続値の予測とします。


```python
num_total = 10000
num_one = 5000
y_true = [0] * (num_total - num_one) + [1] * num_one
y_pred = np.random.uniform(low=0.0, high=1.0, size=(num_total,))
```

先程の問題を踏まえて、ROC曲線とPR曲線がどんな形状になるか考えてください。

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/587e6e1a-927d-66b6-153a-d37239db0566.png">

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/30697cb5-7317-1282-f41f-0867054847b0.png">

</details>

# では第3問！

データ数が1万件の二値分類で、真値の前半5000件が陰性、後半5000件が陽性とします。
予測値は[0,1]のランダムな連続値の予測としますが、確率密度関数はベータ分布$B(2, 5.1)$とします。`y_pred`は0.5より大きい値の割合が約10%になります。


```python
num_total = 10000
num_one = 5000
y_true = [0] * (num_total - num_one) + [1] * num_one
y_pred = stats.beta.rvs(a=2,b=5.1,size=(num_total,))
```

```python
(y_pred>0.5).sum()
# 1005
```

ROC曲線とPR曲線がどんな形状になるか考えてください。

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/959f48cd-2144-17e1-efbd-2ed7421db1fc.png">

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/738dd53c-16e4-2ec9-21a7-0ab1a1fc9715.png">

</details>

# では第4問！

データ数が1万件の二値分類で、真値の前半9990件が陰性、後半10件が陽性とします。
予測値は最後尾のみ1の予測とします。

```python
num_total = 10000
num_one = 10
y_true = [0] * (num_total - num_one) + [1] * num_one

pos = 1
y_pred = [0] * (num_total - pos) + [1] * pos
```


ROC曲線とPR曲線がどんな形状になるか考えてください。

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/1841f055-2586-e9b2-e5ed-2732aab53b32.png">

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/72226f70-6eb4-5dd3-fd92-dec1f4a78bbb.png">

</details>


# では第5問！

データ数が1万件の二値分類で、真値の前半9990件が陰性、後半10件が陽性とします。
予測値は最後尾から20件を陽性の予測とします。

```python
num_total = 10000
num_one = 10
y_true = [0] * (num_total - num_one) + [1] * num_one

pos = 20
y_pred = [0] * (num_total - pos) + [1] * pos
```

ROC曲線とPR曲線がどんな形状になるか考えてください。

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/54af972c-d8c3-a961-7237-1736f737f068.png">

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/74711fb4-b7cb-ce55-d631-652ea88d5dac.png">

</details>

# では第6問！

データ数が1万件の二値分類で、真値の前半9990件が陰性、後半10件が陽性とします。
予測値は先頭から100件と、最後尾から10件を陽性の予測とします。

```python
num_total = 10000
num_one = 10
y_true = [0] * (num_total - num_one) + [1] * num_one

y_pred = [1]*100 + [0]*(num_total-110) + [1]*10
```

ROC曲線とPR曲線がどんな形状になるか考えてください。

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/26e3779b-f73a-b41e-d21e-83f47a46f561.png">

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/40d751fc-7855-4975-7fea-b22abaad12a4.png">

</details>

# では第7問！最終問題です！

データ数が1万件の二値分類で、真値の前半9990件が陰性、後半10件が陽性とします。
予測値は先頭から9990件が陽性、最後尾から10件を陰性の予測とします。
つまり予測を全て外しています。

```python
num_total = 10000
num_one = 10
y_true = [0] * (num_total - num_one) + [1] * num_one

pos = 10
y_pred = [1] * (num_total - pos) + [0] * pos
```

ROC曲線とPR曲線がどんな形状になるか考えてください。

<details><summary>答え</summary>

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/b9b5260b-4281-ead8-2e91-2be9def7d500.png">

<img width=400px src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/711332e2-b2a5-3055-007b-6fc4790a66ae.png">

</details>

# おわりに

いかがでしたか？皆さんは何問正解できましたか？
また、正例・負例に偏りがあるときの評価指標として、ROCとPRが適切かどうか理解できましたか？
不均衡データとの向き合い方は下記も参考になります。

- [不均衡データとの向き合い方](https://qiita.com/dcm_yukimasa-kaneda/items/5eaadbdeec10d92020c6)