代價敏感學習初探 - 有偏損失函數設計


1. 代價敏感學習簡介

0x1:如何將業務場景中對FP和FN損失的不同接受程度,調整我們的損失函數

1. 什么場景下需要代碼敏感學習

在很多真實業務場景中,包括筆者所在的網絡安全領域,誤報造成的損失常常比漏報來的要大,原因很簡單,如果一個IDS系統每天都在產生大量虛警,那么對事件響應處理人員的壓力就會非常大,時間久了,大家對IDS的信任度就會下降,同時真實的有效告警也可能被淹沒在海量的虛警中,反而導致更多和更嚴重的漏報。

但另一方面,可能有人會質疑說漏報的影響不是更惡劣嗎?難道不應該秉着”寧可錯殺一千,不可放過一個可疑“的方針嗎?

根據筆者目前的從業經驗來看,沒有必要這樣。一個好的做法是構建多層次的縱深檢測體系,大白話就是在一個KILLCHAIN的每一個環節都有針對性地部署一個IDS,同時追求每個IDS的精確度,對於單個IDS來說,盡量少誤報,對於整體系統來說,所有IDS綜合起來構成了一個縱深體系,攻擊者想要穿透這個體系而不引發任何的告警,就需要非常高超的技巧和小心翼翼的動作,而這有時候也反過來限制了攻擊者所能做的動作,例如內網掃描這件事。

說完了代碼敏感學習的應用場景,接下來的問題肯定是:代價敏感函數是什么?簡單的回答是:代價敏感學習是在原始標准代價損失函數的基礎上,增加了一些約束和權重條件,使得最終代價的數值計算朝向一個特定的方向偏置(bias),而這個偏置就是具體業務場景更關注的部分

我們先來看一下常規的代價函數是如何計算的。

2. 常規損失函數的數值計算

一般來說,機器學習領域的檢測分類算法所關注的僅僅是如何得到最高的正確率(acc),以2-class分類為例,我們可以使用一個二維矩陣來描述分類算法的預測結果,如下圖所示:

表中的列表示實際數據所屬類別,行表示分類算法的預測類別

不管使用了損失函數是何種形式,形式上,算法的預測錯誤的即是 FPFN 兩部分所表示,即:Loss = Loss(FP)+ Loss(FN)

從損失函數的通用數學公式角度來看,損失函數的求導優化對 FP 和 FN 是沒有任何偏置的。分類算法所關心的是如何使得 FP+FN 的值盡可能的小,從而獲得較高的分類准確率。對於 FP、FN 兩部分各自在錯誤實例中所占的比重,傳統損失函數並沒有加以任何的考慮和限制。

換句話說,傳統損失函數實際上是建立在下述假設的基礎之上的:

在所有情況下,分類算法做出 FN 判斷和做出 FP 判斷對於實際結果的影響因子是完全相同的。所以我們可以不對兩種誤判所占的比例加以約束

3. 業務場景中的損失函數計算

然而在現實世界中,這一假設往往是並不成立的,在實際的業務場景中,FN 和 FN 所帶來的實際損失往往是不同的。一個被廣為接受的上述假設的反例就是銀行借貸問題。

  • 從機器學習算法的角度考慮,算法的分類結果應該使得錯誤分類率降到最低;

  • 而在實際應用中,算法的分類結果應該保證分類結果給銀行造成的損失較小;

在實際情況中,銀行做出 FP 判斷(即沒有將貸款貸給符合條件的申請人),所造成的損失要遠小於其做出 FN 判斷(即將貸款貸給不符合條件的申請人所造成的損失的)

如果我們用下圖來描述銀行做出不同決定所造成的不同的代價的的cost matrix:

分類算法導致的實際損失等於:

Loss-real = FP * C01 + FN * C10

假設現在有兩個分類已訓練好的算法 A 和 B,對於 10 個貸款申請人進行分類。

我們令:

loss(FN)c10 = 10;
loss(FP)c01 = 1

若 A/B 算法的分類結果為下圖

