如何在caret的rfe()中结合permimp置换重要性与cforest实现递归特征消除并解决运行报错
解决caret rfe结合permimp与cforest的报错问题
首先,你遇到的"invalid 'x' type in 'x && y'"错误主要是因为rank函数返回的数据格式不符合caret rfe的要求,另外代码中还有一些细节需要调整。下面是分步的解决方案,以及你需要确认的自定义函数细节:
一、修正当前代码的错误点
1. 调整rank函数的返回格式
caret的rfe要求rank函数返回一个行名为变量名、包含"Overall"列(重要性值)的数据框,不需要额外添加var列。你之前添加的var列会导致后续逻辑判断时类型不匹配,触发报错。
修正后的rank函数:
rank = function(object, x, y) { library(permimp) # 计算置换重要性 vimp <- permimp::permimp(object, conditional = TRUE, threshold = .95, do_check = FALSE) # 转换为数据框,行名是变量名,列是Overall vimp_df <- data.frame(Overall = vimp$values, row.names = names(vimp$values)) # 按重要性降序排序 vimp_df[order(vimp_df$Overall, decreasing = TRUE), , drop = FALSE] }
2. 简化fit函数,避免重复加载包
fit函数里不需要每次都调用library(party),你已经用了party::前缀,直接移除即可:
fit = function(x, y, first, last, ...){ tmp <- as.data.frame(x, stringsAsFactors = TRUE) tmp$y <- y party::cforest(y ~ ., data = tmp, control = party::cforest_unbiased(ntree = 50)) }
3. 明确pred函数的返回类型(可选但推荐)
对于回归任务,给predict添加type = "response"确保返回数值型结果:
pred = function(object, x) predict(object, newdata = x, type = "response")
二、确认你需要的自定义函数是否齐全
你已经定义了rfe所需的全部核心函数,不过再梳理一下:
summary:用defaultSummary完全没问题,它支持回归任务的RMSE、MAE等指标fit:负责训练cforest模型,你已经实现了pred:负责生成预测结果,修正后更稳健rank:负责计算变量重要性,修正格式后符合要求selectSize:用默认的pickSizeBest(选择性能最优的特征数量)selectVar:用默认的pickVars(根据重要性选择对应数量的特征)
这些函数覆盖了rfe运行所需的全部环节,不需要额外自定义其他函数了。
三、完整的可运行代码
library(caret) library(party) library(permimp) # 定义rfe所需的自定义函数列表 permimpRFE <- list( summary = defaultSummary, fit = function(x, y, first, last, ...){ tmp <- as.data.frame(x, stringsAsFactors = TRUE) tmp$y <- y party::cforest(y ~ ., data = tmp, control = party::cforest_unbiased(ntree = 50)) }, pred = function(object, x) predict(object, newdata = x, type = "response"), rank = function(object, x, y) { vimp <- permimp::permimp(object, conditional = TRUE, threshold = .95, do_check = FALSE) vimp_df <- data.frame(Overall = vimp$values, row.names = names(vimp$values)) vimp_df[order(vimp_df$Overall, decreasing = TRUE), , drop = FALSE] }, selectSize = pickSizeBest, selectVar = pickVars ) # 设置rfe控制参数 contr <- caret::rfeControl( functions = permimpRFE, method = "repeatedcv", number = 3, repeats = 2, saveDetails = TRUE ) # 准备数据 dat <- as.data.frame(ChickWeight)[1:50,] preds <- dat[,2:4] response <- dat[,1] # 运行递归特征消除 set.seed(43, kind = "Mersenne-Twister", normal.kind = "Inversion") results <- caret::rfe( x = preds, y = response, sizes = c(1:3), metric = "RMSE", rfeControl = contr ) # 查看结果 print(results)
四、错误原因说明
你之前的rank函数中,当特征数量为1时手动添加var列,导致返回的数据框同时包含行名和var列,caret内部在进行逻辑判断(比如筛选特征时),会把这个额外的列当成变量处理,引发类型不匹配的错误。移除var列,让行名作为变量标识,就解决了这个问题。
内容的提问来源于stack exchange,提问作者yPennylane
相关产品推荐
相关产品推荐

