解决R语言数据不平衡的问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
解决R语⾔数据不平衡的问题
R语⾔解决数据不平衡问题
⼀、项⽬环境
开发⼯具:RStudio
R:3.5.2
相关包:dplyr、ROSE、DMwR
⼆、什么是数据不平衡?为什么要处理数据不平衡?
⾸先我们要知道的第⼀个问题就是“什么是数据不平衡”,从字⾯意思上进⾏解释就是数据分布不均匀。
在我们做有监督学习的时候,数据中有⼀个类的⽐例远⼤于其他类,或者有⼀个类的⽐值远⼩于其他类时,我们就可以认为这个数据存在数据不平衡问题。
那么这样的⼀个问题会对我们后续的分析⼯作带来怎样的影响呢?我举个简单的例⼦,或许⼤家就明⽩了。
假设我们现在需要训练⼀个模型来分辨⼈群中那个⼈是恐怖分⼦。
那么现在给到我们1万个⼈员的数据,在做分析之前其实我们就很清楚,⼀群⼈中恐怖分⼦的⽐例肯定是要远⼩于普通⼈的⽐例的。
那么假如在这1万个⼈中只有⼀个是恐怖分⼦,那么恐怖分⼦与正常⼈的⽐例就是 9999 : 1 。
那么如果我们不进⾏任何处理就直接进⾏有监督学习的话,那么模型只需要将所有⼈数据都分类为正常⼈,模型的准确率就能达到99.99%。
⽽这样的模型显然是没有意义的。
因为基本上说有可能存在的恐怖分⼦的特征基本都被模型给忽略了,这也就说明了为什么要处理数据不平衡问题。
三、常见的数据不平衡处理⽅法
以下是⼏种⽐较常见的处理数据不平衡的⽅法:
1、⽋采样法(Undersampling)
2、过采样法(Oversampling)
3、⼈⼯数据合成法(Synthetic Data Generation)
4、代价敏感学习法(Cose Sensitive Learning)
【注】:本⽂主要以实现为主,因此不对上述⽅法进⾏过多的讲解。
在处理数据之前,我们先看⼀下需要处理的数据分布的情况。
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)
# 由于是多分类问题,我们先提取数据中⽐例最⼤的类和⽐例最⼩的类
# 进⾏平衡(转化为⼆分类问题)
test <- data[which(data$classification == -8 | data$classification == 4),]
# 将分类结果转化为因⼦型(不然会报错)
test$classification <- as.factor(test$classification)
# 进⾏⽋采样
# 其中 method = "under" 表⽰采⽤的⽅法为“⽋采样”
# N = 40 表⽰最终整个数据集的数量
# seed 随机种⼦,为了保留对样本的追踪
under <- ovun.sample(classification ~ ., test, method = "under", N = 40, seed = 1)$data # 查看结果
table(under$classification)
> table(under$classification)
4 -8
28 12
######### ⽅法⼆ #########
library(dplyr)
# 由于是多分类问题,我们先提取数据中⽐例最⼤的类和⽐例最⼩的类
# 进⾏平衡(转化为⼆分类问题)
test <- data[which(data$classification == -8 | data$classification == 4),]
# 提取⼤⽐例类
test1 <- test[which(test$classification == 4),]
# 将⼤⽐例类的数量降为12个
down <- sample_n(test1, 12, replace = TRUE)
# 将⽋采样后的类进⾏合并
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)
# 实现上⼤致与⽋采样相同,只有类型 method 改成了 "over",同时没有限制总数量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),]
# 将⼩⽐例类的数量降为4817个(与⼤⽐例类相同)
# 这⾥使⽤的过采样⽅法是随机复制⼩⽐例类中的数据,将其扩充到指定数量
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、⼈⼯数据合成法(Synthetic Data Generation)
######### ⽅法⼀ #########
library(ROSE)
# 由于是多分类问题,我们先提取数据中⽐例最⼤的类和⽐例最⼩的类
# 进⾏平衡(转化为⼆分类问题)
test <- data[which(data$classification == -8 | data$classification == 4),]
# 将分类结果转化为因⼦型(不然会报错)
test$classification <- as.factor(test$classification)
# ROSE提供了ROSE()函数来合成⼈⼯数据
rose <- ROSE(classification ~ ., test, seed = 1)$data
# 查看结果
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,⼩⽐例类的个数变为 (n/100)a + a 个数据(a为⼩⽐例类原始数量)
# perc.under: 如 perc.under = m,⼤⽐例类的个数变为((nm)/100)a个
# 因此本次案例中,⼩⽐例类的个数变为(3500/100)*12 + 12 = 432个
# ⼤⽐例类的个数变为((3500*300)/100^2)*12 = 1260个
down <- SMOTE(classification ~ ., test, perc.over = 3500, perc.under = 300)
table(down$classification)
> table(down$classification)
-8 4
432 1260
【注】:相较于前两种⽅法⽽⾔,⼈⼯合成法既不会像过采样容易导致过拟合问题,也不会出现⽋采样⼤量丢失信息的问题。
4、代价敏感学习法(Cose Sensitive Learning)
【注】:还没想好怎么写。
三、结语
本⽂之所以都只拿两个分类在进⾏分析,是因为上⾯提到的⽤于解决数据不平衡问题的函数,基本上都是针对⼆分类问题的。
当导⼊的数据中有⼤于两个分类时,函数就会报错。
但是在实际分析的过程中,其实我们更经常遇到的时多分类问题,这是我们就需要将多分类问题转化为⼆分类问题,将各个分类两两进⾏⽐较才能更好的解决数据不平衡的问题。