精度と再現率の逆の関係


10

精度と再現率を学習するために検索を行ったところ、一部のグラフが精度と再現率の逆関係を表していることがわかり、主題を明確にするためにそれについて考え始めました。逆の関係が常に成り立つのだろうか?バイナリ分類の問題があり、ポジティブとネガティブのラベル付きクラスがあるとします。トレーニング後、実際のポジティブな例のいくつかは真のポジティブとして予測され、それらのいくつかは偽陰性であり、実際のネガティブの例のいくつかは真のネガティブとして予測され、いくつかはそれらの偽陽性です。精度を計算して再現するために、次の式を使用します および偽陰性を減らすと真陽性が増加し、その場合はそうしませんt精度と再現率の両方が増加しますか?

Precision=TPTP+FP
Recall=TPTP+FN

回答:


6

偽陰性を減らす(より多くの陽性を選択する)場合、再現率は常に増加しますが、精度は増加または減少する可能性があります。一般に、ランダムより優れたモデルの場合、精度と再現逆の関係にありますが(@pythinkerの答え)、ランダムより悪いモデルの場合は直接的な関係にあります(@kbroseの例)。

真の分布でランダムよりも良いモデルをランダムよりも悪い性能で実行させるサンプルを人為的に構築できることは注目に値します。したがって、サンプルが真の分布に似ていると想定しています。

想起

我々は 従って、リコールのようになり 常に減少により増加。

TP=PFN
r=PFNP=1FNP
FN

精度

正確さのために、関係はそれほど単純ではありません。2つの例から始めましょう。

最初のケース:偽陰性の減少による精度の低下:

label   model prediction
1       0.8
0       0.2
0       0.2
1       0.2

しきい値(偽陰性=)の場合、0.5{10.2}

p=11+0=1

しきい値(偽陰性=)の場合、0.0{}

p=22+2=0.5

2番目のケース:偽陰性の減少による精度の向上(@kbroseの例と同じ):

label   model prediction
0       1.0
1       0.4
0       0.1

しきい値(偽陰性=)の場合、0.5{10.4}

p=00+1=0

しきい値(偽陰性=)の場合、0.0{}

p=11+2=0.33

この場合のROC曲線は、

ROCカーブに基づく精度の分析

しきい値を下げると、偽陰性が減少し、真陽性[率]が増加します。これは、ROCプロットを右に移動することと同じです。ランダムよりも良いモデル、ランダムなモデル、ランダムよりも悪いモデルのシミュレーションを行い、ROC、再現率、精度をプロットしました。

ご覧のとおり、右に移動すると、ランダムモデルよりも精度が低くなり、ランダムモデルでは精度が大幅に変動し、ランダムモデルよりも精度が高くなります。また、3つのケースすべてにわずかな変動があります。したがって、

再現率が増加することにより、モデルがランダムよりも優れている場合、精度は一般に低下します。モードがランダムよりも悪い場合、一般に精度が向上します。

シミュレーションのコードは次のとおりです。

import numpy as np
from sklearn.metrics import roc_curve
from matplotlib import pyplot

np.random.seed(123)
count = 2000
P = int(count * 0.5)
N = count - P
# first half zero, second half one
y_true = np.concatenate((np.zeros((N, 1)), np.ones((P, 1))))

title = 'Better-than-random model'
# title = 'Random model'
# title = 'Worse-than-random model'
if title == 'Better-than-random model':
    # GOOD: model output increases from 0 to 1 with noise
    y_score = np.array([p + np.random.randint(-1000, 1000)/3000
                        for p in np.arange(0, 1, 1.0 / count)]).reshape((-1, 1))
elif title == 'Random model':
    # RANDOM: model output is purely random
    y_score = np.array([np.random.randint(-1000, 1000)/3000
                        for p in np.arange(0, 1, 1.0 / count)]).reshape((-1, 1))
elif title == 'Worse-than-random model':
    # SUB RANDOM: model output decreases from 0 to -1 (worse than random)
    y_score = np.array([-p + np.random.randint(-1000, 1000)/1000
                        for p in np.arange(0, 1, 1.0 / count)]).reshape((-1, 1))

# calculate ROC (fpr, tpr) points
fpr, tpr, thresholds = roc_curve(y_true, y_score)
# calculate recall, precision, and accuracy for corresponding thresholds
# recall = TP / P
recall = np.array([np.sum(y_true[y_score > t])/P
                   for t in thresholds]).reshape((-1, 1))
# precision = TP / (TP + FP)
precision = np.array([np.sum(y_true[y_score > t])/np.count_nonzero(y_score > t)
                      for t in thresholds]).reshape((-1, 1))
# accuracy = (TP + TN) / (P + N)
accuracy = np.array([(np.sum(y_true[y_score > t]) + np.sum(1 - y_true[y_score < t]))
                     /len(y_score)
                      for t in thresholds]).reshape((-1, 1))

