Wenn wir das falsche Negativ verringern (mehr Positive auswählen), erhöht sich der Rückruf immer, aber die Genauigkeit kann zunehmen oder abnehmen. Im Allgemeinen haben Präzision und Rückruf für Modelle, die besser als zufällig sind, eine umgekehrte Beziehung ( Antwort von @pythinker ), aber für Modelle, die schlechter als zufällig sind, eine direkte Beziehung ( Beispiel von @kbrose ).
Es ist erwähnenswert, dass wir künstlich eine Stichprobe erstellen können, die bewirkt, dass ein Modell, das bei wahrer Verteilung besser als zufällig ist, schlechter als zufällig abschneidet. Daher gehen wir davon aus, dass die Stichprobe der wahren Verteilung ähnelt.
Erinnern
Wir haben
daher wäre der Rückruf
was immer mit der Abnahme von zunimmt .T.P.= P.- F.N.
r =P.- F.N.P.= 1 -F.N.P.
F.N.
Präzision
Aus Gründen der Genauigkeit ist die Beziehung nicht so einfach. Beginnen wir mit zwei Beispielen.
Erster Fall : Abnahme der Präzision durch Abnahme des falsch negativen:
label model prediction
1 0.8
0 0.2
0 0.2
1 0.2
Für den Schwellenwert (falsch negativ = ),0,5{ ( 1 , 0,2 ) }
p =11 + 0= 1
Für den Schwellenwert (falsch negativ = )0.0{ }
p =22 + 2= 0,5
Zweiter Fall : Erhöhung der Präzision durch Verringerung des falsch negativen Werts (wie im Beispiel @kbrose ):
label model prediction
0 1.0
1 0.4
0 0.1
Für den Schwellenwert (falsch negativ = ),0,5{ ( 1 , 0,4 ) }
p =00 + 1= 0
Für den Schwellenwert (falsch negativ = )0.0{ }
p =11 + 2= 0,33
Es ist erwähnenswert, dass die ROC-Kurve für diesen Fall ist
Präzisionsanalyse basierend auf der ROC-Kurve
Wenn wir den Schwellenwert senken, nimmt falsch negativ ab und wahr positiv [Rate] nimmt zu, was einer Bewegung nach rechts im ROC-Diagramm entspricht . Ich habe eine Simulation für Modelle durchgeführt, die besser als zufällig, zufällig und schlechter als zufällig sind, und ROC, Rückruf und Präzision aufgezeichnet:
Wie Sie sehen können, nimmt die Genauigkeit bei einem Modell, das besser als zufällig ist, erheblich ab, wenn Sie sich nach rechts bewegen. Bei einem zufälligen Modell weist die Genauigkeit erhebliche Schwankungen auf und bei einem Modell, das schlechter als zufällig ist, nimmt die Genauigkeit zu. In allen drei Fällen gibt es leichte Schwankungen. Deshalb,
Wenn das Modell durch Erhöhen des Rückrufs besser als zufällig ist, nimmt die Genauigkeit im Allgemeinen ab. Wenn der Modus schlechter als zufällig ist, erhöht sich die Genauigkeit im Allgemeinen.
Hier ist der Code für die Simulation:
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()