從數值計算的角度,A 算法的分類正確性要優於 B 算法:Acc(A)= 80% > Acc(B)= 60%

但是從實際業務場景角度,銀行實際損失,A 算法的性能卻不如 B 算法:Loss(A)= 20 > Loss(B)= 4

這就是 cost-sensitive 分類算法所關注和研究的問題。

0x2:代價敏感學習公式

利用 cost matrix,我們可以將 cost-sensitive 分類問題轉化一個最優化問題,對於二分類分類算法來說只有2種判斷結果,所以優化目標為讓下式 L(x, i)達到最小值:

  • 其中 x 是一個實例;

  • (x, i)表示將其分為 i 類;

  • P(j | x) 表示在算法 A 中獲得的 x 屬於類別 j 的后驗概率,這個概率越小,反之 P(i | x) 就越大,這就是求對偶問題的反面;
  • c(i,j) 表示算法 A 將類別 i 的樣本錯判為類別 j 的實際損失(real-cost)

上述公式中,因為損失權重偏置因子c(i,j)的加入,使得我們的目標使得模型不再單純關注如何獲得 P(j|x)的最大值,而是要綜合考慮預測結果P(j | x)以及不同預測結果造成的損失c(i,j)。這兩個因子互相牽制。

1. Cost-sensitive中cost的定義與表示

通常情況下,我們使用 cost matrix 描述待分類數據集上的 cost 信息。Cost matrix C 是一個N × N的矩陣,其中 N 代表待分類數據集中的類別的數量。

C 中的條目 c(i, j)表示分類算法將實際屬於 j 類得到實例分為 i 類所造成的 cost。當 i = j 時代表分類算法正確預測了實例的類別,而i ≠ j的條目對應於不正確的分類結果。

在對 c(i, j)進行賦值的過程中,一般會遵循合理性原則:

  • 即錯誤分類的造成的 cost 肯定要大於正確分類造成的 cost;

  • cost matrix 中的 c(i, j) = 0 , when i = j,而對於其他錯誤的分類結果對應的條目 c(i, j), 我們賦其值為正數,用於表示其代價;

  • 而具體FN和FP如何賦值,取決於具體業務場景。例如如果我們認為誤報的損失大於漏報的損失,則賦值:cFN > cFP;

2. Cost-sensitive損失權重因子對損失函數的影響

從宏觀角度來看,代價損失權重因子c(i, j)可以理解為一種先驗知識。加入損失權重因子c(i, j)后,目標函數L(x,i)從最大似然估計轉變為了最大后驗估計。

筆者認為,cost sensitive的本質是“對不同的后驗預測結果,的條件概率 P(y|x) 賦予不同的懲罰因子”。

在 2-class 分類中,cost-sensitive 分類算法將實例 x 分為 1 類的條件是當且僅當將 x 分為 1 類所造成的預期 cost,不大於將 x 分為 0 類的損失。即

當式子取等號時,這就是所謂的分類器最優決策面(auc曲線本身)。可以看到,cost matrix的不同取值,影響了這個分類器最優決策面的位置,具體如何分析這種影響,我們文章的后面會繼續深入討論。

0x3:代價敏感損失的泛化討論

筆者希望和大家一起更深入思考一下,代價敏感損失的本質是什么。

雖然大量的paper上都提出了cost-sensitive是對不同的predict result給予不同的損失因子,這是離散的范疇。但是筆者認為這個概念可以繼續延展到連續無限的范疇,即對對數幾率回歸損失(sigmoid)這種損失函數也同樣起作用,sigmoid本質上也體現了cost sensitive的思想。

一個標准的sigmoid函數如下:

sigmoid函數的輸出代表了對發生幾率的預測,目標y為 {1,0},即發生於不發生,而sigmoid的輸出介於【0,1】之間。

