解决R语言 数据不平衡的问题
R语言解决数据不平衡问题
一、项目环境
开发工具:RStudio
R:3.5.2
相关包:dplyr、ROSE、DMwR
二、什么是数据不平衡?为什么要处理数据不平衡?
首先我们要知道的第一个问题就是“什么是数据不平衡”,从字面意思上进行解释就是数据分布不均匀。在我们做有监督学习的时候,数据中有一个类的比例远大于其他类,或者有一个类的比值远小于其他类时,我们就可以认为这个数据存在数据不平衡问题。
那么这样的一个问题会对我们后续的分析工作带来怎样的影响呢?我举个简单的例子,或许大家就明白了。
假设我们现在需要训练一个模型来分辨人群中那个人是恐怖分子。那么现在给到我们1万个人员的数据,在做分析之前其实我们就很清楚,一群人中恐怖分子的比例肯定是要远小于普通人的比例的。
那么假如在这1万个人中只有一个是恐怖分子,那么恐怖分子与正常人的比例就是9999:1。
那么如果我们不进行任何处理就直接进行有监督学习的话,那么模型只需要将所有人数据都分类为正常人,模型的准确率就能达到99.99%。而这样的模型显然是没有意义的。
因为基本上说有可能存在的恐怖分子的特征基本都被模型给忽略了,这也就说明了为什么要处理数据不平衡问题。
三、常见的数据不平衡处理方法
以下是几种比较常见的处理数据不平衡的方法:
1、欠采样法(Undersampling)
2、过采样法(Oversampling)
3、人工数据合成法(SyntheticDataGeneration)
4、代价敏感学习法(CoseSensitiveLearning)
【注】:本文主要以实现为主,因此不对上述方法进行过多的讲解。
在处理数据之前,我们先看一下需要处理的数据分布的情况。
load("C:/Users/User/Desktop/data.RData") table(data$classification) prop.table(table(data$classification))
>table(data$classification)
-812345
12104497115848171410
>prop.table(table(data$classification))
-812345
0.0015003750.0130032510.0621405350.1447861970.6022755690.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
2812
#########方法二######### 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)
-84
1212
【注】:欠采样是无放回的采样。
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
48174785
#########方法二######### 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)
-84
48174817
3、人工数据合成法(SyntheticDataGeneration)
#########方法一######### 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
24832346
#########方法二######### 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)
-84
4321260
【注】:相较于前两种方法而言,人工合成法既不会像过采样容易导致过拟合问题,也不会出现欠采样大量丢失信息的问题。
4、代价敏感学习法(CoseSensitiveLearning)
【注】:还没想好怎么写。。。。。
三、结语
本文之所以都只拿两个分类在进行分析,是因为上面提到的用于解决数据不平衡问题的函数,基本上都是针对二分类问题的。当导入的数据中有大于两个分类时,函数就会报错。
但是在实际分析的过程中,其实我们更经常遇到的时多分类问题,这是我们就需要将多分类问题转化为二分类问题,将各个分类两两进行比较才能更好的解决数据不平衡的问题。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。