r 中的 SMOTE 显着减少了样本量

SMOTE in r reducing sample size significantly

我有一个包含大约 130000 条记录的数据集。记录分为两个class的目标变量,0 & 1。1只占总比例的0.09%。

我 运行 我在 Windows 10 上对 R-3.5.1 进行了分析。我使用 SMOTE 算法来处理这个不平衡的数据集。

我用下面的代码来处理不平衡的数据集

library(DMwR)
data_code$target=as.factor(data_code$target) #Converted to factor as 
# SMOTE works with factor data type
smoted_data <- SMOTE(target~., data_code, perc.over=100)

但是在执行代码后,我看到 0 的计数是 212,1 也是 212,这大大减少了我的样本 size.Can 你建议我如何处理这个不平衡的数据集SMOTE 不改变我的数据大小

您需要使用函数中可用的两个参数:perc.overperc.under

根据 SMOTE 中的 doc

The parameters perc.over and perc.under control the amount of over-sampling of the minority class and under-sampling of the majority classes, respectively.

所以:

perc.over will tipically be a number above 100. With this type of values, for each case in the orginal data set belonging to the minority class, perc.over/100 new examples of that class will be created

我看不到你的数据,但是,如果你的少数群体 class 有 100 个案例并且 perc.over=100,算法将从 class 生成 100/100 = 1 个新案例.

The parameter perc.under controls the proportion of cases of the majority class that will be randomly selected for the final "balanced" data set. This proportion is calculated with respect to the number of newly generated minority class cases.

因此,例如 perc.under=100 的值将 select 来自原始数据的大多数 class 与为少数 class 生成的相同观察量].

在我们的示例中,只生成了 1 个新案例,因此它只会添加另一个案例,从而产生一个包含 2 个案例的新数据集。

我建议为 perc.over 使用 100 以上的值,为 perc.under 使用更高的值(默认值为 100 和 200)。

请记住,您添加的新观察结果在您的少数 class 中 不真实 ,我会尽量控制这些。

数值示例:

set.seed(123)

data <- data.frame(var1 = sample(50),
                   var2 = sample(50),
                   out = as.factor(rbinom(50, 1, prob=0.1)))

table(data$out)
#  0  1 
# 43  7 # 50 rows total (original data)
smote_data <- DMwR::SMOTE(out ~ var1, data, perc.over = 200, perc.under = 400)
table(smote_data$out)
#  0  1 
# 56 21 # 77 rows total (smote data)

DMwR 包的替代方案是 smotefamily 包,它 不会 减少样本量。

相反,它从少数 class 中创建额外的数据(= 合成数据),并将其添加到原始数据中。因此 $data 参数中的输出已准备好进行训练。要调整合成数据量,可以修改参数dup_size。但是,默认 dup_size = 0 已经优化输出以实现平衡 classes,因此您无需对其进行调整。

Richard Richard 在 blog post 中对此进行了很好的解释。

示例代码(前两列有特征):

smote1 <- smotefamily::SMOTE(features, target, K = 4, dup_size = 0)
formula1 <- "class ~ ." %>% as.formula
model.smote <- caret::train(formula1, method = "rpart", smote1$data)
predictions.smote <- predict(model.smote, smote1$data[,1:2]) %>% print
cv2 <- confusionMatrix(smote1$data$class %>% as.factor, predictions.smote)

我发现 smotefamily::SMOTE 更方便,因为您不必调整两个参数 perc_overperc_under 直到获得可接受的样本量,而 DMwR::SMOTE 经常生成 NA 值。

我知道我来不及回答您的问题,但希望这个回答能对其他人有所帮助!您使用的包是 DMwR,它使用 combination of SMOTE and under-sampling of the majority class.

我建议您使用 smotefamily::SMOTE,因为它只会对少数 class 进行采样,这样您就不会失去多数 class 的观察结果。