機器學習基礎ROC曲線理解


機器學習基礎ROC曲線理解

一、總結

一句話總結:

ROC曲線的全稱是Receiver Operating Characteristic Curve,中文名字叫“受試者工作特征曲線”,顧名思義,就是評估物品性能。

 

1、ROC曲線起源?

a、ROC曲線起源於第二次世界大戰時期雷達兵對雷達的信號判斷。當時每一個雷達兵的任務就是去解析雷達的信號,但是當時的雷達技術還沒有那么先進,存在很多噪聲(比如一只大鳥飛過),所以每當有信號出現在雷達屏幕上,雷達兵就需要對其進行破譯。
b、有的雷達兵比較謹慎,凡是有信號過來,他都會傾向於解析成是敵軍轟炸機,有的雷達兵又比較神經大條,會傾向於解析成是飛鳥。
c、這個時候,雷達兵的上司就很頭大了,他急需一套評估指標來幫助他匯總每一個雷達兵的預測信息,以及來評估這台雷達的可靠性(如果不論哪一類雷達兵都能准確預測,那這台雷達就很NB~讀者可思考其緣由)。
d、於是,最早的ROC曲線分析方法就誕生了,用來作為評估雷達可靠性的指標~在那之后,ROC曲線就被廣泛運用於醫學以及機器學習領域~

 

 

二、機器學習基礎ROC曲線理解

轉自或參考:機器學習基礎(1)- ROC曲線理解
https://www.jianshu.com/p/2ca96fce7e81

 

本文用於理解ROC曲線的定義,繪制過程及其應用實現,主要用於自我溫習回顧基礎

基本目錄如下:

  1. 什么是ROC曲線?
    1.1 ROC曲線的歷史
    1.2 ROC曲線的定義
    1.3 ROC曲線的應用場景

  2. 如何繪制ROC曲線?
    2.1 ROC曲線的繪制原理
    2.2 ROC曲線繪制的Python實現

------------------第一菇 - 什么是ROC曲線------------------

1.1 ROC曲線的歷史

自從讀了吳軍老師的《數學之美》,我就想明白了一件事情,如果想要講明白一件事情,一定要把他的歷史淵源都講明白,這樣我們才能對其理解透徹,而不是單純學到會用就好~試想,有多少人在讀這篇文章之前,會想到ROC曲線在軍事上的運用呢?接下來,我就當一回搬運工,把ROC曲線的誕生淵源都捋一捋~

經過一番網上調查,ROC曲線起源於第二次世界大戰時期雷達兵對雷達的信號判斷【1】。當時每一個雷達兵的任務就是去解析雷達的信號,但是當時的雷達技術還沒有那么先進,存在很多噪聲(比如一只大鳥飛過),所以每當有信號出現在雷達屏幕上,雷達兵就需要對其進行破譯。有的雷達兵比較謹慎,凡是有信號過來,他都會傾向於解析成是敵軍轟炸機,有的雷達兵又比較神經大條,會傾向於解析成是飛鳥。這個時候,雷達兵的上司就很頭大了,他急需一套評估指標來幫助他匯總每一個雷達兵的預測信息,以及來評估這台雷達的可靠性(如果不論哪一類雷達兵都能准確預測,那這台雷達就很NB~讀者可思考其緣由)。於是,最早的ROC曲線分析方法就誕生了,用來作為評估雷達可靠性的指標~在那之后,ROC曲線就被廣泛運用於醫學以及機器學習領域~

1.2 ROC曲線的定義

ROC的全稱是Receiver Operating Characteristic Curve,中文名字叫“受試者工作特征曲線”,顧名思義,其主要的分析方法就是畫這條特征曲線。這里在網上找了一個比較好的圖樣示例如下,

ROC曲線示例

該曲線的橫坐標為假陽性率(False Positive Rate, FPR),N是真實負樣本的個數,
FP是N個負樣本中被分類器預測為正樣本的個數。

縱坐標為真陽性率(True Positive Rate, TPR),
TPR=\frac{TP}{P}P是真實正樣本的個數,
TP是P個正樣本中被分類器預測為正樣本的個數。

