Trước khi đi sâu vào đường cong đặc tính vận hành máy thu [ROC], chúng ta sẽ xem xét hai đồ thị sẽ cung cấp một số ngữ cảnh cho cơ chế ngưỡng đằng sau đường cong ROC và PR
Trong biểu đồ, chúng tôi quan sát thấy rằng điểm số trải rộng sao cho hầu hết các nhãn dương được đặt gần 1 và rất nhiều nhãn âm gần với 0. Khi chúng tôi đặt ngưỡng cho điểm, tất cả các ngăn bên trái của nó sẽ được phân loại là 0 và mọi thứ ở bên phải sẽ là 1. Rõ ràng là có một số ngoại lệ, chẳng hạn như các mẫu âm tính mà mô hình của chúng tôi cho điểm cao và các mẫu dương tính có điểm thấp. Nếu chúng ta đặt một ngưỡng ngay ở giữa, những ngoại lệ đó sẽ lần lượt trở thành dương tính giả và âm tính giả
Khi chúng ta điều chỉnh các ngưỡng, số lượng tích cực xác thực sẽ tăng hoặc giảm, đồng thời số lượng tích cực thực sự cũng sẽ thay đổi; . Như bạn có thể thấy, mô hình dường như hoạt động khá tốt, vì tỷ lệ dương thực giảm chậm, trong khi tỷ lệ dương giả giảm mạnh khi chúng ta tăng ngưỡng. Hai đường thẳng đó đại diện cho một chiều của đường cong ROC
Tôi đã tạo một chức năng đơn giản có trong gói cho đường cong ROC. Tôi mới bắt đầu thực hành học máy, vì vậy vui lòng cho tôi biết nếu mã này có bất kỳ vấn đề gì
Hãy xem tệp github readme để biết thêm chi tiết. . ]
https. //github. com/bc123456/ROC
from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score, roc_curve
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
def plot_ROC[y_train_true, y_train_prob, y_test_true, y_test_prob]:
'''
a funciton to plot the ROC curve for train labels and test labels.
Use the best threshold found in train set to classify items in test set.
'''
fpr_train, tpr_train, thresholds_train = roc_curve[y_train_true, y_train_prob, pos_label =True]
sum_sensitivity_specificity_train = tpr_train + [1-fpr_train]
best_threshold_id_train = np.argmax[sum_sensitivity_specificity_train]
best_threshold = thresholds_train[best_threshold_id_train]
best_fpr_train = fpr_train[best_threshold_id_train]
best_tpr_train = tpr_train[best_threshold_id_train]
y_train = y_train_prob > best_threshold
cm_train = confusion_matrix[y_train_true, y_train]
acc_train = accuracy_score[y_train_true, y_train]
auc_train = roc_auc_score[y_train_true, y_train]
print 'Train Accuracy: %s ' %acc_train
print 'Train AUC: %s ' %auc_train
print 'Train Confusion Matrix:'
print cm_train
fig = plt.figure[figsize=[10,5]]
ax = fig.add_subplot[121]
curve1 = ax.plot[fpr_train, tpr_train]
curve2 = ax.plot[[0, 1], [0, 1], color='navy', linestyle='--']
dot = ax.plot[best_fpr_train, best_tpr_train, marker='o', color='black']
ax.text[best_fpr_train, best_tpr_train, s = '[%.3f,%.3f]' %[best_fpr_train, best_tpr_train]]
plt.xlim[[0.0, 1.0]]
plt.ylim[[0.0, 1.0]]
plt.xlabel['False Positive Rate']
plt.ylabel['True Positive Rate']
plt.title['ROC curve [Train], AUC = %.4f'%auc_train]
fpr_test, tpr_test, thresholds_test = roc_curve[y_test_true, y_test_prob, pos_label =True]
y_test = y_test_prob > best_threshold
cm_test = confusion_matrix[y_test_true, y_test]
acc_test = accuracy_score[y_test_true, y_test]
auc_test = roc_auc_score[y_test_true, y_test]
print 'Test Accuracy: %s ' %acc_test
print 'Test AUC: %s ' %auc_test
print 'Test Confusion Matrix:'
print cm_test
tpr_score = float[cm_test[1][1]]/[cm_test[1][1] + cm_test[1][0]]
fpr_score = float[cm_test[0][1]]/[cm_test[0][0]+ cm_test[0][1]]
ax2 = fig.add_subplot[122]
curve1 = ax2.plot[fpr_test, tpr_test]
curve2 = ax2.plot[[0, 1], [0, 1], color='navy', linestyle='--']
dot = ax2.plot[fpr_score, tpr_score, marker='o', color='black']
ax2.text[fpr_score, tpr_score, s = '[%.3f,%.3f]' %[fpr_score, tpr_score]]
plt.xlim[[0.0, 1.0]]
plt.ylim[[0.0, 1.0]]
plt.xlabel['False Positive Rate']
plt.ylabel['True Positive Rate']
plt.title['ROC curve [Test], AUC = %.4f'%auc_test]
plt.savefig['ROC', dpi = 500]
plt.show[]
return best_threshold
Một biểu đồ roc mẫu được tạo bởi mã này
Diện tích dưới đường cong ROC là một trong những số liệu hữu ích nhất để đánh giá mô hình phân loại được giám sát. Số liệu này thường được gọi là ROC-AUC. Ở đây, ROC là viết tắt của Đặc tính hoạt động của máy thu và AUC là viết tắt của Khu vực dưới đường cong. Theo tôi, AUROCC là cách viết tắt chính xác hơn nhưng có lẽ nghe không hay bằng. Trong ngữ cảnh phù hợp, AUC cũng có thể ám chỉ ROC-AUC mặc dù nó có thể đề cập đến khu vực dưới bất kỳ đường cong nào
Ảnh của Joel Filipe trên Bapt
Trong bài đăng này, chúng ta sẽ hiểu cách xây dựng đường cong ROC về mặt khái niệm và trực quan hóa đường cong ở định dạng tĩnh và tương tác trong Python
Hiểu về đường cong
Đường cong ROC cho chúng ta thấy mối quan hệ giữa Tỷ lệ dương sai [còn gọi là FPR] và Tỷ lệ dương thực [còn gọi là TPR] qua các ngưỡng khác nhau. Hãy hiểu ý nghĩa của từng thuật ngữ trong số ba thuật ngữ này
Đầu tiên, hãy bắt đầu với việc xem lại ma trận nhầm lẫn trông như thế nào
Hình ảnh của tác giả
Sau khi làm mới bộ nhớ của chúng ta về ma trận nhầm lẫn, hãy xem các thuật ngữ
Tỷ lệ tích cực sai
Chúng ta có thể tìm thấy FPR bằng công thức đơn giản bên dưới
FPR cho chúng tôi biết tỷ lệ phần trăm các bản ghi tiêu cực được dự đoán không chính xác
Hình ảnh của tác giả
Tỷ lệ tích cực thực sự
Chúng ta có thể tìm TPR bằng công thức đơn giản bên dưới
TPR cho chúng tôi biết tỷ lệ phần trăm các bản ghi tích cực được dự đoán chính xác. Điều này còn được gọi là Thu hồi hoặc Độ nhạy
Hình ảnh của tác giả
Ngưỡng
Nói chung, một mô hình phân loại có thể dự đoán xác suất trở thành một lớp nhất định cho một bản ghi nhất định. Bằng cách so sánh giá trị xác suất với giá trị ngưỡng mà chúng tôi đặt, chúng tôi có thể phân loại bản ghi thành một lớp. Nói cách khác, bạn sẽ cần xác định một quy tắc tương tự như sau
Nếu xác suất dương lớn hơn hoặc bằng ngưỡng, thì bản ghi được phân loại là dự đoán dương;
Trong ví dụ nhỏ bên dưới, chúng ta có thể thấy điểm xác suất cho ba bản ghi. Sử dụng hai giá trị ngưỡng khác nhau [0. 5 và 0. 6], chúng tôi đã phân loại từng bản ghi thành một lớp. Như bạn có thể thấy, các lớp dự đoán khác nhau tùy thuộc vào giá trị ngưỡng mà chúng tôi chọn
Hình ảnh của tác giả
Khi xây dựng ma trận nhầm lẫn và tính toán tỷ lệ như FPR và TPR, chúng tôi cần các lớp dự đoán thay vì điểm xác suất
đường cong ROC
Bây giờ chúng ta đã biết giá trị FPR, TPR và ngưỡng là gì, thật dễ hiểu đường cong ROC thể hiện điều gì. Khi xây dựng đường cong, trước tiên chúng tôi tính toán FPR và TPR trên nhiều giá trị ngưỡng. Khi chúng tôi có FPR và TPR cho các ngưỡng, sau đó chúng tôi sẽ vẽ biểu đồ FPR trên trục x và TPR trên trục y để có đường cong ROC. Đó là nó. ✨
Hình ảnh của tác giả
Diện tích dưới đường cong ROC nằm trong khoảng từ 0 đến 1. Một mô hình hoàn toàn ngẫu nhiên có AUROCC bằng 0. 5 được thể hiện bằng đường chéo hình tam giác màu xanh nét đứt bên dưới. Đường cong ROC càng xa đường này, mô hình càng có tính dự báo cao
Hình ảnh của tác giả
Bây giờ, đã đến lúc xem xét một số ví dụ mã để củng cố kiến thức của chúng ta
Xây dựng đường cong ROC tĩnh trong Python
Trước tiên hãy nhập các thư viện mà chúng ta cần cho phần còn lại của bài đăng này
import numpy as np
import pandas as pd
pd.options.display.float_format = "{:.4f}".formatfrom sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, plot_roc_curveimport matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
sns.set[palette='rainbow', context='talk']
Bây giờ chúng ta sẽ xây dựng một hàm sẽ tìm cho chúng ta số lượng dương tính giả và dương tính thật được cung cấp đúng loại, xác suất dự đoán là một loại dương tính và ngưỡng
def get_fp_tp[y, proba, threshold]:
"""Return the number of false positives and true positives."""
# Classify into classes
pred = pd.Series[np.where[proba>=threshold, 1, 0],
dtype='category']
pred.cat.set_categories[[0,1], inplace=True]
# Create confusion matrix
confusion_matrix = pred.groupby[[y, pred]].size[].unstack[]\
.rename[columns={0: 'pred_0',
1: 'pred_1'},
index={0: 'actual_0',
1: 'actual_1'}]
false_positives = confusion_matrix.loc['actual_0', 'pred_1']
true_positives = confusion_matrix.loc['actual_1', 'pred_1']
return false_positives, true_positives
Xin lưu ý rằng bạn sẽ làm việc với các tập dữ liệu được phân vùng [e. g. luyện, kiểm tra] trong thực tế. Nhưng chúng tôi sẽ không phân vùng dữ liệu của mình để đơn giản trong bài đăng này
Chúng tôi sẽ xây dựng một mô hình đơn giản trên tập dữ liệu đồ chơi và nhận xác suất dương [được biểu thị bằng giá trị 1] cho các bản ghi
# Load sample data
X = load_breast_cancer[]['data'][:,:2] # first two columns only
y = load_breast_cancer[]['target']# Train a model
log = LogisticRegression[]
log.fit[X, y]# Predict probability
proba = log.predict_proba[X][:,1]
Chúng tôi sẽ sử dụng 1001 ngưỡng khác nhau giữa 0 và 1 với số gia là 0. 001. Nói cách khác, các giá trị ngưỡng sẽ giống như 0, 0. 001, 0. 002, … 0. 998, 0. 999, 1. Hãy tìm FPR và TPR cho các giá trị ngưỡng
# Find fpr & tpr for thresholds
negatives = np.sum[y==0]
positives = np.sum[y==1]columns = ['threshold', 'false_positive_rate', 'true_positive_rate']
inputs = pd.DataFrame[columns=columns, dtype=np.number]
thresholds = np.linspace[0, 1, 1001]for i, threshold in enumerate[thresholds]:
inputs.loc[i, 'threshold'] = threshold
false_positives, true_positives = get_fp_tp[y, proba, threshold]
inputs.loc[i, 'false_positive_rate'] = false_positives/negatives
inputs.loc[i, 'true_positive_rate'] = true_positives/positives
inputs
Dữ liệu cho cốt truyện đã sẵn sàng. Hãy vẽ nó
def plot_static_roc_curve[fpr, tpr]:
plt.figure[figsize=[7,7]]
plt.fill_between[fpr, tpr, alpha=.5]
# Add dashed line with a slope of 1
plt.plot[[0,1], [0,1], linestyle=[0, [5, 5]], linewidth=2]
plt.xlabel["False Positive Rate"]
plt.ylabel["True Positive Rate"]
plt.title["ROC curve"];
plot_static_roc_curve[inputs['false_positive_rate'],
inputs['true_positive_rate']]
Mặc dù việc xây dựng chức năng tùy chỉnh giúp chúng tôi hiểu đường cong và đầu vào của nó, đồng thời kiểm soát chúng tốt hơn, nhưng chúng tôi cũng có thể tận dụng các khả năng của sklearn được tối ưu hóa hơn. Chẳng hạn, chúng ta có thể nhận FPR, TPR và các ngưỡng bằng hàm roc_curve[]
. Chúng tôi có thể vẽ dữ liệu theo cùng một cách bằng cách sử dụng chức năng vẽ đồ thị tùy chỉnh của chúng tôi
fpr, tpr, thresholds = roc_curve[y, proba]
plot_static_roc_curve[fpr, tpr]
Sklearn cũng cung cấp chức năng plot_roc_curve[]
thực hiện tất cả công việc cho chúng tôi. Tất cả những gì bạn cần là một dòng [thêm tiêu đề là tùy chọn]
plot_roc_curve[log, X, y]
plt.title["ROC curve"]; # Add a title for clarity
Vẽ đường cong ROC tương tác trong Python
Khi sử dụng các biểu đồ tĩnh, thật khó để thấy giá trị ngưỡng tương ứng cho các điểm khác nhau trên đường cong. Một tùy chọn là kiểm tra khung dữ liệu
def get_fp_tp[y, proba, threshold]:
"""Return the number of false positives and true positives."""
# Classify into classes
pred = pd.Series[np.where[proba>=threshold, 1, 0],
dtype='category']
pred.cat.set_categories[[0,1], inplace=True]
# Create confusion matrix
confusion_matrix = pred.groupby[[y, pred]].size[].unstack[]\
.rename[columns={0: 'pred_0',
1: 'pred_1'},
index={0: 'actual_0',
1: 'actual_1'}]
false_positives = confusion_matrix.loc['actual_0', 'pred_1']
true_positives = confusion_matrix.loc['actual_1', 'pred_1']
return false_positives, true_positives
0 mà chúng tôi đã tạo. Một tùy chọn khác là tạo phiên bản tương tác của biểu đồ để chúng tôi có thể thấy FPR và TPR cùng với giá trị ngưỡng tương ứng khi chúng tôi di chuột qua biểu đồdef plot_interactive_roc_curve[df, fpr, tpr, thresholds]:
fig = px.area[
data_frame=df,
x=fpr,
y=tpr,
hover_data=thresholds,
title='ROC Curve'
]
fig.update_layout[
autosize=False,
width=500,
height=500,
margin=dict[l=30, r=30, b=30, t=30, pad=4],
title_x=.5, # Centre title
hovermode = 'closest',
xaxis=dict[hoverformat='.4f'],
yaxis=dict[hoverformat='.4f']
]
hovertemplate = 'False Positive Rate=%{x}
True Positive Rate=%{y}
Threshold=%{customdata[0]:.4f}'
fig.update_traces[hovertemplate=hovertemplate]
# Add dashed line with a slope of 1
fig.add_shape[type='line', line=dict[dash='dash'], x0=0, x1=1, y0=0, y1=1]
fig.show[]plot_interactive_roc_curve[df=inputs,
fpr='false_positive_rate',
tpr='true_positive_rate',
thresholds=['threshold']]
Tính tương tác khá hữu ích phải không?
Hy vọng bạn thích học cách xây dựng và trực quan hóa đường cong ROC. Một khi bạn hiểu đường cong này, thật dễ dàng để hiểu một đường cong liên quan khác. Đường cong thu hồi chính xác
Ảnh của Mael Pavageau trên Bapt
Bạn có muốn truy cập nhiều nội dung như thế này? . Nếu bạn trở thành thành viên bằng liên kết giới thiệu của tôi, một phần phí thành viên của bạn sẽ trực tiếp hỗ trợ tôi