样本不均衡问题
文章目錄一瞥
- 什么是樣本類別分布不均衡?
- 樣本類別分布不均衡導(dǎo)致的危害?
- 解決方法:
- 1.通過過抽樣和欠抽樣解決樣本不均衡
- (1)過抽樣(over-sampling):通過增加分類中少數(shù)類樣本的數(shù)量來實現(xiàn)樣本均衡,比較好的方法有SMOTE算法。
- (2)欠抽樣(under-sampling):通過減少分類中多數(shù)類樣本的數(shù)量來實現(xiàn)樣本均衡
- 2.通過正負(fù)樣本的懲罰權(quán)重解決樣本不均衡
- (1)帶權(quán)值的損失函數(shù):
- (2)難例挖掘
- (3)Focal loss
- python 實現(xiàn)focal loss
- 3.類別均衡采樣
- Thresholding
- Cost sensitive learning
- One-class分類
- 集成的方法
- 使用其他評價指標(biāo)
- 如何選擇
- 參考文獻(xiàn)
今天學(xué)習(xí)了關(guān)于樣本類別分布不均衡的處理的一些知識,在此和大家一起分享一下。
什么是樣本類別分布不均衡?
舉例說明,在一組樣本中不同類別的樣本量差異非常大,比如擁有1000條數(shù)據(jù)樣本的數(shù)據(jù)集中,有一類樣本的分類只占有10條,此時屬于嚴(yán)重的數(shù)據(jù)樣本分布不均衡。
樣本不均衡指的是給定數(shù)據(jù)集中有的類別數(shù)據(jù)多,有的數(shù)據(jù)類別少,且數(shù)據(jù)占比較多的數(shù)據(jù)類別樣本與占比較小的數(shù)據(jù)類別樣本兩者之間達(dá)到較大的比例。
樣本類別分布不均衡導(dǎo)致的危害?
樣本類別不均衡將導(dǎo)致樣本量少的分類所包含的特征過少,并很難從中提取規(guī)律;即使得到分類模型,也容易產(chǎn)生過度依賴與有限的數(shù)據(jù)樣本而導(dǎo)致過擬合問題,當(dāng)模型應(yīng)用到新的數(shù)據(jù)上時,模型的準(zhǔn)確性會很差。
解決方法:
- 數(shù)據(jù)層面:采樣,數(shù)據(jù)增強,數(shù)據(jù)合成等;
- 算法層面:修改損失函數(shù)值,難例挖掘等。
- 分類器層面:
1.通過過抽樣和欠抽樣解決樣本不均衡
采樣
隨機過采樣:從少數(shù)類樣本集中隨機重復(fù)抽取樣本(有放回)以得到更多的樣本;
隨機欠采樣:從多數(shù)類樣本集中隨機選擇較少的樣本(有放回/無放回);
隨機采樣的缺點
過采樣對少數(shù)樣本進(jìn)行了復(fù)制多份,雖然擴(kuò)大了數(shù)據(jù)規(guī)模,但是也容易造成過擬合;
欠采樣中丟失了部分樣本,可能損失有用的信息,造成模型對某些特征的欠擬合
(1)過抽樣(over-sampling):通過增加分類中少數(shù)類樣本的數(shù)量來實現(xiàn)樣本均衡,比較好的方法有SMOTE算法。
1. 基礎(chǔ)版本的過采樣:隨機過采樣訓(xùn)練樣本中數(shù)量比較少的數(shù)據(jù);缺點,容易過擬合;
2. 改進(jìn)版本的過采樣:SMOTE,通過插值的方式加入近鄰的數(shù)據(jù)點;
3. 基于聚類的過采樣:先對數(shù)據(jù)進(jìn)行聚類,然后對聚類后的數(shù)據(jù)分別進(jìn)行過采樣。這種方法能夠降低類間和類內(nèi)的不平衡。
4. 神經(jīng)網(wǎng)絡(luò)中的過采樣:SGD訓(xùn)練時,保證每個batch內(nèi)部樣本均衡。
SMOTE算法:簡單來說smote算法的思想是合成新的少數(shù)類樣本,合成的策略是對每個少數(shù)類樣本a,從它的最近鄰中隨機選一個樣本b,然后在a、b之間的連線上隨機選一點作為新合成的少數(shù)類樣本。具體的過程大家可以自行g(shù)oogle。
附上代碼示例:(首先展示示例數(shù)據(jù),本篇文章都用此數(shù)據(jù))
import pandas as pd
from imblearn.over_sampling import SMOTE #過度抽樣處理庫SMOTE
df=pd.read_table('data2.txt',sep=' ',names=['col1','col2','col3','col4','col5','label'])
x=df.iloc[:,:-1]
y=df.iloc[:,-1]
groupby_data_orginal=df.groupby('label').count() #根據(jù)標(biāo)簽label分類匯總
- 1
- 2
- 3
- 4
- 5
- 6
用groupby可以看到該數(shù)據(jù)label=0的有942個樣本,label=1的只有58個,存在嚴(yán)重的不均衡現(xiàn)象,在這里我們用SMOTE算法來解決一下。
model_smote=SMOTE() #建立smote模型對象
x_smote_resampled,y_smote_resampled=model_smote.fit_sample(x,y)
x_smote_resampled=pd.DataFrame(x_smote_resampled,columns=['col1','col2','col3','col4','col5'])
y_smote_resampled=pd.DataFrame(y_smote_resampled,columns=['label'])
smote_resampled=pd.concat([x_smote_resampled,y_smote_resampled],axis=1)
groupby_data_smote=smote_resampled.groupby('label').count()
- 1
- 2
- 3
- 4
- 5
- 6
(2)欠抽樣(under-sampling):通過減少分類中多數(shù)類樣本的數(shù)量來實現(xiàn)樣本均衡
與過采樣方法相對立的是欠采樣方法,主要是移除數(shù)據(jù)量較多類別中的部分?jǐn)?shù)據(jù)。這個方法的問題在于,丟失數(shù)據(jù)帶來的信息缺失。為克服這一缺點,可以丟掉一些類別邊界部分的數(shù)據(jù)。
from imblearn.under_sampling import RandomUnderSampler
model_RandomUnderSampler=RandomUnderSampler() #建立RandomUnderSample模型對象
x_RandomUnderSample_resampled,y_RandomUnderSample_resampled=model_RandomUnderSampler.fit_sample(x,y) #輸入數(shù)據(jù)并進(jìn)行欠抽樣處理
x_RandomUnderSample_resampled=pd.DataFrame(x_RandomUnderSample_resampled,columns=['col1','col2','col3','col4','col5'])
y_RandomUnderSample_resampled=pd.DataFrame(y_RandomUnderSample_resampled,columns=['label'])
RandomUnderSampler_resampled=pd.concat([x_RandomUnderSample_resampled,y_RandomUnderSample_resampled],axis=1)
groupby_data_RandomUnderSampler=RandomUnderSampler_resampled.groupby('label').count()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.通過正負(fù)樣本的懲罰權(quán)重解決樣本不均衡
(1)帶權(quán)值的損失函數(shù):
簡單粗暴地為小樣本標(biāo)簽增加損失函數(shù)的權(quán)值,加權(quán)之后可以簡單地理解是:對于小樣本一個數(shù)據(jù)頂多個使用,這里的多就是我們要設(shè)置的權(quán)值,有點類似于對小樣本數(shù)據(jù)進(jìn)行了過采樣的操作;
(2)難例挖掘
難例挖掘:指的就是挖掘出模型預(yù)測效果較差的樣本,模型預(yù)測效果較差即就是在難樣本上的預(yù)測損失函數(shù)值很大,挖掘出這些難訓(xùn)練的樣本,然后對這些樣本再進(jìn)行重新訓(xùn)練等。
想一想為什么這個可以部分解決樣本不均衡的問題呢?
其實,很簡單的可以理解這個方法為什么可以work,難例挖掘,對于我們的小樣本數(shù)據(jù),模型的預(yù)測效果可想而知肯定預(yù)測的不好啦,預(yù)測的不好,那么不就會被挖掘出來當(dāng)作難例了嗎?模型對這些樣本再次處理,對小樣本數(shù)據(jù)就有了特殊的待遇,有種成績不好的學(xué)生被老師帶到辦公室再學(xué)習(xí)的感覺,那么成績不好的學(xué)生怎么說也會有點提高吧,模型不也就能夠相應(yīng)的提高performance了!
(3)Focal loss
focal loss 出自于論文Focal Loss for Dense Object Detection
具體的講解可以去看這篇文章:https://zhuanlan.zhihu.com/p/32423092
此處簡單介紹一下:focal loss在原來帶權(quán)值的loss函數(shù)的基礎(chǔ)上進(jìn)行了改進(jìn),改進(jìn)的方向也是損失函數(shù)的權(quán)值。
再瞅一眼二分類交叉熵?fù)p失函數(shù)的表達(dá)式:
按照上述例子,是否發(fā)現(xiàn)我們對于預(yù)測錯誤的樣本的損失函數(shù)值的權(quán)值相比預(yù)測正確的權(quán)值大了很多,原始兩者比例是1:1,現(xiàn)在的比例是1:64,相當(dāng)于對于預(yù)測錯誤的樣本,我們對其處理是權(quán)值增加了63倍。
這種對損失函數(shù)修改權(quán)值的方法,是依據(jù)概率而修改的,不像直接修改損失函數(shù)的權(quán)值,直接修改顯得有些生硬。
記住到這里我們挖掘出來的是預(yù)測錯誤的,而沒有針對數(shù)據(jù)不平衡進(jìn)行操作(當(dāng)然數(shù)據(jù)不平衡也會導(dǎo)致預(yù)測錯誤),我們繼續(xù)對損失函數(shù)加上權(quán)值,此時的權(quán)值就是對類別不平衡的處理,表達(dá)式如下:
python 實現(xiàn)focal loss
def focal_loss(labels, logits, gamma, alpha):labels = tf.cast(labels, tf.float32)probs = tf.sigmoid(logits)ce_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=labels, logits=logits)alpha_t = tf.ones_like(logits) * alphaalpha_t = tf.where(labels > 0, alpha_t, 1.0 - alpha_t)probs_t = tf.where(labels > 0, probs, 1.0 - probs)focal_matrix = alpha_t * tf.pow((1.0 - probs_t), gamma)loss = focal_matrix * ce_loss loss = tf.reduce_mean(loss) return loss
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
**
算法思想:對于分類中不同樣本數(shù)量的類別分別賦予不同的權(quán)重,一般是小樣本量類別權(quán)重高,大樣本量類別權(quán)重低。**
這里以SVM為例:
from sklearn.svm import SVC
model_svm=SVC(class_weight='balanced')
model_svm.fit(x,y)
- 1
- 2
- 3
這里的class_weight選項用其默認(rèn)方法‘balanced’,即SVM會將權(quán)重設(shè)置為與不同類別樣本數(shù)量呈反比的權(quán)重來進(jìn)行自動均衡處理。
3.類別均衡采樣
把樣本按類別分組,每個類別生成一個樣本列表,訓(xùn)練過程中先隨機選擇1個或幾個類別,然后從各個類別所對應(yīng)的樣本列表里選擇隨機樣本。這樣可以保證每個類別參與訓(xùn)練的機會比較均等。
上述方法需要對于樣本類別較多任務(wù)首先定義與類別相等數(shù)量的列表,對于海量類別任務(wù)如ImageNet數(shù)據(jù)集等此舉極其繁瑣。海康威視研究院提出類別重組的平衡方法。
類別重組法只需要原始圖像列表即可完成同樣的均勻采樣任務(wù),步驟如下:
- 首先按照類別順序?qū)υ紭颖具M(jìn)行排序,之后計算每個類別的樣本數(shù)目,并記錄樣本最多那個類的樣本數(shù)目。
- 之后,根據(jù)這個最多樣本數(shù)對每類樣本產(chǎn)生一個隨機排列的列表,
- 然后用此列表中的隨機數(shù)對各自類別的樣本數(shù)取余,得到對應(yīng)的索引值。
- 接著,根據(jù)索引從該類的圖像中提取圖像,生成該類的圖像隨機列表。之后將所有類的隨機列表連在一起隨機打亂次序,即可得到最終的圖像列表,可以發(fā)現(xiàn)最終列表中每類樣本數(shù)目均等。
- 根據(jù)此列表訓(xùn)練模型,在訓(xùn)練時列表遍歷完畢,則重頭再做一遍上述操作即可進(jìn)行第二輪訓(xùn)練,如此往復(fù)。
- 類別重組法的優(yōu)點在于,只需要原始圖像列表,且所有操作均在內(nèi)存中在線完成,易于實現(xiàn)。
Thresholding
Thresholding的方法又稱為post scaling的方法,即根據(jù)測試數(shù)據(jù)的不同類別樣本的分布情況選取合適的閾值判斷類別,也可以根據(jù)貝葉斯公式重新調(diào)整分類器輸出概率值。一般的基礎(chǔ)做法如下:假設(shè)對于某個類別class在訓(xùn)練數(shù)據(jù)中占比為x,在測試數(shù)據(jù)中的占比為x’。分類器輸出的概率值需要做scaling,概率轉(zhuǎn)換公式為:
fp=apap+b*1-p
a=x’x, b=1-x’1-x
當(dāng)然這種加權(quán)的方式亦可在模型訓(xùn)練過程中進(jìn)行添加,即對于二分類問題目標(biāo)函數(shù)可以轉(zhuǎn)換為如下公式:
loss=aytruelogypred+b1-ytruelog1-ypred
Cost sensitive learning
根據(jù)樣本中不同類別的誤分類樣本數(shù)量,重新定義損失函數(shù)。Threshold moving和post scaling是常見的在測試過程進(jìn)行cost調(diào)整的方法。這種方法在訓(xùn)練過程計算損失函數(shù)時亦可添加,具體參見上一部分。另外一種cost sensitive的方法是動態(tài)調(diào)節(jié)學(xué)習(xí)率,認(rèn)為容易誤分的樣本在更新模型參數(shù)時的權(quán)重更大一些。
One-class分類
區(qū)別于作類別判決,One-class分類只需要從大量樣本中檢測出該類別即可,對于每個類別均是一個獨立的detect model。這種方法能很好地樣本極度不均衡的問題。
集成的方法
主要是使用多種以上的方法。例如SMOTEBoost方法是將Boosting和SMOTE 過采樣進(jìn)行結(jié)合。
使用其他評價指標(biāo)
在準(zhǔn)確率不行的情況下,使用召回率或者精確率試試。
準(zhǔn)確度這個評價指標(biāo)在類別不均衡的分類任務(wù)中并不能work。幾個比傳統(tǒng)的準(zhǔn)確度更有效的評價指標(biāo):
混淆矩陣(Confusion Matrix):使用一個表格對分類器所預(yù)測的類別與其真實的類別的樣本統(tǒng)計,分別為:TP、FN、FP與TN。
精確度(Precision)
召回率(Recall)
F1得分(F1 Score):精確度與找召回率的加權(quán)平均。
特別是:
Kappa (Cohen kappa)
ROC曲線(ROC Curves):見Assessing and Comparing Classifier Performance with ROC Curves
如何選擇
解決數(shù)據(jù)不平衡問題的方法有很多,上面只是一些最常用的方法,而最常用的方法也有這么多種,如何根據(jù)實際問題選擇合適的方法呢?接下來談?wù)勔恍┪业慕?jīng)驗。
1、在正負(fù)樣本都非常之少的情況下,應(yīng)該采用數(shù)據(jù)合成的方式;
2、在負(fù)樣本足夠多,正樣本非常之少且比例及其懸殊的情況下,應(yīng)該考慮一分類方法;
3、在正負(fù)樣本都足夠多且比例不是特別懸殊的情況下,應(yīng)該考慮采樣或者加權(quán)的方法。
4、采樣和加權(quán)在數(shù)學(xué)上是等價的,但實際應(yīng)用中效果卻有差別。尤其是采樣了諸如Random Forest等分類方法,訓(xùn)練過程會對訓(xùn)練集進(jìn)行隨機采樣。在這種情況下,如果計算資源允許上采樣往往要比加權(quán)好一些。
5、另外,雖然上采樣和下采樣都可以使數(shù)據(jù)集變得平衡,并且在數(shù)據(jù)足夠多的情況下等價,但兩者也是有區(qū)別的。實際應(yīng)用中,我的經(jīng)驗是如果計算資源足夠且小眾類樣本足夠多的情況下使用上采樣,否則使用下采樣,因為上采樣會增加訓(xùn)練集的大小進(jìn)而增加訓(xùn)練時間,同時小的訓(xùn)練集非常容易產(chǎn)生過擬合。
6、對于下采樣,如果計算資源相對較多且有良好的并行環(huán)境,應(yīng)該選擇Ensemble方法。
參考文獻(xiàn)
如何解決樣本不均衡問題
Pytorch中使用樣本權(quán)重(sample_weight)的正確方式
SMOTE算法(人工合成數(shù)據(jù))
如何解決機器學(xué)習(xí)中數(shù)據(jù)不平衡問題
</div><link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-b6c3c6d139.css" rel="stylesheet"><div class="more-toolbox"><div class="left-toolbox"><ul class="toolbox-list"><li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true"><use xlink:href="#csdnc-thumbsup"></use></svg><span class="name">點贊</span><span class="count">1</span></a></li><li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-csdnc-Collection-G"></use></svg><span class="name">收藏</span></a></li><li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{"mod":"1582594662_002"}"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-csdnc-fenxiang"></use></svg>分享</a></li><!--打賞開始--><!--打賞結(jié)束--><li class="tool-item tool-more"><a><svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg></a><ul class="more-box"><li class="item"><a class="article-report">文章舉報</a></li></ul></li></ul></div></div><div class="person-messagebox"><div class="left-message"><a href="https://blog.csdn.net/weixin_42462804"><img src="https://profile.csdnimg.cn/5/2/D/3_weixin_42462804" class="avatar_pic" username="weixin_42462804"><img src="https://g.csdnimg.cn/static/user-reg-year/2x/2.png" class="user-years"></a></div><div class="middle-message"><div class="title"><span class="tit"><a href="https://blog.csdn.net/weixin_42462804" data-report-click="{"mod":"popu_379"}" target="_blank">和你在一起^_^</a></span></div><div class="text"><span>發(fā)布了129 篇原創(chuàng)文章</span> · <span>獲贊 87</span> · <span>訪問量 9萬+</span></div></div><div class="right-message"><a href="https://im.csdn.net/im/main.html?userName=weixin_42462804" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信</a><a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">關(guān)注</a></div></div></div>
</article>
樣本不均衡分類問題的解決
1.每種分類構(gòu)建一個模型負(fù)樣本為少數(shù)其他類
2.多個模型融合會產(chǎn)生比較好的結(jié)果
3.兩個模型都調(diào)閾值增強正確的全部預(yù)測對 然后再把兩個模型融合起來
4.或者直接構(gòu)建兩個欠擬合模型再融合二者
20211010
集成方法——使用所有分類中的小樣本量,同時從分類中的大樣本量中隨機抽取數(shù)據(jù)來與小樣本量合并構(gòu)成訓(xùn)練集,這樣反復(fù)多次會得到很多訓(xùn)練集,從而訓(xùn)練出多個模型。例如,在數(shù)據(jù)集中的正、負(fù)樣本分別為100和10000條,比例為1:100,此時可以將負(fù)樣本隨機切分為100份,每份100條數(shù)據(jù),然后每次形成訓(xùn)練集時使用所有的正樣本(100條)和隨機抽取的負(fù)樣本(100條)形成新的訓(xùn)練數(shù)據(jù)集。如此反復(fù)可以得到100個模型。然后繼續(xù)集成表決
當(dāng)然常用的是上述集成方法,但是不是直接進(jìn)行使用,試想訓(xùn)練100個模型進(jìn)行表決,離線會很麻煩,而且線上使用也不現(xiàn)實。
所以通常會進(jìn)行修改使用,一般情況下在選擇正負(fù)樣本時會進(jìn)行相關(guān)比例的控制,假設(shè)正樣本的條數(shù)是N,則負(fù)樣本的條數(shù)會控制在2N或者3N,即遵循1:2或者1:3的關(guān)系,當(dāng)然具體的業(yè)務(wù)場景下要進(jìn)行不同的嘗試和離線評估指標(biāo)的對比。
總結(jié)
- 上一篇: 快速访问github镜像 wiki镜像重
- 下一篇: SMOTE算法代码实现-机器学习