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

Posted

技术标签:

【中文标题】在 CARET k-fold 交叉验证分类中更改 SMOTE 参数【英文标题】:Change SMOTE parameters inside CARET k-fold cross-validation classification 【发布时间】:2016-02-25 21:23:55 【问题描述】:

我有一个分类问题,需要预测一个非常倾斜的类(例如,要预测 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,我该怎么做?

非常感谢。

编辑:

实际上我意识到我可以在上述函数的“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, perc.over = 1200, perc.under = 100)
              list(x = dat[, !grepl(".y", colnames(dat), fixed = TRUE)],
                   y = dat$.y)
              ,
            first = TRUE)

【问题讨论】:

【参考方案1】:

我不确定你是否理解了你不理解的内容,但这里试图澄清这段代码的作用。

smotest 对象被创建为列表,因为它是 trainControl 函数的参数 sampling 必须表示的方式。此列表的第一个元素是 name,仅用于显示目的。第二个,func,是实际的采样函数。第三个,first,是一个逻辑值,指示是否必须在预处理步骤之前或之后进行采样。

元素func 在这里只是SMOTE 函数的包装。在这个包装器中,第 3 行在这里,因为只有 data.frame 可以传递给 SMOTE 函数。添加第 4 行是因为在 SMOTE 中使用了与 data.frame 组合的 formula,而不是一对 x y。此处第 6 行是为了确保将适当的格式返回到 trainControl

而且,回答你最后一个问题:是的,你可以按照你的建议为SMOTE设置额外的参数。

【讨论】:

感谢您的回答,但是,当我尝试上面发布的内容(即添加参数)时,它返回错误“parse_sampling(trControl$sampling) 中的错误:该采样方案不在插入符号中构建-在图书馆”。但是,当我尝试不使用这些新参数时,它可以工作。 奇怪...因为只有当给定 trainControl 的采样参数是字符时才会提示此错误... 我想我刚刚意识到我的错误。我忘了清理我没有在模型中输入的训练数据集中的变量,例如我有文本变量的原因。谢谢你让我意识到这一点! 我会添加一些对某些人来说可能很明显的东西,但我花了一段时间寻找它。一旦创建了包装函数(例如:smotest),它必须被传递给 trainControl 中的参数采样,用不带引号的“smote”代替:trainControl(sampling=smotest) 而不是 trainControl(sampling="smote")跨度>

以上是关于在 CARET k-fold 交叉验证分类中更改 SMOTE 参数的主要内容,如果未能解决你的问题,请参考以下文章

我在 k-fold cross_validation 中使用相同的 Tfidf 词汇吗

如何在朴素贝叶斯分类器中使用 k 折交叉验证?

Spark K-fold 交叉验证

在 k-Fold 交叉验证中,是不是为 Sklearn 中的每个折叠启动了一个新模型?

用于文本分类的神经网络中的 K-Fold

交叉验证(cross validation)是什么?K折交叉验证(k-fold crossValidation)是什么?