從函數曲線上可以很容易看出:

  • 對於靠近【0,1】兩側的預測值,預測值和實際值的差值是比位於中間概率的差值要小的,因此這個區域中的1階導數相對就較低,這進而導致了例如GD算法的最終損失較低;

  • 而位於【0,1】中間位置的地方,1階導數相對較高,進而導致最終損失較高;

通過這種函數特性,sigmoid函數會“驅使”模型將預測結果向靠近 0 或者靠近 1 的方向前進,或者說sigmoid函數不喜歡模糊地帶,而偏愛(bias)確定性的結果。

0x4:Cost-Sensitive的幾何意義

如果我們畫出ROC曲線,橫軸和縱軸分別是 acc 和 recall,可以現象,曲線是一個形如下圖的曲線:

損失函數的極值點就是最終的決策分界面ROC曲線的“切線點”(圖中的綠點)。

我們可以做一個直觀的想象:cost() 函數起到的作用是“拉伸”原始的ROC曲線,使其向acc或者recall的方向拉伸,拉伸的結果會導致超分界面“提早”和 acc 或者 recall 方面相切。

  • 對誤報的懲罰加大:cost()對FN的因子比例增大,則使roc曲線朝上圖中 true positive rate 方向拉伸,即向上,則相切點會更靠下,最終的效果是獲得更低的 true positive rate;

  • 對漏報的懲罰加大:cost()對FP的因子比例增大,則使roc曲線朝上圖中 false positive rate 方向拉伸,即向左,則相切點會更靠右,最終的效果是獲得更低的 false positive rate;

以上的函數幾何視角,啟發我們一點:

cost-sensitive Loss Function 的作用本質上是通過“拉伸”損失函數的函數形式,進而影響模型的最優決策面。對 acc 和 recall 的不同權重因子,最終影響了 roc 曲線中向 acc 和 recall 方向的偏離程度

當然,cost-sensitive只是影響了模型最優決策面的位置,最優決策面並不是最終的決策函數。

如果將auc函數看成是【x,y】坐標系的話,不同的x,y取值代表了最終決策不同的偏向,例如我們取x=0.1,即追求低誤報,則相對的,y值肯定也低,即召回也低了。如果我們稍微放低一些對低誤報的追求,則召回也能對應提高。在實際的tensorflow開發中,這通過對最終模型預測的p的threshold來實現。

那cost-sensitive在這里又扮演了什么角色呢?

簡單來說可以這么理解,在相同的threshold前提下,誤報敏感損失函數會使得模型獲得更低的誤報,漏報敏感損失函數會使得模型會的更低的漏報。

但是要始終牢記的是:最終的模型效果是兩部分組成的,AUC函數的形式+認為設定的threshold決策策略

0x5:實現cost sensitive思想的不同方式

解決 cost-sensitive 分類問題的核心在於解決的優化問題,即如何使得分類算法的結果能夠獲得有傾向性的L值。 

目前,在如何獲得有傾向性的分類算法這一問題上,目前有幾種比較主流的方法:

1. Train set sample rescaling

通過有意調整,將訓練數據集的正負例呈現不同數量比,以提高分類算法對於某些分類結果的敏感性。

例如如果想獲得更高的acc,更低的誤報,我們在訓練集中,調整反例的數量是正例的數倍。相關的討論,可以參閱另一篇blog

2. Class membership probability - cost matrix reweighted

通過修改不同分類在算法中的 class membership probability,以獲得具有一定數據傾向性的分類算法。這種算法被稱為reweighted。這種方法也是本文主要討論的。

0x6:代價敏感函數在不同機器學習算法中的應用

目前,分類決策樹、神經網絡、支持向量機(SVM)、boosting等常用學習算法都有其對應的代價敏感擴展算法。

各個方法在具體形式上各不相同,但其核心思想是一致的,這里以AdaCost為例舉例說明。

AdaCost 算法由 AdaBoost 分類算法改進而來,也是一種通過 reweighted 方式獲取 cost-sensitive 分類算法的方法。

