不平衡數據集的處理


一、不平衡數據集的定義

 所謂的不平衡數據集指的是數據集各個類別的樣本量極不均衡。以二分類問題為例,假設正類的樣本數量遠大於負類的樣本數量,通常情況下通常情況下把多數類樣本的比例接近100:1這種情況下的數據稱為不平衡數據。不平衡數據的學習即需要在分布不均勻的數據集中學習到有用的信息。

不平衡數據集的處理方法主要分為兩個方面:

1、從數據的角度出發,主要方法為采樣,分為欠采樣和過采樣以及對應的一些改進方法。

2、從算法的角度出發,考慮不同誤分類情況代價的差異性對算法進行優化,主要是基於代價敏感學習算法(Cost-Sensitive Learning),代表的算法有adacost;

另外可以將不平衡數據集的問題考慮為一分類(One Class Learning)或者異常檢測(Novelty Detection)問題,代表的算法有One-class SVM。

本文主要介紹從數據角度出發的不平衡數據集的處理方法以及對應的python庫(imblearn)。

二、從數據角度出發的不平衡數據集的處理方法

2-1、隨機采樣

2-1-1、朴素隨機過采樣(上采樣)

針對不平衡數據, 最簡單的一種方法就是生成少數類的樣本, 這其中最基本的一種方法就是: 從少數類的樣本中進行隨機采樣來增加新的樣本,對應Python庫中函數為RandomOverSampler:

from imblearn.over_sampling

import RandomOverSampler

ros = RandomOverSampler(random_state=0)

X_resampled, y_resampled = ros.fit_sample(X, y)

2-1-2、朴素隨機欠采樣(下采樣)

與過采樣相反,欠采樣是從多數類樣本中隨機選擇少量樣本,再合並原有少數類樣本作為新的訓練數據集。

隨機欠采樣有兩種類型分別為有放回和無放回兩種,無放回欠采樣在對多數類某樣本被采樣后不會再被重復采樣,有放回采樣則有可能。

對應Python庫中函數為RandomUnderSampler,通過設置RandomUnderSampler中的replacement=True參數, 可以實現自助法(boostrap)抽樣。

2-1-3、隨機采樣的優缺點

隨機采樣最大的優點是簡單,但缺點也很明顯。上采樣后的數據集中會反復出現一些樣本,訓練出來的模型會有一定的過擬合;而下采樣的缺點顯而易見,那就是最終的訓練集丟失了數據,模型只學到了總體模式的一部分。

上采樣會把小眾樣本復制多份,一個點會在高維空間中反復出現,這會導致一個問題,那就是運氣好就能分對很多點,否則分錯很多點。

為了解決這一問題,可以在每次生成新數據點時加入輕微的隨機擾動,經驗表明這種做法非常有效,但是這一方式會加重過擬合。

2-2、過采樣的改進:SMOTE與ADASYN

相對於采樣隨機的方法進行過采樣, 還有兩種比較流行的過采樣的改進方式: 

(1)、Synthetic Minority Oversampling Technique(SMOTE)

(2)、Adaptive Synthetic (ADASYN) 

2-2-1、SMOTE

SMOTE算法的基本思想是對少數類樣本進行分析並根據少數類樣本人工合成新樣本添加到數據集中,具體下圖所示,算法流程如下:

