【譯】非平衡數據機器學習


這篇文章翻譯至http://www.svds.com/learning-imbalanced-classes/,作者簡潔明了地闡述了非平衡數據及解決這類問題的常用方法。其實一些朴素的方法我們自己也能想到,並且也實際使用過一些,比如重采樣、調整權值等。然而,我們並沒有去做一些歸納。感謝作者幫我們歸納了一些思想朴素但又實際有用的方法。

什么是非平衡數據?

如果你剛開始一門機器學習課程,可能大部分數據集都相當的簡單。此外,當你構建分類器時,樣本的類別是平衡的,這意味着每個類別有大致相同的樣本數。教師通常都采用清理過的數據集作為示例,以讓教學專注於具體的算法或技術而不是其他問題。通常,你看到的是如下圖所示的二維數據,圖中一個點代表一個樣本,不同的顏色代表不同的類別:

image

分類算法的目標是試圖學習一條分割線(分類器)來區分這兩類點。基於多種數學、統計或者幾何假設,有很多方法來達到這個目的。

image

但是當你面對真實的世界,你注意到的第一問題就是,沒有清理的數據存在許多噪聲且類別不平衡。真實數據的散點圖更像是這樣:

image

主要問題是類別的不平衡:紅色點的數量嚴重少於藍色的。

研究不平衡類通常認為不平衡意味着少數類只占比10~20%。實際上,一些數據集遠比這更不平衡。例如:

1. 每年大約有2%的信用卡賬戶被欺騙。(大多數欺詐檢測領域嚴重不平衡。)

2. 狀態醫療甄別通常在大量不存在此狀態的人口中檢測極少數有此狀態的人(比如美國的HIV攜帶者僅占0.4%)。

3. 磁盤驅動器故障每年約1%。

4. 網絡廣告的轉化率估計在10-3到10-6之間。

5. 工廠生產故障率通常約0.1%。

這些領域許多問題是不平衡的,我稱他們為海底撈針問題,機器學習分類器從大量負類(不感興趣的)中找到少數正類(感興趣,或故障)。

當你遇到這樣的問題,用標准算法去解決一定會很困難。傳統算法往往偏向於多數類,因為他們的損失函數在沒考慮數據分布的情況下優化如錯誤率等量。最壞的情況是,小類別樣本會被認為是大類別的異常值而被忽略。學習算法簡單的生成一個平凡分類器,將每個樣本都分類為大類別。

這種看似病態行為但事實上並不是。事實上,如果你的目標是最大化簡單精度(或者等價,最小化錯誤率),這是一個完全可以接受的解決方案。但是如果我們假設稀有類樣本對於分類更重要,那么我們就應更小心、更精細的處理這個問題。

如果你遇到這樣的問題,並想要解決他們的實用建議,繼續讀下去吧。

注意:這篇文章的目的是洞察和關於如何解決這類問題的實際建議。而不是一個教你逐行寫代碼的編碼教程。我用Jupyter Notebooks來實踐這些想法,但這篇文章將解釋一些基本思想和原則。

處理非平衡數據

非平衡數據學習在機器學習研究中已經活躍了20多年。它作為許多論文、研習班、特別會議和學位論文的主題(最近一項調查大約有220引用)。試用了大量的技術,得到了不同的結果和一些清晰的答案。數據科學家第一次遇到這類問題通常要問,數據非平衡我該怎么做?同樣的問題沒有確切的答案,一般化問題哪種機器學習算法最好?沒有確切的答案:看什么樣的數據。

這里有一個實用方法的粗糙大綱。大概排列如下:

什么都不做。有時你比較幸運什么都不用做。你可以在所謂的自然分布的數據上訓練,有時它並不需要任何修改。

通過某種方法使訓練集平衡:

對稀有類別過采樣

對大類別欠采樣

對稀有類別合成新數據

扔掉稀有類別樣本,轉換為一個異常檢測框架。

在算法層面,或之后:

調整類權值(誤分類cost)

調整決策閾值

修改現有算法讓其對稀有類更敏感

構建一個對不平衡數據表現良好的全新算法

題外話:評估注意事項

首先,快速瀏覽。在談論怎樣訓練一個針對不平衡數據的分類器之前,我們需要討論怎樣正確的評估它。這無論怎么強調都不為過。只有當你測量正確的指標,你才會取得進展。

1. 不要用精確度(或錯誤率)去評估你的分類器。有兩個嚴重的問題。第一,精確度簡單的以0.5為閾值來處理二分類,但當數據非平衡時這通常是錯的。第二,分類精確度是基於誤差的一個簡單計數,你應該知道得更多。你應該知道哪些類、在哪兒被混淆。如果你不明白這些點,閱讀The Basics of Classifier Evaluation, Part 2可能會有用。你可以用一個ROC曲線,或者一個PR曲線來可視化你的分類器性能。