AdaCost 的基本思想是使用若干個較弱的分類器以投票方式集成出一個分類器,各個分類器的權值由評價函數調整確定。在 AdaBoost 算法中,評價函數僅和算法的分類准確性相關。W.Fan 等人在 AdaBoost 的評價函數中引入了 cost 的元素,使得分類算法能夠有效降低分類結果的 cost 值。

具體來說 AdaCost 算法添加了一個評價分類結果的 cost 性能的函數β:y × X × c → ℝ+,使得訓練出來的弱分類器的權值集合能夠符合 cost-sensitive 的要求。下面給出其偽碼:

Relevant Link:   

http://202.119.32.195/cache/4/03/lamda.nju.edu.cn/d2623fb33f624a2a05033bb5d0e23d45/qiny.pdf
http://lamda.nju.edu.cn/huangsj/dm11/files/qiny.pdf 
https://homes.cs.washington.edu/~pedrod/papers/kdd99.pdf 
https://cling.csd.uwo.ca/papers/cost_sensitive.pdf 

 

2. 在貝葉斯Bayes最優決策理論下,代價敏感損失函數設計准則

上個章節中,我們談到了一個詞,”分類器最優決策面“,這個東西是什么呢?這個章節我們來詳細討論。

0x1:貝葉斯最優決策理論

1. 貝葉斯最優分類(Bayes optimal classification)

對於二分類問題, 定義2級代價矩陣(cost matrix):

,其中是將b類樣本預測為a類樣本的分類代價。

Bayes決策理論,最優決策的目標是最小化期望分類代價(最大后驗概率估計),即給定樣本x,若下式成立,則預測其類別為正;否則,預測其類別為負。

,其中 p(x)為后驗概率,p(x) = P(y = +1|x),1 − p(x) = P(y = −1|x)。

上式的意思是:當,Loss(正例判對+負例誤報為正例)<= Loss(正例漏報,負例判對)時,模型預測最終結果為正。

將上式移項后可重寫為:

其中:

  • :表示正樣本的分類代價;

  • :表示負樣本的分類代價;

因此貝葉斯最優分類器輸出的分類器函數為(這里不考慮人為設定的threshold決策函數):

因此,Bayes分類器也可寫作:

當正負類別分類代價相等時,即c+ = c−,Bayes分類器退化為普通的無偏損失函數;而當c+和c-存在不對稱偏置時,Bayes分類器也成為有偏損失函數。

2. 貝葉斯決策錯誤理論上界

cost matrix本質上是改變了Bayes分類器的損失理論上界。

0x2:代價敏感損失設計准則(Design criterions of cost-sensitive loss)

1. 准則一

代價敏感損失函數需滿足Bayes一致性,即單調性

新設計的代價敏感損失函數滿足下述特性:

2. 准則二

對應的條件代價敏感風險在Bayes分類邊界(分類器最優決策面)處取得最大值。

Bayes分類器的期望分類代價為:

在分類邊界處,將樣本x判為正、負類別的分類代價相等並達到最大值,此時最難預測樣本類別。 

Relevant Link:   

https://www.cnblogs.com/Determined22/p/6347778.html
http://jcta.cnjournals.com/cta_cn/ch/reader/view_abstract.aspx?doi=10.7641/CTA.2015.40519 
https://www.bilibili.com/read/cv112928/
https://www.zhihu.com/question/27670909
《統計決策論及貝葉斯分析》- J.O.伯傑

  

3. 代價敏感損失函數的函數特性分析

這個章節,我們來真正進入代價敏感函數的內部原理,探究一下cost matrix是如何影響原始損失函數的形態,進而影響原始損失函數的性質的。

0x1:原始無偏損失函數函數性質

我們前面說過,當正負類別分類代價相等時,即c+ = c−,Bayes分類器退化為普通的無偏損失函數;而當c+和c-存在不對稱偏置時,Bayes分類器也成為有偏損失函數。

所以這里先來看下我們熟悉的原始無偏損失函數的函數性質。

具體探討以下損失函數:平方損失、指數損失、對數損失、SVM損失。這幾種損失函數均可表示為間隔yF(x)的函數, 即,如下圖所示:

