大俠幸會,在下全網同名「演算法金」 0 基礎轉 AI 上岸,多個演算法賽 Top 「日更萬日,讓更多人享受智慧樂趣」
在機器學習和資料科學的江湖中,評估模型的好壞是非常關鍵的一環。而 ROC(Receiver Operating Characteristic)曲線和 AUC(Area Under Curve)正是評估分類模型效能的重要工具。
這個知識點在面試中也很頻繁的出現。儘管理解這些概念本身不難,但許多人在複習時容易混淆,或在面試緊張時忘記,影響回答效果。
本篇文章將會從基礎概念入手,逐步深入到實際操作。我們會詳細解釋 ROC 曲線和 AUC 的定義和意義,透過例項和程式碼示範幫助大俠掌握這些工具的使用方法,最後透過一些實際應用案例和相關概念的對比,力求全面理解並靈活運用 ROC 和 AUC。
1. 基礎概念介紹
1.1 什麼是 ROC 曲線
ROC 曲線,即接收者操作特徵曲線,ROC曲線產生於第二次世界大戰期間,最早用在訊號檢測領域,偵測戰場上的敵軍載具(飛機、船艦)。現在是是用來評價二分類模型效能的常用圖形工具。它透過顯示真陽性率(True Positive Rate,簡稱 TPR)與假陽性率(False Positive Rate,簡稱 FPR)之間的權衡來幫助我們理解模型的分類能力。
1.2 什麼是 AUC
AUC,即曲線下面積(Area Under Curve),是 ROC 曲線下面積的一個數值表示。它提供了一個定量的指標,用來衡量分類模型的整體表現。AUC 值範圍從 0 到 1,值越大表示模型效能越好。
1.3 為何需要 ROC/AUC
在分類任務中,特別是當資料集類別不平衡時,單純依賴準確率(Accuracy)可能會造成誤導。為了更好地理解這一點,讓我們透過一個例子來說明。
例子說明
假設我們有一個武俠元素的資料集,其中 95% 的樣本是普通弟子,5% 的樣本是高手。
讓我們透過程式碼示例來演示這一點(程式碼供復現使用,可直接跳過下滑到解釋部分):
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve, roc_auc_score, accuracy_score, confusion_matrix
# 生成一個極度不平衡的武俠資料集
# 假設特徵表示武功修煉時間、戰鬥勝率等,標籤表示是否為高手
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, weights=[0.95, 0.05], random_state=42)
# 將資料集分為訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 建立一個總是預測普通弟子的模型
class AlwaysNegativeModel:
def predict(self, X):
return np.zeros(X.shape[0])
# 訓練和預測
model = AlwaysNegativeModel()
y_pred = model.predict(X_test)
# 計算混淆矩陣和準確率
cm = confusion_matrix(y_test, y_pred)
accuracy = accuracy_score(y_test, y_pred)
# 計算 ROC 曲線和 AUC
# 在這裡我們需要一個機率預測來計算 ROC 曲線和 AUC,為了演示,我們假設模型輸出的是一個常量機率
y_pred_prob = np.zeros(X_test.shape[0])
fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob)
auc = roc_auc_score(y_test, y_pred_prob)
# 視覺化結果
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title("混淆矩陣")
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
plt.colorbar()
plt.xlabel("預測標籤")
plt.ylabel("真實標籤")
plt.xticks([0, 1], ["普通弟子", "高手"])
plt.yticks([0, 1], ["普通弟子", "高手"])
for i in range(2):
for j in range(2):
plt.text(j, i, cm[i, j], ha="center", va="center", color="red")
print(f"準確率: {accuracy:.2f}")
print(f"AUC: {auc:.2f}")
結果分析
如果我們使用一個簡單的分類器,它總是預測所有樣本為普通弟子。
這個模型的準確率為 95%,看起來表現很好,但實際上它根本無法識別高手,是一個毫無用處的分類器。
這個分類器沒有任何實際的分類能力,因為它無法識別出真正的高手。
- ROC 曲線和 AUC:透過繪製 ROC 曲線並計算 AUC,我們可以看到 AUC 為 0.50,這表明模型沒有任何區分能力。ROC 曲線是一條對角線,顯示模型在隨機猜測。
準確率只告訴我們模型整體預測正確的比例,但在類別不平衡的情況下,這個指標可能會誤導我們。ROC 曲線和 AUC 提供了更全面的視角,展示了模型在不同閾值下的效能,幫助我們更準確地評估模型的分類能力。
更多內容,見免費知識星球
2. 詳細解釋
2.1 TPR(True Positive Rate)和 FPR(False Positive Rate)的定義
要理解 ROC 曲線,首先需要明白 TPR 和 FPR 的概念:
- TPR(True Positive Rate):也稱為靈敏度(Sensitivity)或召回率(Recall),表示的是在所有真實為正的樣本中,被正確預測為正的比例。其計算公式為:
其中,TP(True Positives)是將正類正確分類為正類的樣本數,FN(False Negatives)是將正類錯誤分類為負類的樣本數。
- FPR(False Positive Rate):表示的是在所有真實為負的樣本中,被錯誤預測為正的比例。其計算公式為:
其中,FP(False Positives)是將負類錯誤分類為正類的樣本數,TN(True Negatives)是將負類正確分類為負類的樣本數。
2.2 AUC 的數學定義
AUC(Area Under Curve)是 ROC 曲線下的面積,用於評估分類模型的效能。AUC 值的範圍從 0 到 1,值越大表示模型的效能越好。
數學上,AUC 可以透過積分計算:
在離散情況下,AUC 可以透過梯形法則近似計算:
3 繪製 ROC 曲線的步驟
繪製 ROC 曲線的步驟如下:
- 選擇閾值:從 0 到 1 的不同閾值。
- 計算 TPR 和 FPR:對於每個閾值,計算相應的 TPR 和 FPR。
- 繪製曲線:以 FPR 為橫軸,TPR 為縱軸,繪製 ROC 曲線。
選擇閾值:從 0 到 1 的不同閾值
from sklearn.metrics import roc_curve
# 預測測試集機率
y_pred_prob = model.predict_proba(X_test)[:, 1]
# 計算 ROC 曲線
fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob)
# 輸出部分閾值
print("閾值: ", thresholds[:10]) # 僅展示前10個閾值
計算 TPR 和 FPR:對於每個閾值,計算相應的 TPR 和 FPR
# 輸出部分閾值對應的 TPR 和 FPR
for i in range(10): # 僅展示前10個閾值的對應值
print(f"閾值: {thresholds[i]:.2f} -> 假陽性率 (FPR): {fpr[i]:.2f}, 真陽性率 (TPR): {tpr[i]:.2f}")
繪製曲線:以 FPR 為橫軸,TPR 為縱軸,繪製 ROC 曲線
import matplotlib.pyplot as plt
# 視覺化 ROC 曲線
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='blue', lw=2, label='ROC 曲線')
plt.plot([0, 1], [0, 1], color='gray', lw=1, linestyle='--', label='隨機猜測')
plt.xlabel("假陽性率 (FPR)")
plt.ylabel("真陽性率 (TPR)")
plt.title("ROC 曲線")
plt.legend(loc="lower right")
# 在曲線上標出幾個閾值點
threshold_points = [0.2, 0.5, 0.8]
for threshold in threshold_points:
idx = np.where(thresholds >= threshold)[0][0]
plt.scatter(fpr[idx], tpr[idx], marker='o', color='red')
plt.text(fpr[idx], tpr[idx], f"閾值={threshold:.2f}", fontsize=12)
plt.show()
4 AUC 的意義
AUC 值越大,模型的效能越好。具體來說:
- AUC = 0.5 表示模型沒有分類能力,相當於隨機猜測。
- 0.5 < AUC < 0.7 表示模型有一定的分類能力,但效果一般。
- 0.7 ≤ AUC < 0.9 表示模型有較好的分類能力。
- AUC ≥ 0.9 表示模型有非常好的分類能力。
AUC 的優缺點
優點:
- 閾值無關:AUC 衡量的是模型在所有可能的分類閾值下的表現,因此不受單一閾值的影響。
- 綜合效能評估:AUC 綜合了 TPR 和 FPR 的資訊,能夠全面評估模型的效能。
缺點:
- 可能不適用於極度不平衡的資料:在極度不平衡的資料集上,AUC 可能無法準確反映模型的效能,需要結合其他評估指標使用。
- 解釋複雜:對於非專業人士來說,AUC 的解釋和理解可能比較困難。
程式碼示例
下面我們透過程式碼示例來計算 AUC 並解釋其意義:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, roc_auc_score, accuracy_score, confusion_matrix
# 生成一個不平衡的武俠資料集
# 假設特徵表示武功修煉時間、戰鬥勝率等,標籤表示是否為高手
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, weights=[0.9, 0.1], random_state=42)
# 將資料集分為訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 訓練一個邏輯迴歸模型
model = LogisticRegression()
model.fit(X_train, y_train)
# 預測測試集
y_pred_prob = model.predict_proba(X_test)[:, 1]
# 計算 ROC 曲線和 AUC
fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob)
auc = roc_auc_score(y_test, y_pred_prob)
# 視覺化結果
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title("ROC 曲線")
plt.plot(fpr, tpr, color='blue', lw=2, label=f"AUC = {auc:.2f}")
plt.plot([0, 1], [0, 1], color='gray', lw=1, linestyle='--')
plt.xlabel("假陽性率")
plt.ylabel("真陽性率")
plt.legend(loc="lower right")
plt.subplot(1, 2, 2)
plt.title("AUC 值示意")
plt.fill_between(fpr, tpr, color='blue', alpha=0.3)
plt.plot(fpr, tpr, color='blue', lw=2, label=f"AUC = {auc:.2f}")
plt.xlabel("假陽性率")
plt.ylabel("真陽性率")
plt.legend(loc="lower right")
plt.tight_layout()
plt.show()
print(f"AUC: {auc:.2f}")
ROC 曲線圖
- 橫軸(假陽性率,FPR):表示負類樣本中被錯誤分類為正類的比例。
- 縱軸(真陽性率,TPR):表示正類樣本中被正確分類為正類的比例。
- 藍色曲線:展示了模型在不同閾值下的 FPR 和 TPR 之間的關係。
- 灰色虛線:表示一個隨機猜測模型的表現,其 AUC 值為 0.5。
- AUC 值:圖中顯示的 AUC 值(在圖例中標註),越接近 1 說明模型的分類效能越好。
AUC 值示意圖
- 藍色區域:ROC 曲線下的面積,即 AUC 值。這個面積越大,說明模型的分類效能越好。
- AUC 值標註:同樣在圖例中標註了 AUC 值。
透過這兩個圖,可以直觀地看到模型在不同閾值下的分類效能,以及透過 AUC 值來量化這種效能。
5. 實際應用案例
為了讓大俠更好地理解 ROC 和 AUC 在實際中的應用,我們將展示它們在不同領域中的應用,如醫學診斷和金融風險評估,並透過實際案例進行程式碼實現。
5.1 在不同領域中的應用
醫學診斷
在醫學診斷中,ROC 曲線和 AUC 被廣泛用於評估診斷測試的效能。例如,在篩查癌症時,醫生希望測試能夠正確識別出患病和未患病的患者。ROC 曲線可以幫助醫生選擇最佳的閾值,從而最大化檢測的準確性。
金融風險評估
在金融領域,ROC 和 AUC 被用於評估信用評分模型的效能。例如,銀行希望識別高風險借款人,以降低貸款違約率。ROC 曲線可以幫助銀行選擇適當的閾值,以平衡風險和收益。
5.2 實際案例分析及程式碼實現
我們將使用一個模擬的醫學診斷資料集來演示如何應用 ROC 和 AUC。假設我們有一個資料集,包含患者的各種特徵以及他們是否患有某種疾病。
程式碼示例和結果分析
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, roc_auc_score, accuracy_score, confusion_matrix
# 載入乳腺癌資料集
data = load_breast_cancer()
X = data.data
y = data.target
# 將資料集分為訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 訓練一個邏輯迴歸模型
model = LogisticRegression(max_iter=10000)
model.fit(X_train, y_train)
# 預測測試集
y_pred = model.predict(X_test)
y_pred_prob = model.predict_proba(X_test)[:, 1]
# 計算混淆矩陣和準確率
cm = confusion_matrix(y_test, y_pred)
accuracy = accuracy_score(y_test, y_pred)
# 計算 ROC 曲線和 AUC
fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob)
auc = roc_auc_score(y_test, y_pred_prob)
# 視覺化結果
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title("混淆矩陣")
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
plt.colorbar()
plt.xlabel("預測標籤")
plt.ylabel("真實標籤")
plt.xticks([0, 1], ["未患病", "患病"])
plt.yticks([0, 1], ["未患病", "患病"])
for i in range(2):
for j in range(2):
plt.text(j, i, cm[i, j], ha="center", va="center", color="red")
plt.subplot(1, 2, 2)
plt.title("ROC 曲線")
plt.plot(fpr, tpr, color='blue', lw=2, label=f"AUC = {auc:.2f}")
plt.plot([0, 1], [0, 1], color='gray', lw=1, linestyle='--', label='隨機猜測')
plt.xlabel("假陽性率")
plt.ylabel("真陽性率")
plt.legend(loc="lower right")
plt.tight_layout()
plt.show()
print(f"準確率: {accuracy:.2f}")
print(f"AUC: {auc:.2f}")
結果分析
- 準確率:模型的準確率(Accuracy)為 0.98,這意味著在所有測試樣本中,有 98% 的樣本被正確分類。
- AUC 值:AUC 值為 0.998,這意味著模型在區分未患病和患病患者方面表現非常完美。AUC = 0.998 表示模型在所有可能的閾值下都能完全區分正類和負類樣本,這是一種理想狀態。
解釋
- 準確率為 0.98:在大多數情況下,這是一個很高的準確率,表明模型幾乎所有的預測都是正確的。
- AUC = 0.998:表示模型在所有可能的閾值下都能完全區分未患病和患病患者,展示了模型極高的區分能力。
6. 相關概念的對照和對比
在這部分內容中,我們將對 ROC/AUC 與其他評估指標進行對照和對比,以便大俠更全面地理解這些指標在模型評估中的作用。
6.1 ROC/AUC 與混淆矩陣
混淆矩陣是一種用來評價分類模型效能的工具,它透過展示真陽性(TP)、假陽性(FP)、真陰性(TN)和假陰性(FN)的數量來評估模型。ROC 曲線和 AUC 則是從不同的閾值下綜合評估模型的效能。
示例程式碼:
from sklearn.metrics import confusion_matrix, accuracy_score
# 預測測試集
y_pred = model.predict(X_test)
y_pred_prob = model.predict_proba(X_test)[:, 1]
# 計算混淆矩陣
cm = confusion_matrix(y_test, y_pred)
accuracy = accuracy_score(y_test, y_pred)
# 輸出混淆矩陣和準確率
print("混淆矩陣:")
print(cm)
6.2 ROC/AUC 與 PR 曲線
PR 曲線(Precision-Recall Curve)是另一種評估二分類模型的方法,特別適用於不平衡資料集。它透過展示查準率(Precision)和召回率(Recall)之間的關係來評估模型效能。
- 查準率(Precision):表示在所有被預測為正類的樣本中,實際為正類的比例。
- 召回率(Recall):表示在所有實際為正類的樣本中,被正確預測為正類的比例。
示例程式碼:
from sklearn.metrics import precision_recall_curve
# 計算 PR 曲線
precision, recall, _ = precision_recall_curve(y_test, y_pred_prob)
# 視覺化 PR 曲線
plt.figure()
plt.plot(recall, precision, color='blue', lw=2, label='PR 曲線')
plt.xlabel("召回率")
plt.ylabel("查準率")
plt.title("PR 曲線")
plt.legend(loc="lower left")
plt.show()
6.3 其他評估指標(如 Precision、Recall)與 ROC/AUC 的關係
除了 ROC/AUC 和 PR 曲線,其他常用的評估指標還有:
- 準確率(Accuracy):表示被正確分類的樣本佔總樣本的比例。
- 查準率(Precision):表示在所有被預測為正類的樣本中,實際為正類的比例。
- 召回率(Recall):表示在所有實際為正類的樣本中,被正確預測為正類的比例。
- F1 分數(F1 Score):查準率和召回率的調和平均數,用於綜合評價模型的精確性和召回率。
示例程式碼:
from sklearn.metrics import precision_score, recall_score, f1_score
# 計算查準率、召回率和 F1 分數
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
# 輸出結果
print(f"查準率: {precision:.2f}")
print(f"召回率: {recall:.2f}")
print(f"F1 分數: {f1:.2f}")
7. 誤區和注意事項
在使用 ROC 和 AUC 評估分類模型效能時,大俠需要注意一些常見的誤區和使用注意事項,以便準確地理解和應用這些指標。
7.1 常見誤區
誤區一:高準確率等於高效能
高準確率並不一定意味著模型效能優秀,尤其是在類別不平衡的情況下。正如前文所示,即使一個模型總是預測為大多數類,其準確率也可能很高,但其實際分類能力可能非常差。
誤區二:AUC 值越高越好
雖然 AUC 值高表示模型效能好,但在某些應用場景下,其他指標如查準率(Precision)和召回率(Recall)可能更加重要。例如,在醫療診斷中,召回率(即靈敏度)通常比 AUC 更加關鍵,因為漏診的代價非常高。
誤區三:單一指標評價模型
依賴單一指標評價模型效能是不全面的。最好結合多個指標(如 AUC、準確率、查準率、召回率和 F1 分數)來綜合評估模型的效能。
7.2 使用 ROC/AUC 時的注意事項
注意事項一:資料不平衡問題
在處理類別不平衡的資料集時,AUC 和 ROC 曲線可以提供更全面的評估,但仍需要結合 PR 曲線等其他指標進行綜合分析。
注意事項二:選擇合適的閾值
ROC 曲線展示了模型在不同閾值下的效能表現,需要根據具體應用場景選擇合適的閾值。例如,在金融風險評估中,選擇較低的閾值可能會增加風險,但可以減少漏檢。
注意事項三:模型的校準
確保模型的機率輸出是校準的,即輸出的機率與實際發生的機率一致。模型校準可以透過可靠性圖(Calibration Curve)等方法進行評估和調整。
[ 抱個拳,總個結 ]
經過前面的詳細講解,我們已經全面瞭解了 ROC 曲線和 AUC 的概念、計算方法、程式碼實現以及在不同領域中的應用。下面對文章的核心內容進行簡要回顧:
核心要點回顧
- 基礎概念:ROC 曲線是用來評價二分類模型效能的工具,透過顯示真陽性率(TPR)和假陽性率(FPR)之間的權衡來幫助我們理解模型的分類能力。AUC(曲線下面積)是 ROC 曲線下的面積,用於量化模型的整體表現。
- 詳細解釋:我們詳細解釋了 TPR 和 FPR 的定義,繪製 ROC 曲線的步驟,並透過例項程式碼演示瞭如何計算和繪製 ROC 曲線以及 AUC。還對 AUC 的數學定義、意義及其優缺點進行了分析。
- 程式碼示範:透過使用 Python 和 scikit-learn 庫,我們實現瞭如何計算和繪製 ROC 曲線及 AUC,並透過例項展示了這些指標在實際應用中的效果。
- 實際應用案例:我們使用乳腺癌資料集進行模型訓練和評估,展示了 ROC 和 AUC 在醫學診斷中的實際應用,並透過程式碼詳細演示瞭如何計算和解釋這些指標。
- 相關概念對照和對比:我們對 ROC/AUC 與混淆矩陣、PR 曲線等其他評估指標進行了對照和對比,幫助全面理解這些指標的作用,並根據具體應用場景選擇合適的評估方法。
- 誤區和注意事項:我們討論了在使用 ROC 和 AUC 時常見的誤區和需要注意的事項,提醒大俠避免在模型評估中常見的錯誤,並提供了結合多種評估指標綜合分析模型效能的方法。
關鍵概念回顧
- ROC 曲線:評估模型在不同閾值下的效能,透過展示 TPR 和 FPR 的關係來幫助理解模型的分類能力。
- AUC:量化 ROC 曲線下的面積,用於綜合評價模型的整體表現,AUC 值越大表示模型效能越好。
- 混淆矩陣:展示模型的分類結果,透過四個基本要素(TP、FP、TN、FN)來評估模型效能。
- PR 曲線:展示查準率和召回率之間的關係,特別適用於類別不平衡的資料集。
- 校準曲線:評估模型的機率輸出是否與實際機率一致,確保模型的機率預測是準確的。
透過這篇文章的講解,希望大俠們能夠更加全面地理解和應用 ROC 曲線和 AUC,在實際專案中靈活運用這些知識,提升模型評估的準確性和可靠性。
- 科研為國分憂,創新與民造福 -
日更時間緊任務急,難免有疏漏之處,還請大俠海涵 內容僅供學習交流之用,部分素材來自網路,侵聯刪
[ 演算法金,碎碎念 ]
全網同名,日更萬日,讓更多人享受智慧樂趣
如果覺得內容有價值,煩請大俠多多 分享、在看、點贊,助力演算法金又猛又持久、很黃很 BL 的日更下去;
同時邀請大俠 關注、星標 演算法金,圍觀日更萬日,助你功力大增、笑傲江湖