我正在处理一个二元分类问题,数据集不平衡。我希望创建一个新的、更平衡的数据集,每个类别的观测值占50%。为此,我在R中使用了DMwR库
提供的SMOTE算法。
在新的数据集中,我希望保持多数类的观测值不变。
然而,我遇到了两个问题:
- SMOTE减少或增加了多数类的观测值数量(我只希望增加少数类的数量)。
- SMOTE生成的一些观测值包含NA值。
假设我有20个观测值:多数类有17个观测值,而少数类只有3个观测值。这里是我的代码:
library(DMwR)library(dplyr)sample_data <- data.frame(matrix(rnorm(200), nrow=20))sample_data[1:17,"X10"] <- 0sample_data[18:20,"X10"] <- 1sample_data[,ncol(sample_data)] <- factor(sample_data[,ncol(sample_data)], levels = c('1','0'), labels = c('Yes','No'))newDataSet <- SMOTE(X10 ~., sample_data, perc.over = 400, perc.under = 100)
在我的代码中,我设置了perc.over = 400
来创建12个新的少数类观测值,并设置了perc.under = 100
以保持多数类不变。
然而,当我检查newDataSet时,我发现SMOTE将多数类的数量从17减少到了12。此外,一些生成的观测值包含NA值。
下图显示了获得的结果:
回答:
根据?SMOTE
的说明:
对于原始数据集中属于少数类的每个案例,将创建perc.over/100个该类别的新示例。
此外:
例如,如果为少数类生成了200个新示例,perc.under值为100将从原始数据集中随机选择正好200个属于多数类的案例,作为最终数据集的一部分。
因此,在你的情况下,你正在:
- 创建12个新的
Yes
(除了原始的那些)。 - 随机选择12个
No
。
新的Yes
中包含NA可能与SMOTE
的k
参数有关。根据?SMOTE
的说明:
k:一个数字,表示用于生成少数类新示例的最近邻居的数量。
其默认值为5,但在你的原始数据中只有3个Yes
。设置k = 2
似乎可以解决这个问题。
最后的评论:为了达到你的目标,我会仅使用SMOTE
来增加少数类的观测值数量(使用perc.over
= 400或500)。然后,你可以将它们与多数类的原始观测值结合起来。