# Sort performance measures from min tpr to max tpr
index = np.argsort(tpr)
tpr_sorted = tpr[index]
recall_sorted = recall[index]
precision_sorted = precision[index]
accuracy_sorted = accuracy[index]

# visualize
fig, ax = pyplot.subplots(3, 1)
fig.suptitle(title, fontsize=12)

line = np.arange(0, len(thresholds))/len(thresholds)
ax[0].plot(fpr, tpr, label='ROC', color='purple')
ax[0].plot(line, line, '--', label='random', color='black')
ax[0].set_xlabel('fpr')
ax[0].legend(loc='center left', bbox_to_anchor=(1, 0.5))
ax[1].plot(line, recall, label='recall', color='blue')
ax[1].plot(line, precision, label='precision', color='red')
ax[1].plot(line, accuracy, label='accuracy', color='black')
ax[1].set_xlabel('1 - threshold')
ax[1].legend(loc='center left', bbox_to_anchor=(1, 0.5))
ax[2].plot(tpr_sorted, recall_sorted, label='recall', color='blue')
ax[2].plot(tpr_sorted, precision_sorted, label='precision', color='red')
ax[2].plot(tpr_sorted, accuracy_sorted, label='accuracy', color='black')
ax[2].set_xlabel('tpr (1 - fnr)')
ax[2].legend(loc='center left', bbox_to_anchor=(1, 0.5))

fig.tight_layout()
fig.subplots_adjust(top=0.88)
pyplot.show()

したがって、ランダムな現象が完全に支配する場合、実際には、それらは一般に逆の関係にあることが観察されます。さまざまな状況がありますが、一般に、精度を上げると、負の例をより正確に予測することを意味し、再現率を上げると、正の例をより正確に予測することを意味しますか?
Tolga Karahan

@TolgaKarahanまず、TN、TPなどに関して「より正確に」定義する必要があります。たとえば、「精度」は正と負の両方の場合、つまり(TP + TN / P + N)をプロットに追加したものです。ランダムモデルよりも良いモデルと悪いモデルがあります。
エスマイリアン

特定のクラスのすべてのラベルに対する正しく予測されたラベルの比率を意味します。TP / PまたはTN / Nのように。精度を上げると、TN / Nの増加に伴い、負の例をより正確に予測できますか?
Tolga Karahan

@TolgaKarahanあは。ランダムよりも良いモデルでは、精度の増加は再現率の減少を意味し(逆も同様)、TP / P(P = TP + FN)の減少です。TN / Nの場合、正の数を減らしてFP / Nを減らし、1-FP / N = TN / Nを増やすため、しきい値が高くなる(リコールが減少する)と、TPとFPの両方が減少することがわかります。だからあなたの質問への答えはイエスです。
Esmailian

それは良いです。最後に、TP / Pをポジティブリコールとして定義し、TN / Nをネガティブリコールとして定義すると、精度の向上とともにネガティブリコールが増加し、リコールが増加すると同じことです。ですから、ネガティブまたはポジティブな想起の増加の問題のようであり、私にとってどちらがより重要であるかです。
Tolga Karahan

3

あなたは正しい@Tolgaです。両方が同時に増加する可能性があります。次のデータを検討してください。

Prediction | True Class
       1.0 | 0
       0.5 | 1
       0.0 | 0

カットオフポイントを0.75に設定すると、

Precso=TPTP+FP=00+1=0
Recall=TPTP+FN=00+1=0

カットオフポイントを0.25に下げると、

Precso=TPTP+FP=11+1=0.5
Recall=TPTP+FN=11+0=1

ご覧のとおり、偽陰性の数を減らすと精度と再現率の両方が向上します。


1
ありがとうございました。データの配布は非常に重要であり、当然のことですが当然です。
Tolga Karahan

しかし、それでも現実的である必要があります。False Positiveの数を増やすことなくFalse Negativesの数を減らすことはできません。
Pedro Henrique Monforte

あなたはあなたの主張をバックアップするためのデータや引数を提供していません。OPのステートメントが正しい理由を正確に示す例を示します。そして私は現実的である必要があるものです。本当に?
kbrose

3

問題の明確な説明をありがとう。重要なのは、偽陰性を減らしたい場合は、決定関数のしきい値を十分に下げる必要があるということです。あなたが述べたように、偽陰性が減少した場合、真陽性は増加しますが、偽陽性も増加する可能性があります。その結果、再現率が増加し、精度が低下します。


1
私はこのトピックを学習したばかりであり、モデルの変更による影響を無視して方程式に焦点を合わせているようです。この説明は、物事を明確にするのに役立ちました。ありがとうございました。
Tolga Karahan

@TolgaKarahanどういたしまして 私の回答が役に立ったことを非常に嬉しく思います。
pythinker

これは誤りです。私の答えを見てください。
kbrose
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.