Đường cong ROC Python

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}".format
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, plot_roc_curve
import 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

Đường cong ROC cho bạn biết điều gì?

Đường cong ROC thể hiện sự đánh đổi giữa độ nhạy [hoặc TPR] và độ đặc hiệu [1 – FPR] . Các bộ phân loại cung cấp các đường cong gần góc trên bên trái hơn cho thấy hiệu suất tốt hơn. Là một đường cơ sở, một bộ phân loại ngẫu nhiên dự kiến ​​sẽ cho các điểm nằm dọc theo đường chéo [FPR = TPR].

Làm cách nào để sử dụng điểm ROC AUC trong Python?

Đường cong ROC và AUC trong Python . Giống như hàm roc_curve[], hàm AUC lấy cả kết quả thực [0,1] từ tập kiểm tra và xác suất dự đoán cho lớp 1. The AUC for the ROC can be calculated using the roc_auc_score[] function. Like the roc_curve[] function, the AUC function takes both the true outcomes [0,1] from the test set and the predicted probabilities for the 1 class.

ROC và AUC có giống nhau không?

ROC là một đường cong xác suất và AUC biểu thị mức độ hoặc thước đo khả năng phân tách. Nó cho biết mức độ mô hình có khả năng phân biệt giữa các lớp. AUC càng cao, mô hình càng dự đoán tốt hơn các lớp 0 là 0 và 1 lớp là 1

Chủ Đề