舉一個簡單的例子方便大家的理解,還是剛才雷達的例子。假設現在有10個雷達信號警報,其中8個是真的轟炸機(P)來了,2個是大鳥(N)飛過,經過某分析員解析雷達的信號,判斷出9個信號是轟炸機,剩下1個是大鳥,其中被判定為轟炸機的信號中,有1個其實是大鳥的信號(FP=1),而剩下8個確實是轟炸機信號(TP=8)。因此可以計算出FPR為0.5,TPR為1,而(0.5,1)就對應ROC曲線上一點。

說到這里,想必大家已經明白這倆個指標的計算方法,再往深挖一點,可以思考一下這倆個指標背后的原理。還是雷達的例子,敏銳的雷達系統我們肯定希望它能把所有的敵方轟炸機來襲都感知到並預測出來,即TPR越高越好,但我們又不希望它把大鳥的飛過也當成轟炸機來預警,即FRP越低越好。因此,大家可以發現,這倆個坐標值其實是有相互制約的一個概念在里面。

當繪制完成曲線后,就會對模型有一個定性的分析,如果要對模型進行量化的分析,此時需要引入一個新的概念,就是AUC(Area under roc Curve)面積,這個概念其實很簡單,就是指ROC曲線下的面積大小,而計算AUC值只需要沿着ROC橫軸做積分就可以了。真實場景中ROC曲線一般都會在y=x這條直線的上方,所以AUC的取值一般在0.5~1之間。AUC的值越大,說明該模型的性能越好。

1.3 ROC曲線的應用場景

ROC曲線的應用場景有很多,根據上述的定義,其最直觀的應用就是能反映模型在選取不同閾值的時候其敏感性(sensitivity, FPR)和其精確性(specificity, TPR)的趨勢走向【2】。不過,相比於其他的P-R曲線(精確度和召回率),ROC曲線有一個巨大的優勢就是,當正負樣本的分布發生變化時,其形狀能夠基本保持不變,而P-R曲線的形狀一般會發生劇烈的變化,因此該評估指標能降低不同測試集帶來的干擾,更加客觀的衡量模型本身的性能。要解釋清楚這個問題的話,大家還是先回顧一下混淆矩陣。

混淆矩陣

其中,精確率P的計算公式為,

召回率R的計算公式為,

此時,若將負樣本的數量增加,擴大個10倍,可以預見FP,TN都會增加,必然會影響到P,R。但ROC曲線的倆個值,FPR只考慮第二行,N若增大10倍,則FP,TN也會成比例增加,並不影響其值,TPR更是只考慮第一行,不會受到影響。這里在網上盜個圖【3】,方便大家理解哈~
ROC曲線和P-R曲線對比圖

其中第一行ab均為原數據的圖,左邊為ROC曲線,右邊為P-R曲線。第二行cd為負樣本增大10倍后倆個曲線的圖。可以看出,ROC曲線基本沒有變化,但P-R曲線確劇烈震盪。因此,在面對正負樣本數量不均衡的場景下,ROC曲線(AUC的值)會是一個更加穩定能反映模型好壞的指標。

------------------第二菇 - 如何繪制ROC曲線------------------

2.1 ROC曲線的繪制原理

如果大家對二值分類模型熟悉的話,都會知道其輸出一般都是預測樣本為正例的概率,而事實上,ROC曲線正是通過不斷移動分類器的“閾值”來生成曲線上的一組關鍵點的。可能這樣講有點抽象,還是舉剛才雷達兵的例子。每一個雷達兵用的都是同一台雷達返回的結果,但是每一個雷達兵內心對其屬於敵軍轟炸機的判斷是不一樣的,可能1號兵解析后認為結果大於0.9,就是轟炸機,2號兵解析后認為結果大於0.85,就是轟炸機,依次類推,每一個雷達兵內心都有自己的一個判斷標准(也即對應分類器的不同“閾值”),這樣針對每一個雷達兵,都能計算出一個ROC曲線上的關鍵點(一組FPR,TPR值),把大家的點連起來,也就是最早的ROC曲線了。

為方便大家進一步理解,本菇也在網上找到了一個示例跟大家一起分享【4】。下圖是一個二分模型真實的輸出結果,一共有20個樣本,輸出的概率就是模型判定其為正例的概率,第二列是樣本的真實標簽。


