1. 程式人生 > >系統學習機器學習之樣本不平衡問題處理

系統學習機器學習之樣本不平衡問題處理

原文連結:http://blog.csdn.net/heyongluoyao8/article/details/49408131

在分類中如何處理訓練集中不平衡問題

  在很多機器學習任務中,訓練集中可能會存在某個或某些類別下的樣本數遠大於另一些類別下的樣本數目。即類別不平衡,為了使得學習達到更好的效果,因此需要解決該類別不平衡問題。

Jason Brownlee 的回覆:

原文標題:8 Tactics to Combat Imbalanced Classes in Your Machine Learning Dataset
你在對一個類別不均衡的資料集進行分類時得到了90%的準確度(Accuracy)。當你進一步分析發現,資料集的90%的樣本是屬於同一個類,並且分類器將所有的樣本都分類為該類。在這種情況下,顯然該分類器是無效的。並且這種無效是由於訓練集中類別不均衡而導致的。
  首先舉幾個所收到的郵件中關於類別不均衡的例子:

  • 在一個二分類問題中,訓練集中class 1的樣本數比class 2的樣本數是60:1。使用邏輯迴歸進行分類,最後結果是其忽略了class 2,即其將所有的訓練樣本都分類為class 1。
  • 在分類任務的資料集中,有三個類別,分別為A,B,C。在訓練集中,A類的樣本佔70%,B類的樣本佔25%,C類的樣本佔5%。最後我的分類器對類A的樣本過擬合了,而對其它兩個類別的樣本欠擬合。

什麼是類別不均衡問題

類別資料不均衡是分類任務中一個典型的存在的問題。簡而言之,即資料集中,每個類別下的樣本數目相差很大。例如,在一個二分類問題中,共有100個樣本(100行資料,每一行資料為一個樣本的表徵),其中80個樣本屬於class 1,其餘的20個樣本屬於class 2,class 1:class2=80:20=4:1,這便屬於類別不均衡。當然,類別不均衡問同樣會發生在多分類任務中。它們的解決方法是一樣的。因此,為了便於討論與理解,我們從二分類任務入手進行講解。

類別不均衡問題是現實中很常見的問題

大部分分類任務中,各類別下的資料個數基本上不可能完全相等,但是一點點差異是不會產生任何影響與問題的。
  在現實中有很多類別不均衡問題,它是常見的,並且也是合理的,符合人們期望的。如,在欺詐交易識別中,屬於欺詐交易的應該是很少部分,即絕大部分交易是正常的,只有極少部分的交易屬於欺詐交易。這就是一個正常的類別不均衡問題。又如,在客戶流失的資料集中,絕大部分的客戶是會繼續享受其服務的(非流失物件),只有極少數部分的客戶不會再繼續享受其服務(流失物件)。一般而已,如果類別不平衡比例超過4:1,那麼其分類器會大大地因為資料不平衡性而無法滿足分類要求的。因此在構建分類模型之前,需要對分類不均衡性問題進行處理。
  在前面,我們使用準確度這個指標來評價分類質量,可以看出,在類別不均衡時,準確度這個評價指標並不能work。因為分類器將所有的樣本都分類到大類下面時,該指標值仍然會很高。即,該分類器偏向了大類這個類別的資料。

八大解決方法

  • 擴大資料集
    當遇到類別不均衡問題時,首先應該想到,是否可能再增加資料(一定要有小類樣本資料),更多的資料往往戰勝更好的演算法。因為機器學習是使用現有的資料多整個資料的分佈進行估計,因此更多的資料往往能夠得到更多的分佈資訊,以及更好分佈估計。即使再增加小類樣本資料時,又增加了大類樣本資料,也可以使用放棄一部分大類資料(即對大類資料進行欠取樣)來解決。
  • 嘗試其它評價指標
            從前面的分析可以看出,準確度這個評價指標在類別不均衡的分類任務中並不能work,甚至進行誤導(分類器不work,但是從這個指標來看,該分類器有著很好的評價指標得分)。因此在類別不均衡分類任務中,需要使用更有說服力的評價指標來對分類器進行評價。如何對不同的問題選擇有效的評價指標參見這裡
      上面的超連結中的文章,講述瞭如何對乳腺癌患者復發類別不均衡資料進行分類。在文中,推薦了幾個比傳統的準確度更有效的評價指標:

  • 混淆矩陣(Confusion Matrix):使用一個表格對分類器所預測的類別與其真實的類別的樣本統計,分別為:TP、FN、FP與TN。

  • 精確度(Precision)
  • 召回率(Recall)
  • F1得分(F1 Score):精確度與找召回率的加權平均。

特別是:

  • Kappa (Cohen kappa)
  • ROC曲線(ROC Curves):見Assessing and Comparing Classifier Performance with ROC Curves

  • 對資料集進行重取樣
     可以使用一些策略該減輕資料的不平衡程度。該策略便是取樣(sampling),主要有兩種取樣方法來降低資料的不平衡性。

  • 對小類的資料樣本進行取樣來增加小類的資料樣本個數,即過取樣(over-sampling ,取樣的個數大於該類樣本的個數)。

  • 對大類的資料樣本進行取樣來減少該類資料樣本的個數,即欠取樣(under-sampling,取樣的次數少於該類樣本的個素)。

            取樣演算法往往很容易實現,並且其執行速度快,並且效果也不錯。更詳細的內容參見這裡

一些經驗法則:

  • 考慮對大類下的樣本(超過1萬、十萬甚至更多)進行欠取樣,即刪除部分樣本;
  • 考慮對小類下的樣本(不足1為甚至更少)進行過取樣,即新增部分樣本的副本;
  • 考慮嘗試隨機取樣與非隨機取樣兩種取樣方法;
  • 考慮對各類別嘗試不同的取樣比例,比一定是1:1,有時候1:1反而不好,因為與現實情況相差甚遠;
  • 考慮同時使用過取樣與欠取樣。

  • 嘗試產生人工資料樣本
           一種簡單的人工樣本資料產生的方法便是,對該類下的所有樣本每個屬性特徵的取值空間中隨機選取一個組成新的樣本,即屬性值隨機取樣。你可以使用基於經驗對屬性值進行隨機取樣而構造新的人工樣本,或者使用類似樸素貝葉斯方法假設各屬性之間互相獨立進行取樣,這樣便可得到更多的資料,但是無法保證屬性之前的線性關係(如果本身是存在的)。
      有一個系統的構造人工資料樣本的方法SMOTE(Synthetic Minority Over-sampling Technique)。SMOTE是一種過取樣演算法,它構造新的小類樣本而不是產生小類中已有的樣本的副本,即該演算法構造的資料是新樣本,原資料集中不存在的。該基於距離度量選擇小類別下兩個或者更多的相似樣本,然後選擇其中一個樣本,並隨機選擇一定數量的鄰居樣本對選擇的那個樣本的一個屬性增加噪聲,每次處理一個屬性。這樣就構造了更多的新生資料。

  • 嘗試不同的分類演算法
           強烈建議不要對待每一個分類都使用自己喜歡而熟悉的分類演算法。應該使用不同的演算法對其進行比較,因為不同的演算法使用於不同的任務與資料。具體可以參見“Why you should be Spot-Checking Algorithms on your Machine Learning Problems”。
           決策樹往往在類別不均衡資料上表現不錯。它使用基於類變數的劃分規則去建立分類樹,因此可以強制地將不同類別的樣本分開。目前流行的決策樹演算法有:C4.5、C5.0、CART和Random Forest等。

  • 嘗試對模型進行懲罰

           你可以使用相同的分類演算法,但是使用一個不同的角度,比如你的分類任務是識別那些小類,那麼可以對分類器的小類樣本資料增加權值,降低大類樣本的權值(這種方法其實是產生了新的資料分佈,即產生了新的資料集,譯者注),從而使得分類器將重點集中在小類樣本身上。一個具體做法就是,在訓練分類器時,若分類器將小類樣本分錯時額外增加分類器一個小類樣本分錯代價,這個額外的代價可以使得分類器更加“關心”小類樣本。如penalized-SVM和penalized-LDA演算法。

         Weka中有一個懲罰模型的通用框架CostSensitiveClassifier,它能夠對任何分類器進行封裝,並且使用一個自定義的懲罰矩陣對分錯的樣本進行懲罰。
      如果你鎖定一個具體的演算法時,並且無法通過使用重取樣來解決不均衡性問題而得到較差的分類結果。這樣你便可以使用懲罰模型來解決不平衡性問題。但是,設定懲罰矩陣是一個複雜的事,因此你需要根據你的任務嘗試不同的懲罰矩陣,並選取一個較好的懲罰矩陣。

  • 嘗試一個新的角度理解問題
         我們可以從不同於分類的角度去解決資料不均衡性問題,我們可以把那些小類的樣本作為異常點(outliers),因此該問題便轉化為異常點檢測(anomaly detection)與變化趨勢檢測問題(change detection)。

         異常點檢測即是對那些罕見事件進行識別。如通過機器的部件的振動識別機器故障,又如通過系統呼叫序列識別惡意程式。這些事件相對於正常情況是很少見的。
    變化趨勢檢測類似於異常點檢測,不同在於其通過檢測不尋常的變化趨勢來識別。如通過觀察使用者模式或銀行交易來檢測使用者行為的不尋常改變。
      將小類樣本作為異常點這種思維的轉變,可以幫助考慮新的方法去分離或分類樣本。這兩種方法從不同的角度去思考,讓你嘗試新的方法去解決問題。

  • 嘗試創新
      仔細對你的問題進行分析與挖掘,是否可以將你的問題劃分成多個更小的問題,而這些小問題更容易解決。你可以從這篇文章In classification, how do you handle an unbalanced training set?中得到靈感。例如:

    • 將你的大類壓縮成小類;
    • 使用One Class分類器(將小類作為異常點);
    • 使用整合方式,訓練多個分類器,然後聯合這些分類器進行分類;
      ….

    這些想法只是冰山一角,你可以想到更多的有趣的和有創意的想法去解決問題。更多的想法參加Reddit的文章http://www.quora.com/In-classification-how-do-you-handle-an-unbalanced-training-set

選擇某一種方法並使用它

  你不必成為一個精通所有演算法的演算法奇才或者一個建立準確而可靠的處理資料不平衡的模型的統計學家,你只需要根據你的問題的實際情況從上述演算法或方法中去選擇一種或兩種方法去使用。希望上述的某些方法能夠解決你的問題。例如使用其它評價指標或重取樣演算法速度快並且有效。

總結

  記住,其實並不知道哪種方法最適合你的任務與資料,你可以使用一些啟發式規則或經驗去選擇某一個較優演算法。當然最好的方法測試每一種演算法,然後選擇最好的方法。最重要的是,從點滴開始做起,根據自己現有的知識,並不斷學習去一步步完善。

     這裡有一些我認為有價值的可供參考的相關資料,讓你進一步去認識與研究資料不平衡問題:

     相關書籍
    Imbalanced Learning: Foundations, Algorithms, and Applications
     相關論文
      Data Mining for Imbalanced Datasets: An Overview
      Learning from Imbalanced Data
      Addressing the Curse of Imbalanced Training Sets: One-Sided Selection (PDF)
      A Study of the Behavior of Several Methods for Balancing Machine Learning Training Data

Sergey Feldman的回答:

  • 設超大類中樣本的個數是極小類中樣本個數的L倍,那麼在隨機梯度下降(SGD,stochastic gradient descent)演算法中,每次遇到一個極小類中樣本進行訓練時,訓練L次。

  • 將大類中樣本劃分到L個聚類中,然後訓練L個分類器,每個分類器使用大類中的一個簇與所有的小類樣本進行訓練得到。最後對這L個分類器採取少數服從多數對未知類別資料進行分類,如果是連續值(預測),那麼採用平均值。

  • 設小類中有N個樣本。將大類聚類成N個簇,然後使用每個簇的中心組成大類中的N個樣本,加上小類中所有的樣本進行訓練。
  • 無論你使用前面的何種方法,都對某個或某些類進行了損害。為了不進行損害,那麼可以使用全部的訓練集採用多種分類方法分別建立分類器而得到多個分類器,採用投票的方式對未知類別的資料進行分類,如果是連續值(預測),那麼採用平均值。

  • 在最近的ICML論文中,表明增加資料量使得已知分佈的訓練集的誤差增加了,即破壞了原有訓練集的分佈,從而可以提高分類器的效能。這篇論文與類別不平衡問題不相關,因為它隱式地使用數學方式增加資料而使得資料集大小不變。但是,我認為破壞原有的分佈是有益的。

  • More details than you need: imho, the most interesting of the corrupting distributions is the blankout distribution, where you just zero out a random subset of features. Why is it interesting? Because you are helping your classifier be sturdier/hardier by giving it variations of your data that have essentially missing features. So it has to learn to classify correctly even in adverse conditions. 一個相關的想法是,在神經網路中,隨機選擇部分隱藏層單元來繼續訓練(即,隨機去掉一部分隱藏層單元,(zeroed-out))。具體見http://web.stanford.edu/~sidaw/cgi-bin/home/lib/exe/fetch.php?media=papers:fastdropout.pdf

Kripa Chettiar的回答:

  • 增加新資料,可以使用SMOTE或SMOTEBoost產生人造資料。
  • 將大類壓縮。壓縮比例需要具體情況具體分析,取決於你所擁有的資料。例如,A類中有30個樣本,B類中有4000個樣本,那麼你可以將B類壓縮成1000(進行取樣)。
  • 可以結合1與2
  • 對於那種極小類是異常點的分類任務,因此分類器需要學習到大類的決策分介面,即分類器是一個單個類分類器(One Class Classifier)。Weka中有相關的庫。

Dan Levin的回答:

一個很好的方法去處理非平衡資料問題,並且在理論上證明了。這個方法便是由Robert E. Schapire於1990年在Machine Learning提出的”The strength of weak learnability” ,該方法是一個boosting演算法,它遞迴地訓練三個弱學習器,然後將這三個弱學習器結合起形成一個強的學習器。我們可以使用這個演算法的第一步去解決資料不平衡問題。
  首先使用原始資料集訓練第一個學習器L1。
  然後使用50%在L1學習正確和50%學習錯誤的的那些樣本訓練得到學習器L2,即從L1中學習錯誤的樣本集與學習正確的樣本集中,迴圈一邊取樣一個。
  接著,使用L1與L2不一致的那些樣本去訓練得到學習器L3。
  最後,使用投票方式作為最後輸出。
  那麼如何使用該演算法來解決類別不平衡問題呢?
  假設是一個二分類問題,大部分的樣本都是true類。讓L1輸出始終為true。使用50%在L1分類正確的與50%分類錯誤的樣本訓練得到L2,即從L1中學習錯誤的樣本集與學習正確的樣本集中,迴圈一邊取樣一個。因此,L2的訓練樣本是平衡的。L使用L1與L2分類不一致的那些樣本訓練得到L3,即在L2中分類為false的那些樣本。最後,結合這三個分類器,採用投票的方式來決定分類結果,因此只有當L2與L3都分類為false時,最終結果才為false,否則true。
  自己已經在實踐中使用過很多次,並且效果都不錯。

Kaushik Kasi的回答:

  • 對小類中的樣本進行復制以增加該類中的樣本數,但是可能會增加bias。
  • 對小類中的樣本通過調整特徵值來人工生成樣本,而使得該類中樣本個數增多。如在影象中,對一幅影象進行扭曲得到另一幅影象,即改變了原影象的某些特徵值。但是該方法可能會產生現實中並存在的樣本。

Muktabh Mayank的回答:

這裡有一個類似SVM的方法來處理不平衡問題。具體參見這裡。