image

圖 1 ROC曲線

image

圖 2 PR曲線

2. 不要用score和predict從分類器獲取硬分類(標簽),而應該用proba和predict_proba獲取概率估計。

3. 當你獲得概率估計后,不要盲目的以0.5為閾值來划分類別。觀察性能曲線,來確定將要采樣的閾值。早期的論文有許多錯誤發生就是因為研究人員簡單的以0.5截斷。

4. 不管你訓練什么,總是在自然分布上測試。見

sklearn.cross_validation.StratifiedKFold

5. 你可能不需要概率估計來分類,但是當你需要時,使用校准。見

sklearn.calibration.CalibratedClassifierCV

前面第一幅二維圖比單個數字信息更大,但當你需要單個數字指標,其中一個比精確度更可取:

1. The Area Under the ROC curve (AUC)

2. F1 Score

3. Cohen’s Kappa

過采樣和欠采樣

最簡單的方法需要處理步驟變化不大,只包括簡單的調整樣本集直到它們平衡。過采樣通過隨機重復少類別的樣本來增加它的數量。欠采樣隨機對多類別樣本降采樣。一些數據科學家(天真的)認為過采樣更優越,因為它獲得更多的數據,而欠采樣扔掉了。但是記住,復制數據不是沒有效果—重復的數據使變量具有更低的變化。積極的結果是重復了誤差的數量:如果一個分類器使原來假陰的少類別數據再重復5次,那么它將在新數據集上計算6次誤差。相反,欠采樣可以使獨立變量看起來具有更高的方差。

因此,機器學習文獻展示了自然分布下過采樣和欠采樣混合的結果。

image

大多數機器學習包可以執行簡單的采樣調整。R包unbalanced針對非平衡數據集實現了一系列的采樣方法。scikit-learn.cross_validation包含了基本的采樣算法。

Wallace等的貝葉斯參數

可能最好的理論依據和實踐建議來至於論文《Class Imbalance, Redux》,作者是Wallace, Small, Brodley and Trikalinos4。他們贊成欠采樣。他們以數學的切底的理論為依據,但在這里我只能介紹一個他們用到的例子來表達他們的觀點。

他們認為,兩個類別必須是在一些解釋變量分布的尾部可分的。假設你有兩個類別用一個因變量,x,每個類是一個標准差為1的高斯分布。類別1的均值是1,類別2的均值是2。我們任意的假定類別2為多類別。他們應該是這樣:

image

給定一個x值,你會用什么閾值來確定它來自哪個類?可以清楚的知道兩者之間的最佳分割線是它們的中點,x=1.5,顯示為垂直的線:如果一個新的樣本x落在1.5左邊,它可能是類別1,相反是類別2。當從樣本中學習時,我們希望判別截至1.5是我們會得到的,如果類平衡,這大概是我們應該得到的。X軸上的點顯示不同分布生成的樣本。

但我們類別1是少類別,所以假設其有10個樣本,類別2有50個樣本。很可能我們學習到一個平移過的分割線,如下:

image

我們可以通過下采樣多類別去匹配少類別使結果更好。問題是我們學習到的分割線將有很高的可變性(因為樣本更少),如下所示(10次樣本導致10條不同的豎線):

image

因此最終的步驟是利用bagging去聯合這些分類器。主要過程如下:

image

這個技術在Scikit-learn中沒有實現,但是文件blagging.py實現類一個BlaggingClassifier,即平衡引導樣本先驗聚合。

基於近鄰的方法

過采樣和欠采樣隨機選擇樣本來修正他們的比例。其他方法認真檢查樣本空間,並決定基於他們的近鄰做什么。例如,Tomek鏈接是對對立類的實例,它們是自己的最近鄰。換句話說,它們是對非常相似的對立實例。

image

Tomek算法查找這樣的對並刪掉其中多類別的實例。這個想法是凈化多類別與少類別之間的邊界,使少類別區域更明顯。上圖顯示了Tomek鏈接刪除的一個簡單例子。R包unbalanced實現了Tomek鏈接刪除,作為針對非平衡數據集的一個采樣技術。Scikit-learn沒有內建的模塊實現此方法,但有一些獨立的包(如,TomekLink)。

合成新的樣本:SMOTE及其衍生

另一個研究方向不涉及對樣本重采樣,而是合成新的樣本。這種方法最著名的例子是Chawla的SMOTE(Synthetic Minority Oversampling Technique)系統。這個想法是在現有樣本間插值來產生新的少類別樣本。過程基本如下。假設我們有一組多類別和少類別的樣本,如下:

image

SMOTE通常是成功的,並產生了許多變體,擴展,和適應不同概念的學習算法。SMOTE及其變體在R包和python包UnbalancedDataset中都有。

注意SMOTE的大量限制很重要。因為它通過在稀有樣本間插值來操作,它只能在可用樣本體內產生樣本,而不是外面。通常,SMOTE只能填充現有少類別樣本的凸包,但是不創造其新的外部區域。

調整類權重

許多機器學習工具包都有調整某類重要性的方法。例如,Scikit-learn有許多分類器可以設置一個可選的參數class_weight,使其高於1。這里有個直接從Scikit-learn文檔獲得的例子,顯示了增加10倍少類別權重的影響。黑色實線顯示默認設置的分割邊界(每個類別權重相等),虛線是將少類別參數class_weight設為10后的分割邊界。

image

正如你所看到的,少類別獲得更多重要性(他的誤差被認為比其他類更貴)和調整分割超平面來減少損失。

應該注意的是,修正類重要性通常只對類誤差代價有影響(假陰性,如果少數類是積極的)。它將相應地調整一個分界面來減少這些。當然,如果訓練集上的分類器沒有錯誤沒有調整可能發生錯誤,所以改變類權重可能沒有效果。

以后

這篇文章專注與以簡單易用的方法從非平衡數據中學習分類器。他們中大部分涉及修正數據之前或之后應用標准的學習算法。簡要提及其他一些方法是有價值的。

新算法

學習非平衡類別是機器學習正在進行的研究領域,每年都有新的算法提出來。在結束之前,我將提到一些最近算法的進步與前景。

2014年Goh和Rudin發表類一篇文章《 Box Drawings for Learning with Imbalanced Data》,介紹了兩種從具有稀有樣本的數據中學習的算法。這些算法試圖圍繞少類別樣本集群構建“盒子”。

image

他們的目標是開發一種簡潔明了的表示少數類的方法。他們的等式懲罰盒子數量和規則化項。

他們介紹了兩個算法,其中一個使用整數規划提供一個精確的但相當昂貴的解決方案。另一個使用快速聚類的方法來產生一個初始化盒子。實驗結果表明,兩種算法在大量的測試數據集上表現都很好。

我早期提出解決非平衡問題的一個方法是丟棄少類別樣本,把它作為一個單類問題(或異常檢測)。最近的一個異常檢測技術對於這個目的效果好得驚人。Liu,Ting和Zhou推出了一個稱為隔離森林的技術,試圖通過學習隨機森林識別異常數據,然后測量的平均數量決定分裂需要隔離每個特定的數據點。由此產生的數量可以用來計算每個數據點的異常分數,也可以解釋為例子屬於少數類的可能性。實際上,作者使用高度不平衡數據測試他們的系統,並得到很好的結果。后續論文由Bandaragoda, Ting, Albrecht, Liu and Wells提出了最近鄰集合作為一個類似的想法,能夠克服隔離森林的一些缺點。

購買或者產生更多的數據

最后需要注意一點,這篇博文焦距在非平衡類情況,假設你得到的是非平衡數據,並且只需要解決非平衡。在某些情況下,比如Kaggle比賽,給你一組固定的數據,你不能要求更多。

但是你可能面臨一個相關的困難的問題:你只是沒有足夠的稀有類的樣本。上面的技術都不可能工作,你該怎么做?

現實世界某些領域你可以購買或者構造稀有類樣本。這是機器學習正在進行的一個研究領域。如果稀有類數據僅僅需要可靠的人工標簽,通常的方法是采用眾包,比如Mechanical Turk。人工標簽的可靠性可能是一個問題,但是機器學習已經完成結合人工標簽增加可靠性。最后,Claudia Perlich在 All The Data and Still Not Enough 中舉例,怎樣利用替代變量或問題巧妙的解決數據稀有或不存在的問題,本質上使用代理或潛在的變量使看似不可能的問題變為可能。與此相關的是使用轉移學習策略去學習一個問題,並把結果轉移到另一個稀有數據的問題上,就像這里所描述的那樣。

評論和問題?

在這里,我試圖將我大多數實用知識提煉出來。我知道有很多不足,我會重視你的反饋。我漏掉什么重要的嗎?本博客歡迎任何評論和問題。

資源和進一步閱讀

1. 幾種Jupyter notebooks說明了非平衡學習的各方面。

◎采樣的高斯:Gaussians.ipynb

◎Wallance方法:blagging.py

ImbalancedClasses.ipynb

2. MATLAB代碼:http://web.mit.edu/rudin/www/code/BoxDrawingsCode.zip

3. R孤立森林:https://sourceforge.net/projects/iforest/


免責聲明!

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



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