二值分類模型輸出結果示例

現在我們指定一個閾值為0.9,那么只有第一個樣本(0.9)會被歸類為正例,而其他所有樣本都會被歸為負例,因此,對於0.9這個閾值,我們可以計算出FPR為0,TPR為0.1(因為總共10個正樣本,預測正確的個數為1),那么我們就知道曲線上必有一個點為(0, 0.1)。依次選擇不同的閾值(或稱為“截斷點”),畫出全部的關鍵點以后,再連接關鍵點即可最終得到ROC曲線如下圖所示。

ROC曲線示例圖

其實還有一種更直觀的繪制ROC曲線的方法,這邊簡單提一下。就是把橫軸的刻度間隔設為\frac{1}{N},縱軸的刻度間隔設為\frac{1}{P},N,P分別為負樣本與正樣本數量。然后再根據模型的輸出結果降序排列,依次遍歷樣本,從0開始繪制ROC曲線,每遇到一個正樣本就沿縱軸方向繪制一個刻度間隔的曲線,每遇到一個負樣本就沿橫軸方向繪制一個刻度間隔的曲線,遍歷完所有樣本點以后,曲線也就繪制完成了。究其根本,其最大的好處便是不需要再去指定閾值尋求關鍵點了,每一個樣本的輸出概率都算是一個閾值了。當然,無論是工業界還是學術界的實現,都不可能手動去繪制,下面就來講一下如何用Python高效繪制ROC曲線。

2.2 ROC曲線繪制的Python實現

熟悉sklearn的讀者肯定都知道,幾乎所有評估模型的指標都來自sklearn庫下面的metrics,包括計算召回率,精確率等。ROC曲線的繪制也不例外,都得先計算出評估的指標,也就是從metrics里面去調用roc_curve, auc,然后再去繪制。

from sklearn.metrics import roc_curve, auc 

roc_curve和auc的官方說明教程示例如下【5】。

# 數據准備 >>> import numpy as np >>> from sklearn import metrics >>> y = np.array([1, 1, 2, 2]) >>> scores = np.array([0.1, 0.4, 0.35, 0.8]) # roc_curve的輸入為 # y: 樣本標簽 # scores: 模型對樣本屬於正例的概率輸出 # pos_label: 標記為正例的標簽,本例中標記為2的即為正例 >>> fpr, tpr, thresholds = metrics.roc_curve(y, scores, pos_label=2) # 假陽性率 >>> fpr array([ 0. , 0.5, 0.5, 1. ]) # 真陽性率 >>> tpr array([ 0.5, 0.5, 1. , 1. ]) # 閾值 >>> thresholds array([ 0.8 , 0.4 , 0.35, 0.1 ]) # auc的輸入為很簡單,就是fpr, tpr值 >>> auc = metrics.auc(fpr, tpr) >>> auc 0.75 

因此調用完roc_curve以后,我們就齊全了繪制ROC曲線的數據。接下來的事情就很簡單了,調用plt即可,還是用官方的代碼示例一步到底。

import matplotlib.pyplot as plt plt.figure() lw = 2 plt.plot(fpr, tpr, color='darkorange', lw=lw, label='ROC curve (area = %0.2f)' % auc) plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver operating characteristic example') plt.legend(loc="lower right") plt.show() 

最終生成的ROC曲線結果如下圖。


ROC曲線結果

至此,整一套ROC曲線的繪制就說明白了。

簡單總結一下本文,先是講述了ROC曲線的歷史淵源,引導讀者理解ROC曲線的各個基本概念,又與P-R曲線做了詳細的對比,讓讀者理解其應用場景,最后接地氣的輕微解讀了一番其繪制過程,並附上了代碼實現。希望大家讀完本文后對ROC曲線會有一個全新的認識。有說的不對的地方也請大家指出,多多交流,大家一起進步~😁

參考文獻:
【1】https://www.ncbi.nlm.nih.gov/books/NBK22319/
【2】https://stats.stackexchange.com/questions/28745/advantages-of-roc-curves
【3】https://blog.csdn.net/songyunli1111/article/details/82285266
【4】https://www.zhihu.com/question/22844912/answer/246037337
【5】http://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_curve.html#sklearn.metrics.roc_curve

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM