熱線電話:13121318867

登錄
首頁精彩閱讀R語言中樣本平衡的幾種方法
R語言中樣本平衡的幾種方法
2017-06-07
收藏

R語言中樣本平衡的幾種方法

在對不平衡的分類數據集進行建模時,機器學習算法可能并不穩定,其預測結果甚至可能是有偏的,而預測精度此時也變得帶有誤導性。在不平衡的數據中,任一算法都沒法從樣本量少的類中獲取足夠的信息來進行精確預測。因此,機器學習算法常常被要求應用在平衡數據集上。不平衡分類是一種有監督學習,但它處理的對象中有一個類所占的比例遠遠大于其余類。比起多分類,這一問題在二分類中更為常見。不平衡一詞指代數據中響應變量(被解釋變量)的分布不均衡,如果一個數據集的響應變量在不同類上的分布差別較大我們就認為它不平衡。

舉個例子,假設我們有一個觀測數為100000的數據集,它包含了哈佛大學申請人的信息。眾所周知,哈佛大學以極低的錄取比例而聞名,那么這個數據集的響應變量(即:該申請人是否被錄取,是為1,否為0)就很不平衡,大致98%的觀測響應變量為0,只有2%的幸運兒被錄取。

在現實生活中,這類例子更是不勝枚舉,我在下面列舉了一些實例,請注意他們的不平衡度是不一樣的。

一個自動產品質量檢測機每天會檢測工廠生產的產品,你會發現次品率是遠遠低于合格率的。

某地區進行了居民癌癥普查,結果患有癌癥的居民人數也是遠遠少于健康人群。

在信用卡欺詐數據中,違規交易數比合規交易少不少。

一個遵循6δ原則的生產車間每生產100萬個產品才會產出10個次品。

生活中的例子還有太多,現在你可以發現獲取這些非平衡數據的可能性有多大,所以掌握這些數據集的處理方法也是每個數據分析師的必修課。

常用樣本平衡的處理辦法

欠采樣法

該方法主要是對大類進行處理。它會減少大類的觀測數來使得數據集平衡。這一辦法在數據集整體很大時較為適宜,它還可以通過降低訓練樣本量來減少計算時間和存儲開銷。

欠采樣法共有兩類:隨機(Random)的和有信息的(Informative)。

隨機欠采樣法會隨機刪除大類的觀測直至數據集平衡。有信息的欠采樣法則會依照一個事先制定的準則來刪去觀測。

有信息的欠采樣中,利用簡易集成算法(EasyEnsemble)和平衡級聯算法(BalanceCascade)往往能得到比較好的結果。這兩種算法也都很直白易懂。

簡易集成法:首先,它將從大類中有放回地抽取一些獨立樣本生成多個子集。然后,將這些子集和小類的觀測合并,再基于合并后的數據集訓練多個分類器,以其中多數分類器的分類結果為預測結果。如你所見,整個流程和無監督學習非常相似。

平衡級聯法:它是一種有監督的學習法,首先將生成多個分類器,再基于一定規則系統地篩選哪些大類樣本應當被保留。

但欠采樣法有一個顯而易見的缺陷,由于要刪去不少觀測,使用該方法會使得大類損失不少重要信息。

過采樣

這一方法針對小類進行處理。它會以重復小類的觀測的方式來平衡數據。該方法也被稱作升采樣(Upsampling)。和欠采樣類似,它也能分為隨機過采樣和有信息的過采樣兩類。

隨機過采樣會將小類觀測隨機重復。有信息過采樣也是遵循一定的準則來人工合成小類觀測。

使用該方法的一大優勢是沒有任何信息損失。缺點則是由于增加了小類的重復樣本,很有可能導致過擬合(計算時間和存儲開銷也增大不少)。我們通過該方法可以在訓練集上得到非常高的擬合精度,但在測試集上預測的表現則可能變得愈發糟糕。

人工數據合成法

簡單說來,人工數據合成法是利用生成人工數據而不是重復原始觀測來解決不平衡性。它也是一種過采樣技術。

在這一領域,SMOTE法(Synthetic Minority OversamplingTechnique)是有效而常用的方法。 該算法基于特征空間(而不是數據空間)生成與小類觀測相似的新數據(總體是基于歐氏距離來度量相似性,在特征空間生成一些人工樣本,更通俗地說是在樣本點和它近鄰點的連線上隨機投點作為生成的人工樣本)。我們也可以說,它生成了小類觀測的隨機集合來降低分類器的誤差。為了生成人工數據,我們需要利用自助法(Bootstrapping)和K近鄰法(K-neraestneighbors)。

詳細步驟如下:

計算樣本點間的距離并確定其近鄰。生成一個0到1上的均勻隨機數,并將其乘以距離。 把第二步生成的值加到樣本點的特征向量上。這一過程等價于在在兩個樣本的連線上隨機選擇了一個點。 R中有一個包專門用來實現SMOTE過程。

代價敏感學習(CSL)

該方法會衡量誤分類觀測的代價來解決不平衡問題。它不會生成平衡的數據集,而是通過生成代價矩陣來解決不平衡問題。代價矩陣是描述特定場景下誤分類觀測帶來的損失的工具。近來已有研究表明,代價敏感學習法很多時候比采樣法更優。

例子:給定一個有關行人的數據集,我們想要了解行人是否會攜帶炸彈。數據集包含了所有的必要信息,且攜帶炸彈的人會被標記為正類,不帶炸彈的就是負類?,F在問題來了,我們需要把行人都分好類。讓我們先來設定下這一問題的代價矩陣。如果我們將行人正確分類了,我們不會蒙受任何損失。但如果我們把一個恐怖分子歸為負類(False Negative),我們要付出的代價會比把和平分子歸為正類(FalsePositive)的代價大的多。

代價矩陣和混淆矩陣類似,都有偽正類(FP)和偽負類(FN)。只要觀測被正確分類,我們不會有任何代價損失。該方法的目標就是找到一個使得總代價最小的分類器Total Cost = C(FN)xFN + C(FP)xFP,其中,FN是被誤分類的正類樣本數,FP是被誤分類的負類樣本數。C(FN)和C(FP)分別代表FN和FP帶來的損失。本例中C(FN) > C(FP)

其它方法

除此之外,我們還有其他的比較前沿的方法來處理不平衡樣本。

比如基于聚類的采樣法(Cluster based sampling),自適應人工采樣法(adaptivesynthetic sampling),邊界線SMOTE(borderline SMOTE),SMOTEboost,DataBoost-IM,核方法等。

這些方法的基本思想和前文介紹的四類方法大同小異。還有一些更直觀的方法可以幫助你提升預測效果:如利用聚類技術,把大類分為K個次類,每個此類的樣本不重疊。再基于每個次類和小類的合并樣本來訓練分類器。最后把各個分類結果平均作為預測值。

除此之外,也可以聚焦于獲取更多數據來提高小類的占比。

R語言中處理樣本平衡的幾種方法及案例

ROSE包中內置了一個叫做hacide的不平衡數據集,它包括hacide.train和hacide.test兩個部分

data(hacide)

summary(hacide.train)

## cls           x1                 x2         

## 0:980   Min.   :-3.73468  Min.   :-3.17886 

## 1: 20   1st Qu.:-0.39539   1st Qu.:-0.78564 

##         Median :-0.03025   Median:-0.06871 

##         Mean   :-0.03185   Mean  :-0.06603 

##         3rd Qu.: 0.35474   3rd Qu.:0.69454 

##         Max.   : 1.98859   Max.  : 3.03422


#檢查cls的分布

prop.table(table(hacide.train$cls))

##

##   0    1

## 0.98 0.02

數據的不平衡性極其嚴重。那么,這對我們的分類精度會帶來多大影響?我們先建立一個簡單的決策樹模型:


treeimb <- rpart(cls ~ ., data =hacide.train)

pred.treeimb <- predict(treeimb, newdata= hacide.test)

roc.curve(hacide.test$cls,pred.treeimb[,2], plotit = F)

## Area under the curve (AUC): 0.600


我們將使用采樣技術來提升預測精度。ROSE這個包提供了ovun.sample()的函數來實現過采樣和欠采樣。

過采樣

data.balanced.over <- ovun.sample(cls ~., data = hacide.train, method = "over",N = 1960, seed = 1)$data

#N代表最終平衡數據集包含的樣本點,本例中我們有980個原始負類樣本

#所以我們要通過過采樣法把正類樣本也補充到980個,數據集共有1960個觀測。

summary(data.balanced.over)

## cls           x1                x2         

## 0:980   Min.   :-3.7347  Min.   :-3.17886 

## 1:980   1st Qu.:-1.4272   1st Qu.:-1.71230 

##         Median :-0.3636   Median:-1.10791 

##         Mean   :-0.4976   Mean  :-0.86577 

##         3rd Qu.: 0.3669   3rdQu.:-0.03141 

##         Max.   : 1.9886   Max.  : 3.03422

欠采樣

data.balanced.under <- ovun.sample(cls ~., data = hacide.train, method = "under", N = 40, seed = 1)$data

#欠采樣后數據是平衡了,但由于只剩下了40個樣本,我們損失了太多信息。

#我們還可以同時采取這兩類方法,只需要把參數改為method = “both”。

#這時,對小類樣本會進行有放回的過采樣而對大類樣本則進行無放回的欠采樣

summary(data.balanced.under)

## cls          x1                x2        

## 0:20   Min.   :-3.7347  Min.   :-3.0160 

## 1:20   1st Qu.:-1.4453   1st Qu.:-1.7321 

##         Median :-0.2949   Median :-1.0603 

##        Mean   :-0.4647   Mean  :-0.6991 

##        3rd Qu.: 0.4754   3rd Qu.:0.2932 

##        Max.   : 1.9886   Max.  : 3.0342


雙采樣

data.balanced.both <- ovun.sample(cls ~., data = hacide.train, method = "both", p=0.5, N=1000, seed =1)$data

#函數的參數p代表新生成數據集中稀有類(正類)的比例。

summary(data.balanced.both)

## cls           x1                x2        

## 0:520   Min.   :-3.7347  Min.   :-3.1789 

## 1:480   1st Qu.:-1.4999   1st Qu.:-1.6710 

##         Median :-0.3341   Median :-1.0405 

##         Mean   :-0.4799   Mean  :-0.8230 

##         3rd Qu.: 0.3648   3rd Qu.:0.1073 

##         Max.   : 1.9886   Max.  : 2.8838

人工數據合成

欠采樣會損失信息,過采樣容易導致過擬合,因而ROSE包也提供了ROSE()函數來合成人工數據,它能提供關于原始數據的更好估計。


data.rose <- ROSE(cls ~ ., data =hacide.train, seed = 1)$data

summary(data.rose)

## cls           x1                x2        

## 0:520   Min.   :-7.3390  Min.   :-3.8467 

## 1:480   1st Qu.:-1.1717   1st Qu.:-1.7673 

##         Median :-0.2453   Median:-0.9313 

##         Mean   :-0.4795   Mean  :-0.8213 

##         3rd Qu.: 0.3574   3rd Qu.:0.1108 

##         Max.   : 4.1899   Max.  : 3.1168

這里生成的數據量和原始數據集相等(1000個觀測)?,F在,我們已經用4種方法平衡了數據,我們分別建模評評估精度。



訓練決策樹

tree.rose <- rpart(cls ~ ., data =data.rose)

tree.over <- rpart(cls ~ ., data =data.balanced.over)

tree.under <- rpart(cls ~ ., data =data.balanced.under)

tree.both <- rpart(cls ~ ., data =data.balanced.both)

在測試集上做預測

pred.tree.rose <- predict(tree.rose,newdata = hacide.test)

pred.tree.over <- predict(tree.over,newdata = hacide.test)

pred.tree.under <- predict(tree.under,newdata = hacide.test)

pred.tree.both <- predict(tree.both,newdata = hacide.test)

下面,使用roc.curve()函數來評估精度


roc.curve(hacide.test$cls,pred.tree.rose[,2], plotit = F)

## Area under the curve (AUC):0.989

roc.curve(hacide.test$cls,pred.tree.over[,2], plotit = F)

## Area under the curve (AUC): 0.798

roc.curve(hacide.test$cls,pred.tree.under[,2], plotit = F)

## Area under the curve (AUC): 0.867

roc.curve(hacide.test$cls,pred.tree.both[,2], plotit = F)

## Area under the curve (AUC): 0.798


因此,我們發現利用人工數據合成法可以帶來最高的預測精度,其表現比采樣法更好。這一技術和更穩健的模型結合(隨機森林,提升法)可以得到更高的精度。當我們面對不平衡數據集時,我們常常發現利用采樣法修正的效果不錯。但在本例中,人工數據合成比傳統的采樣法更好。為了得到更好的結果,你可以使用一些更前沿的方法,諸如基于boosting 的人工數據合成。


數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