Nếu chúng ta giảm âm tính giả (chọn thêm số dương), thu hồi luôn tăng, nhưng độ chính xác có thể tăng hoặc giảm. Nói chung, đối với các mô hình tốt hơn ngẫu nhiên, độ chính xác và thu hồi có mối quan hệ nghịch đảo ( câu trả lời của @pythinker ), nhưng đối với các mô hình xấu hơn ngẫu nhiên, chúng có mối quan hệ trực tiếp ( ví dụ của @kbrose ).
Điều đáng chú ý là chúng ta có thể xây dựng một mẫu một cách giả tạo một mô hình tốt hơn so với ngẫu nhiên trên phân phối thực để thực hiện kém hơn ngẫu nhiên, vì vậy chúng tôi giả định rằng mẫu đó giống với phân phối thực.
Gợi lại
Do đó, chúng ta có
, thu hồi sẽ là
luôn tăng khi giảm .TP= P- FN
r =P- FNP= 1 -FNP
FN
Độ chính xác
Đối với độ chính xác, mối quan hệ không đơn giản như vậy. Hãy bắt đầu với hai ví dụ.
Trường hợp đầu tiên : giảm độ chính xác, bằng cách giảm âm tính giả:
label model prediction
1 0.8
0 0.2
0 0.2
1 0.2
Đối với ngưỡng (sai âm = ),0.5{(1,0.2)}
p=11+0=1
Đối với ngưỡng (sai âm = ),0.0{}
p=22+2=0.5
Trường hợp thứ hai : tăng độ chính xác, bằng cách giảm âm tính giả (giống như ví dụ @kbrose ):
label model prediction
0 1.0
1 0.4
0 0.1
Đối với ngưỡng (sai âm = ),0.5{(1,0.4)}
p=00+1=0
Đối với ngưỡng (sai âm = ),0.0{}
p=11+2=0.33
Điều đáng chú ý là đường cong ROC cho trường hợp này là
Phân tích độ chính xác dựa trên đường cong ROC
Khi chúng ta hạ thấp ngưỡng, âm tính giả sẽ giảm và [tỷ lệ] dương thực sự tăng, tương đương với việc di chuyển sang phải trong biểu đồ ROC . Tôi đã thực hiện một mô phỏng cho các mô hình tốt hơn ngẫu nhiên, ngẫu nhiên và tồi tệ hơn ngẫu nhiên, và vẽ ROC, thu hồi và độ chính xác:
Như bạn có thể thấy, bằng cách di chuyển sang phải, đối với mô hình tốt hơn ngẫu nhiên, độ chính xác giảm, đối với mô hình ngẫu nhiên, độ chính xác có dao động đáng kể và tăng độ chính xác của mô hình kém hơn ngẫu nhiên. Và có sự dao động nhẹ trong cả ba trường hợp. Vì thế,
Bằng cách tăng thu hồi, nếu mô hình tốt hơn ngẫu nhiên, độ chính xác thường giảm. Nếu chế độ tệ hơn ngẫu nhiên, độ chính xác thường tăng.
Đây là mã cho mô phỏng:
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()