解決R語言 數(shù)據(jù)不平衡的問題
R語言解決數(shù)據(jù)不平衡問題
一、項(xiàng)目環(huán)境
開發(fā)工具:RStudio
R:3.5.2
相關(guān)包:dplyr、ROSE、DMwR
二、什么是數(shù)據(jù)不平衡?為什么要處理數(shù)據(jù)不平衡?
首先我們要知道的第一個(gè)問題就是“什么是數(shù)據(jù)不平衡”,從字面意思上進(jìn)行解釋就是數(shù)據(jù)分布不均勻。在我們做有監(jiān)督學(xué)習(xí)的時(shí)候,數(shù)據(jù)中有一個(gè)類的比例遠(yuǎn)大于其他類,或者有一個(gè)類的比值遠(yuǎn)小于其他類時(shí),我們就可以認(rèn)為這個(gè)數(shù)據(jù)存在數(shù)據(jù)不平衡問題。
那么這樣的一個(gè)問題會(huì)對(duì)我們后續(xù)的分析工作帶來怎樣的影響呢?我舉個(gè)簡單的例子,或許大家就明白了。
假設(shè)我們現(xiàn)在需要訓(xùn)練一個(gè)模型來分辨人群中那個(gè)人是恐怖分子。那么現(xiàn)在給到我們1萬個(gè)人員的數(shù)據(jù),在做分析之前其實(shí)我們就很清楚,一群人中恐怖分子的比例肯定是要遠(yuǎn)小于普通人的比例的。
那么假如在這1萬個(gè)人中只有一個(gè)是恐怖分子,那么恐怖分子與正常人的比例就是 9999 : 1 。
那么如果我們不進(jìn)行任何處理就直接進(jìn)行有監(jiān)督學(xué)習(xí)的話,那么模型只需要將所有人數(shù)據(jù)都分類為正常人,模型的準(zhǔn)確率就能達(dá)到99.99%。而這樣的模型顯然是沒有意義的。
因?yàn)榛旧险f有可能存在的恐怖分子的特征基本都被模型給忽略了,這也就說明了為什么要處理數(shù)據(jù)不平衡問題。
三、 常見的數(shù)據(jù)不平衡處理方法
以下是幾種比較常見的處理數(shù)據(jù)不平衡的方法:
1、欠采樣法(Undersampling)
2、過采樣法(Oversampling)
3、人工數(shù)據(jù)合成法(Synthetic Data Generation)
4、代價(jià)敏感學(xué)習(xí)法(Cose Sensitive Learning)
【注】:本文主要以實(shí)現(xiàn)為主,因此不對(duì)上述方法進(jìn)行過多的講解。
在處理數(shù)據(jù)之前,我們先看一下需要處理的數(shù)據(jù)分布的情況。
load("C:/Users/User/Desktop/data.RData") table(data$classification) prop.table(table(data$classification))
> table(data$classification)
-8 1 2 3 4 5
12 104 497 1158 4817 1410
> prop.table(table(data$classification))
-8 1 2 3 4 5
0.001500375 0.013003251 0.062140535 0.144786197 0.602275569 0.176294074
1、 欠采樣
######### 方法一 ######### library(ROSE) # 由于是多分類問題,我們先提取數(shù)據(jù)中比例最大的類和比例最小的類 # 進(jìn)行平衡(轉(zhuǎn)化為二分類問題) test <- data[which(data$classification == -8 | data$classification == 4),] # 將分類結(jié)果轉(zhuǎn)化為因子型(不然會(huì)報(bào)錯(cuò)) test$classification <- as.factor(test$classification) # 進(jìn)行欠采樣 # 其中 method = "under" 表示采用的方法為“欠采樣” # N = 40 表示最終整個(gè)數(shù)據(jù)集的數(shù)量 # seed 隨機(jī)種子,為了保留對(duì)樣本的追蹤 under <- ovun.sample(classification ~ ., test, method = "under", N = 40, seed = 1)$data # 查看結(jié)果 table(under$classification)
> table(under$classification)
4 -8
28 12
######### 方法二 ######### library(dplyr) # 由于是多分類問題,我們先提取數(shù)據(jù)中比例最大的類和比例最小的類 # 進(jìn)行平衡(轉(zhuǎn)化為二分類問題) test <- data[which(data$classification == -8 | data$classification == 4),] # 提取大比例類 test1 <- test[which(test$classification == 4),] # 將大比例類的數(shù)量降為12個(gè) down <- sample_n(test1, 12, replace = TRUE) # 將欠采樣后的類進(jìn)行合并 down <- rbind(test[which(test$classification == -8), ],down) table(down$classification)
> table(down$classification)
-8 4
12 12
【注】:欠采樣是無放回的采樣。
2、 過采樣
######### 方法一 ######### library(ROSE) test <- data[which(data$classification == -8 | data$classification == 4),] test$classification <- as.factor(test$classification) # 實(shí)現(xiàn)上大致與欠采樣相同,只有類型 method 改成了 "over",同時(shí)沒有限制總數(shù)量 under <- ovun.sample(classification ~ ., test, method = "over", seed = 1)$data table(under$classification)
> table(under$classification)
4 -8
4817 4785
######### 方法二 ######### library(dplyr) test <- data[which(data$classification == -8 | data$classification == 4),] # 提取小比例類 test1 <- test[which(test$classification == -8),] # 將小比例類的數(shù)量降為4817個(gè)(與大比例類相同) # 這里使用的過采樣方法是隨機(jī)復(fù)制小比例類中的數(shù)據(jù),將其擴(kuò)充到指定數(shù)量 down <- sample_n(test1, 4817, replace = TRUE) down <- rbind(test[which(test$classification == 4), ],down) table(down$classification)
> table(down$classification)
-8 4
4817 4817
3、人工數(shù)據(jù)合成法(Synthetic Data Generation)
######### 方法一 ######### library(ROSE) # 由于是多分類問題,我們先提取數(shù)據(jù)中比例最大的類和比例最小的類 # 進(jìn)行平衡(轉(zhuǎn)化為二分類問題) test <- data[which(data$classification == -8 | data$classification == 4),] # 將分類結(jié)果轉(zhuǎn)化為因子型(不然會(huì)報(bào)錯(cuò)) test$classification <- as.factor(test$classification) # ROSE提供了ROSE()函數(shù)來合成人工數(shù)據(jù) rose <- ROSE(classification ~ ., test, seed = 1)$data # 查看結(jié)果 table(rose$classification)
> table(rose$classification)
4 -8
2483 2346
######### 方法二 ######### library(DMwR) test <- data[which(data$classification == -8 | data$classification == 4),] test$classification <- as.factor(test$classification) # perc.over: 如 perc.over = n,小比例類的個(gè)數(shù)變?yōu)?(n/100)a + a 個(gè)數(shù)據(jù)(a為小比例類原始數(shù)量) # perc.under: 如 perc.under = m,大比例類的個(gè)數(shù)變?yōu)?(nm)/100)a個(gè) # 因此本次案例中,小比例類的個(gè)數(shù)變?yōu)?3500/100)*12 + 12 = 432個(gè) # 大比例類的個(gè)數(shù)變?yōu)?(3500*300)/100^2)*12 = 1260個(gè) down <- SMOTE(classification ~ ., test, perc.over = 3500, perc.under = 300) table(down$classification)
> table(down$classification)
-8 4
432 1260
【注】:相較于前兩種方法而言,人工合成法既不會(huì)像過采樣容易導(dǎo)致過擬合問題,也不會(huì)出現(xiàn)欠采樣大量丟失信息的問題。
4、代價(jià)敏感學(xué)習(xí)法(Cose Sensitive Learning)
【注】:還沒想好怎么寫。。。。。
三、 結(jié)語
本文之所以都只拿兩個(gè)分類在進(jìn)行分析,是因?yàn)樯厦嫣岬降挠糜诮鉀Q數(shù)據(jù)不平衡問題的函數(shù),基本上都是針對(duì)二分類問題的。當(dāng)導(dǎo)入的數(shù)據(jù)中有大于兩個(gè)分類時(shí),函數(shù)就會(huì)報(bào)錯(cuò)。
但是在實(shí)際分析的過程中,其實(shí)我們更經(jīng)常遇到的時(shí)多分類問題,這是我們就需要將多分類問題轉(zhuǎn)化為二分類問題,將各個(gè)分類兩兩進(jìn)行比較才能更好的解決數(shù)據(jù)不平衡的問題。
相關(guān)文章
R語言 數(shù)據(jù)表匹配和拼接 merge函數(shù)的使用
這篇文章主要介紹了R語言 數(shù)據(jù)表匹配和拼接 merge函數(shù)的使用說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03關(guān)于R語言lubridate包處理時(shí)間數(shù)據(jù)的問題
這篇文章主要介紹了關(guān)于R語言lubridate包處理時(shí)間數(shù)據(jù)的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05R語言控制結(jié)構(gòu)知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理一篇關(guān)于R語言控制結(jié)構(gòu)知識(shí)點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。2021-03-03