在CARET k-fold交叉验证分类中更改SMOTE参数

5
我有一个分类问题,需要预测一个非常倾斜的类(例如,90%/10%不平衡的二进制变量)。
为了解决这个问题,我想使用SMOTE方法来过采样这个类变量。然而,正如我在这里读到的(http://www.marcoaltini.com/blog/dealing-with-imbalanced-data-undersampling-oversampling-and-proper-cross-validation),最佳实践是在k-fold循环内使用SMOTE以避免过拟合。
由于我正在使用caret包执行我的分析,我参考了这个链接(http://topepo.github.io/caret/sampling.html)。我完全理解所有内容,但最后一部分讲解如何更改SMOTE参数时我不太清楚。
smotest <- list(name = "SMOTE with more neighbors!",
            func = function (x, y) {
              library(DMwR)
              dat <- if (is.data.frame(x)) x else as.data.frame(x)
              dat$.y <- y
              dat <- SMOTE(.y ~ ., data = dat, k = 10)
              list(x = dat[, !grepl(".y", colnames(dat), fixed = TRUE)],
                   y = dat$.y)
              },
            first = TRUE)

我简单地不理解这个。有人能解释一下吗?假设我想包括SMOTE参数perc.over、k和perc.under,我该如何做?
非常感谢。
编辑:
实际上,我意识到我可能只需在上述函数中添加这些参数即可,例如:
smotest <- list(name = "SMOTE with more neighbors!",
            func = function (x, y) {
              library(DMwR)
              dat <- if (is.data.frame(x)) x else as.data.frame(x)
              dat$.y <- y
              dat <- SMOTE(.y ~ ., data = dat, k = 10, perc.over = 1200, perc.under = 100)
              list(x = dat[, !grepl(".y", colnames(dat), fixed = TRUE)],
                   y = dat$.y)
              },
            first = TRUE)
1个回答

1
我不确定你不理解的是什么,但这里尝试澄清这段代码中所做的事情。 smotest对象被创建为列表,因为它是必须表示为trainControl函数的sampling参数的方式。这个列表的第一个元素是一个name,仅用于显示目的。第二个元素func是实际的抽样函数。第三个元素first是一个逻辑值,指示抽样是否在预处理步骤之前或之后完成。
此处的func元素只是SMOTE函数的包装器。在这个包装器中,第3行出现是因为只有data.frame可以传递给SMOTE函数。第4行添加是因为在SMOTE中使用了一个formuladata.frame结合,而不是一对xy。第6行在这里是为了确保适当的格式返回给trainControl

回答你的最后一个问题:是的,你可以像你所提出的那样设置额外的参数给 SMOTE


谢谢你的回答,然而,当我尝试上面发布的内容时,即添加参数时,它会返回一个错误信息:“在parse_sampling(trControl$sampling)中出现错误:该抽样方案不在caret的内置库中”。然而,当我尝试不使用这些新参数时,它可以正常工作。 - user2715157
1
奇怪...因为只有在将sampling参数传递给trainControl的时候才应该出现这个错误,而且它必须是一个字符类型... - Pop
我想我刚刚意识到了我的错误。我忘记清理训练数据集中那些我没有输入模型的变量,比如文本变量。谢谢你让我意识到这一点! - user2715157
1
我想补充一些对有些人来说可能很明显,但我花了很长时间才找到的东西。例如,一旦创建了包装函数(例如:smotest),它必须被传递给trainControl中的sampling参数,用不带引号的"smote"替换它,就像这样:trainControl(sampling=smotest),而不是trainControl(sampling="smote")。 - Ivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接