1、對於少數類中每一個樣本x,計算該點與少數類中其他樣本點的距離,得到最近的k個近鄰(即對少數類點進行KNN算法)。
2、根據樣本不平衡比例設置一個采樣比例以確定采樣倍率,對於每一個少數類樣本x,從其k近鄰中隨機選擇若干個樣本,假設選擇的近鄰為x'。
3、對於每一個隨機選出的近鄰x',分別與原樣本按照如下的公式構建新的樣本:

                    xnew=x+rand(0,1∗ (xx)

但是SMOTE算法缺點也十分明顯:一方面是增加了類之間重疊的可能性(由於對每個少數類樣本都生成新樣本,因此容易發生生成樣本重疊(Overlapping)的問題),

另一方面是生成一些沒有提供有益信息的樣本。

                        SMOTE算法圖

對應Python庫中函數為SMOTE:

from imblearn.over_sampling import SMOTE

X_resampled_smote, y_resampled_smote = SMOTE().fit_sample(X, y)

2-2-2、SMOTE的改進:Borderline-SMOTE

Borderline-SMOTE與原始SMOTE不同的地方在於,原始的SMOTE是對所有少數類樣本生成新樣本。而改進的方法則是先根據規則判斷出少數類的邊界樣本,再對這些樣本生成新樣本。

判斷邊界的一個簡單的規則為:K近鄰中有一半以上多數類樣本的少數類為邊界樣本。直觀地講,只為那些周圍大部分是多數類樣本的少數類樣本生成新樣本。

假設a為少數類中的一個樣本,此時少數類的樣本分為三類,如下圖所示:

(i) 噪音樣本(noise), 該少數類的所有最近鄰樣本都來自於不同於樣本a的其他類別:

(ii) 危險樣本(in danger), 至少一半的最近鄰樣本來自於同一類(不同於a的類別);

(iii) 安全樣本(safe), 所有的最近鄰樣本都來自於同一個類。

                     Borderline-SMOTE算法

對應的Python庫中的實現有三種可以選擇的規則:

SMOTE函數中的kind參數控制了選擇哪種規則:

borderline1:最近鄰中的隨機樣本與該少數類樣本a來自於不同的類;

borderline2:最近鄰中的隨機樣本可以是屬於任何一個類的樣本;

svm:使用支持向量機分類器產生支持向量然后再生成新的少數類樣本。

具體實現如下:

from imblearn.under_sampling

import ClusterCentroids

cc = ClusterCentroids(random_state=0)

X_resampled, y_resampled = cc.fit_sample(X, y)

2-2-3、ADASYN

這種改進方法的主要思想是根據數據分布情況為不同的少數類樣本生成不同數量的新樣本。首先根據最終的平衡程度設定總共需要生成的新少數類樣本數量 ,然后為每個少數類樣本x計算分布比例。

對應Python庫中函數為ADASYN:

from imblearn.over_sampling import ADASYN

X_resampled_adasyn, y_resampled_adasyn = ADASYN().fit_sample(X, y)

2-2-4、基於聚類的過采樣方法

以二分類為例,該方法是首先分別對正負例進行聚類,在聚類之后進行再進行上述的過采樣方法。例如:有一個二分類數據集,其正負類比例為:1000:50。首先通過kmeans算法對正負類分別聚類,

得到正類:600,300,100;負類:30,20。然后使用過采樣的方法分別對所有類別進行過采樣得到正類:600,600,600;對於負類的上采樣個數為:(600+600+600)/2 = 900,即負類為:900,900。

最終得到的數據集為正類1800,負類1800。基於聚類的過采樣方法的優點是不僅可以解決類間不平衡問題,而且還能解決類內部不平衡問題。 

2-3、欠采樣的改進:EasyEnsemble、BalanceCascade與NearMiss

隨機欠采樣的問題主要是信息丟失,為了解決信息丟失的問題提出了以下幾種改進的方式:

1、EasyEnsemble,利用模型融合的方法(Ensemble):

多次過采樣(放回采樣,這樣產生的訓練集才相互獨立)產生多個不同的訓練集,進而訓練多個不同的分類器,通過組合多個分類器的結果得到最終的結果。簡單的最佳實踐是建立n個模型,每個模型使用少數類的所有樣本和多數類的n個不同樣本。假設二分類數據集的正負類比例為50000:1000,最后要得到10個模型,那么將保留負類的1000個樣本,並隨機采樣得到10000個正類樣本。

然后,將10000個樣本成10份,每一份與負類樣本組合得到新的子訓練集,訓練10個不同的模型。

 

2、BalanceCascade,利用增量訓練的思想(Boosting):

先通過一次下采樣產生訓練集,訓練一個分類器,對於那些分類正確的多數類樣本不放回,然后對這個更小的多數類樣本下采樣產生訓練集,訓練第二個分類器,以此類推,最終組合所有分類器的結果得到最終結果。

 

3、NearMiss,利用KNN試圖挑選那些最具代表性的多數類樣本:

首先計算出每個樣本點之間的距離,通過一定規則來選取保留的多數類樣本點。因此該方法的計算量通常很大。

2-3-1、上述方法的Python實現

EasyEnsemble:

EasyEnsemble方法對應Python庫中函數為EasyEnsemble,有兩個很重要的參數: (i) n_subsets控制的是子集的個數 ;(ii) replacement決定是有放回還是無放回的隨機采樣。

 

from imblearn.ensemble

import EasyEnsemble

ee = EasyEnsemble(random_state=0, n_subsets=10)

X_resampled, y_resampled = ee.fit_sample(X, y)

 

BalanceCascade:

BalanceCascade方法對應Python庫中函數為BalanceCascade,有三個很重要的參數: (i) estimator是選擇使用的分類器;(ii) n_max_subset控制的是子集的個數;(iii)  bootstrap決定是有放回還是無放回的隨機采樣。

 

from imblearn.ensemble

import BalanceCascade

from sklearn.linear_model

import LogisticRegression

bc = BalanceCascade(random_state=0,

          estimator=LogisticRegression(random_state=0),

          n_max_subset=4)

X_resampled, y_resampled = bc.fit_sample(X, y)

 

NearMiss:

NearMiss方法對應Python庫中函數為NearMiss,通過version來選擇使用的規則:

NearMiss-1:選擇離N個近鄰的負樣本的平均距離最小的正樣本;

NearMiss-2:選擇離N個負樣本最遠的平均距離最小的正樣本;

NearMiss-3:是一個兩段式的算法。 首先,對於每一個負樣本, 保留它們的M個近鄰樣本;接着, 那些到N個近鄰樣本平均距離最大的正樣本將被選擇。

 

from imblearn.under_sampling

import NearMiss nm1 = NearMiss(random_state=0, version=1)

X_resampled_nm1, y_resampled = nm1.fit_sample(X, y)

 

所有方法的簡單實驗效果可以見:不平衡數據分類算法介紹與比較

2-4、不平衡問題其他的處理方式

除了上述提到的過采樣與欠采樣的方法之外,還可以將多種方法進行組合使用。

另外還可以通過為不同的樣本點賦予不同的權重的方式來處理不平衡問題(與改進損失函數的方式有所類似)。

在算法層面除了對算法本身的改進之外,還需要關注模型的評價指標,來確認使用的方法是否有效。

個人實踐發現,組合方法的結果會比單一某種方法會好很多,例如SMOTEENN和SMOTETomek。

參考文獻:

[1].不均衡學習的抽樣方法

[2].機器學習︱非平衡數據處理方式與評估

[3].數據不平衡問題的處理

[4].不平衡數據的機器學習

[5].數據不平衡imblearn算法匯總

[6].不平衡數據分類算法介紹與比較


免責聲明!

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



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