这篇文章将为大家详细讲解有关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
关于R语言项目中出现数据不平衡如何解决就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。