在tidymodels中用ranger拟合随机森林时权重分配报错求助
问题分析与解决
你遇到的variable lengths differ错误,核心原因是对weights参数的理解偏差——这个参数是用来给**每一条训练样本(行)**分配权重的,不是给预测变量(列)设置权重的。你传的wts = c(1,2)只有2个元素,但train_try有105行左右,长度不匹配,所以触发了报错。
下面针对你想给Petal.Length(权重1)和Petal.Width(权重2)设置特征权重的需求,提供两种可行的解决方案:
方法1:手动缩放特征(简单直观)
既然你认为Petal.Width的重要性是前者的两倍,直接将Petal.Width的值乘以2,就能在模型训练中放大它的影响力,这是最容易理解和实现的方式。
修改后的完整代码:
library(tidyverse) library(tidymodels) library(Metrics) set.seed(12) split_try <- initial_split(iris, prop = 0.7) train_try <- split_try %>% training() %>% na.omit() test_try <- split_try %>% testing() %>% na.omit() # 给训练集和测试集的Petal.Width加权(乘以2) train_weighted <- train_try %>% mutate(Petal.Width_weighted = Petal.Width * 2) test_weighted <- test_try %>% mutate(Petal.Width_weighted = Petal.Width * 2) col_try <- names(train_try)[1:2] ranger_try <- vector('list', length(col_try)) output_try <- vector('list', length(col_try)) # 修正原代码长度错误 for (i in seq_along(col_try)) { ranger_try[[i]] <- rand_forest(trees = 10, mode = "regression") %>% set_engine("ranger") %>% # 使用加权后的Petal.Width替代原变量 fit(as.formula(paste(col_try[i], "~ Petal.Length + Petal.Width_weighted")), data = train_weighted) output_try[[i]] <- predict(ranger_try[[i]], test_weighted) names(output_try[[i]]) <- paste0(col_try[i],"_pred") test_try <- cbind(test_try, output_try[[i]]) } # 查看最终结果 head(test_try)
方法2:使用ranger的feature_weights参数(优雅适配需求)
ranger包本身支持给特征设置权重,但需要搭配extratrees分裂规则,并且在set_engine中指定feature_weights参数。这种方法不需要手动修改特征值,更贴合"特征权重"的需求。
修改后的完整代码:
library(tidyverse) library(tidymodels) library(Metrics) set.seed(12) split_try <- initial_split(iris, prop = 0.7) train_try <- split_try %>% training() %>% na.omit() test_try <- split_try %>% testing() %>% na.omit() col_try <- names(train_try)[1:2] ranger_try <- vector('list', length(col_try)) output_try <- vector('list', length(col_try)) # 修正原代码长度错误 # 定义特征权重:对应公式中预测变量的顺序(Petal.Length=1,Petal.Width=2) feat_wts <- c(1, 2) for (i in seq_along(col_try)) { ranger_try[[i]] <- rand_forest(trees = 10, mode = "regression") %>% set_engine("ranger", splitrule = "extratrees", # 必须使用该分裂规则才能支持feature_weights feature_weights = feat_wts) %>% fit(as.formula(paste(col_try[i], "~ Petal.Length + Petal.Width")), data = train_try) output_try[[i]] <- predict(ranger_try[[i]], test_try) names(output_try[[i]]) <- paste0(col_try[i],"_pred") test_try <- cbind(test_try, output_try[[i]]) } # 查看最终结果 head(test_try)
额外修正说明
原代码中output_try <- vector('list', length(test_try))是错误的:length(test_try)返回的是数据框的列数(5),但你只需要对应2个因变量的模型结果,所以应该改成length(col_try)。
两种方法都能实现你给预测变量分配权重的需求,方法1适配所有模型类型,方法2是ranger特有的优化方案,可根据个人偏好选择。
内容的提问来源于stack exchange,提问作者jaykay
相关产品推荐
相关产品推荐