下標給出了各個損失函數對應最優決策函數及其條件風險

下圖給出了各個損失函數的最優解和最優解處的條件風險:

可以看到,在無偏損失情況下,與貝葉斯分類器等價,最優解處的條件風險與最小分類誤差一致,即在p(x) = 1/2 處取得最大值。

這和我們的認識是一致的,怎么理解呢?簡單來說可以這么理解。

如果我們使用邏輯斯蒂回歸訓練一個二分類器,那么我們可以設定預測的閾值p為0.5,當>=0.5時,預測結果為正例,當<0.5時預測結果為負例。這是最優的閾值,任何偏離0.5的閾值p都會增加損失:

  • 決策閾值向0.5左偏:整體損失的增加主要來自誤報增加。

  • 決策閾值向0.5右偏:整體損失的增加主要來自漏報增加,當然在某些情況下,漏報可能是我們可以接受的,因為這換取了一定的誤報降低。

討論完了原始的無偏損失函數,接下來我們要開始討論有偏的代價損失函數,現有算法有以下兩類常用分類代價引入策略:

1) 分類代價在損失函數外:cyL(yF(x));
2) 分類代價在損 函數內:L(ycyF(x));

0x2:分類代價在損失函數外(Classification cost outside of loss function)

這種類型的代價敏感損失將分類代價與原始損失相乘。

下表給出了各個代價敏感損失此時的最優決策和最優決策處的條件代價敏感風險

我們取c+ = 1.5,c− = 0.5這種偏置組合,此時,Bayes分類器為

繪制各個損失函數的最優解和最優解處的條件風險:

可以看出,4種代價敏感損失均滿足准則1,即最優分類器為Bayes分類器。

另一方面,除代價敏感SVM損失外,其余損失均不滿足准則2, 最優解處的條件代價敏感風險沒有在Bayes分類邊界處取得最大值,而是有不同程度的偏移。

0x3:分類代價在損失函數內(Classification cost inside of loss function)

這種類型的代價敏感損失將分類代價引入損失函數內部,將其與判決函數F相乘。

下表列出了各個代價敏感損失此時的最優決策和最優決策處的條件代價敏感風險

我們取c+ = 1.5,c− = 0.5這種偏置組合,繪制各個損失函數的最優解和最優解處的條件風險:

可看出,4種代價敏感損失均滿足准則1和准則2,即最優分類器為Bayes分類器,最優解處的條件代價敏感風險在Bayes分類邊界處取得最大值。

這種損失偏置條件下,模型的漏報會傾向於低漏報。 

綜上,雖然這4種損失函數代價敏感化之后並未都嚴格滿足准則1/2,但是總體上,cost sensitive實際上扭曲了原始損失函數的函數曲線,使其發生了偏置。

Relevant Link:    

http://jcta.cnjournals.com/cta_cn/ch/reader/create_pdf.aspx?file_no=CCTA140519&flag=1&journal_id=cta_cn&year_id=2015

 

4. 在Keras中開發適合業務場景的代價敏感函數 

在具體工程項目中,因為TensorFlow/Keras並沒提供原生的代價敏感函數,我們可以通過繼承和重寫原有的損失函數的方式,對原始的經典損失函數進行改造(函數內/函數外)

# 方式一
def vae_loss(x, x_decoded_mean):
    xent_loss = objectives.binary_crossentropy(x, x_decoded_mean)
    kl_loss = - 0.5 * K.mean(1 + z_log_sigma - K.square(z_mean) - K.exp(z_log_sigma), axis=-1)
    return xent_loss + kl_loss
 
vae.compile(optimizer='rmsprop', loss=vae_loss)

Relevant Link:    

https://stackoverflow.com/questions/45961428/make-a-custom-loss-function-in-keras
https://blog.csdn.net/A_a_ron/article/details/79050204
https://blog.csdn.net/xiaojiajia007/article/details/73274669

 


免責聲明!

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



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