使用DMwR包SMOTE函数报错:invalid 'labels'及NA引入问题排查
先还原你的操作和遇到的问题:
执行的代码:
# 安装DMwR包以实现SMOTE install.packages("DMwR") library(DMwR) smoted_data <- SMOTE(state~., deliq, perc.over=200, perc.under = 1600)
遇到的错误与警告:
Error in factor(newCases[, a], levels = 1:nlevels(data[, a]), labels = levels(data[, : invalid 'labels'; length 0 should be 1 or 2
In smote.exs(data[minExs, ], ncol(data), perc.over, k) : NAs introduced by coercion
结合你已经确认的「因子水平无0、无NA值」这些信息,我梳理了几个可能的原因和对应的解决思路:
因子变量存在未使用的空水平
即使你看不到0水平,有些因子变量可能在数据导入或处理过程中残留了空的水平(比如原本有这个类别,但当前数据集里没有对应观测)。SMOTE生成新样本时会尝试匹配所有因子水平,空水平会导致标签长度不匹配的错误。你可以用droplevels()清理数据集:deliq_clean <- droplevels(deliq) smoted_data <- SMOTE(state~., deliq_clean, perc.over=200, perc.under = 1600)数值变量被错误识别为因子类型
警告里的「NAs introduced by coercion」提示有强制类型转换失败的情况,大概率是某个本该是数值的变量被当成了因子。SMOTE在计算样本近邻时需要数值变量做距离计算,强行转换就会产生NA。你可以用str(deliq)查看所有变量的类型,把错误的因子转成数值:# 假设错误识别的变量叫var_x deliq$var_x <- as.numeric(as.character(deliq$var_x))过采样/欠采样参数设置过于极端
你设置的perc.over=200(少数类样本量扩充2倍)和perc.under=1600(多数类采样至少数类新样本量的16倍)可能过于激进,尤其是如果少数类原始样本量极少的话,SMOTE在生成新样本时容易出现逻辑漏洞。可以先调低参数测试:smoted_data <- SMOTE(state~., deliq, perc.over=100, perc.under = 500)DMwR包版本兼容性问题
不同版本的DMwR包对因子变量的处理逻辑可能有差异,旧版本可能存在这类边缘场景的bug。尝试更新包并重启R:update.packages("DMwR") # 重启R后重新加载包并运行SMOTE library(DMwR) smoted_data <- SMOTE(state~., deliq, perc.over=200, perc.under = 1600)
内容的提问来源于stack exchange,提问作者SKB

