如何在recipe工作流中调优step_impute_knn的参数?
如何自动调优
step_impute_knn的参数 问题描述
我想用recipe包的step_impute_knn填充数据缺失值,测试默认参数(neighbors = 5、nthread = 1、eps = 1e-08)后,填充的数值变量均值和标准差与原始数据接近,但想找到最优参数组合,不想手动调参,也没找到简单的实现方法。
样本数据
train <- structure(list(PassengerId = c("0001_01", "0002_01", "0003_01", "0003_02", "0004_01", "0005_01"), HomePlanet = c("Europa", "Earth", "Europa", "Europa", "Earth", NA), CryoSleep = c("False", "False", "False", "False", "False", "False"), Cabin = c("B/0/P", "F/0/S", "A/0/S", "A/0/S", "F/1/S", "F/0/P"), Destination = c("TRAPPIST-1e", "TRAPPIST-1e", "TRAPPIST-1e", "TRAPPIST-1e", "TRAPPIST-1e", "PSO J318.5-22" ), Age = c(39, 24, 58, 33, 16, 44), VIP = c("False", "False", "True", "False", "False", "False"), RoomService = c(0, 109, 43, 0, 303, 0), FoodCourt = c(0, 9, 3576, 1283, 70, 483), ShoppingMall = c(0, 25, 0, 371, 151, 0), Spa = c(0, 549, 6715, 3329, 565, 291), VRDeck = c(0, 44, 49, 193, 2, 0), Name = c("Maham Ofracculy", "Juanna Vines", "Altark Susent", "Solam Susent", "Willy Santantines", "Sandie Hinetthews" ), Transported = c("False", "True", "False", "False", "True", "True")), row.names = c(NA, 6L), class = "data.frame")
当前代码
train_no_na <- train %>% na.omit() imp_knn_blueprint <- recipe(Transported ~ ., data = train_no_na) %>% step_impute_knn(recipe = ., HomePlanet, impute_with = imp_vars(.), neighbors = 5, options = list(nthread = 1, eps = 1e-08)) imp_knn_prep <- prep(imp_knn_blueprint, training = train_no_na) imp_knn_5 <- bake(imp_knn_prep, new_data = train)
自动调参解决方案
结合tidymodels生态的tune包可以实现简单的自动调参,步骤如下:
1. 加载所需包
library(tidymodels) # 整合recipes、tune、workflows等工具 library(tidyverse)
2. 定义带可调参数的预处理流程
将需要调优的参数标记为tune(),nthread为并行数,若无需调优可固定:
tune_recipe <- recipe(Transported ~ ., data = train) %>% # KNN需要数值型输入,先编码分类变量 step_dummy(all_nominal_predictors(), -all_outcomes()) %>% step_impute_knn(HomePlanet, impute_with = imp_vars(all_predictors()), neighbors = tune(), # 标记为待调参数 options = list(nthread = 1, eps = tune())) # eps也标记为待调
3. 创建工作流(结合预处理与模型)
用逻辑回归作为评估模型(适配分类目标Transported):
# 定义基础模型 log_reg <- logistic_reg() %>% set_engine("glm") %>% set_mode("classification") # 绑定预处理流程与模型 wf <- workflow() %>% add_recipe(tune_recipe) %>% add_model(log_reg)
4. 定义参数网格
指定待调参数的范围与取值数量:
param_grid <- grid_regular( neighbors(range = c(3, 10)), # 邻居数范围:3-10 eps(range = c(1e-10, 1e-6)), # eps范围:1e-10到1e-6 levels = 3 # 每个参数取3个值,生成9种组合 )
5. 交叉验证拆分数据
用5折交叉验证评估参数效果:
set.seed(123) # 固定随机种子保证结果可复现 cv_folds <- vfold_cv(train, v = 5)
6. 运行调参
tune_results <- tune_grid( wf, resamples = cv_folds, grid = param_grid, metrics = metric_set(accuracy) # 用准确率作为评估指标 )
7. 查看并选择最优参数
# 查看效果Top3的参数组合 show_best(tune_results, metric = "accuracy") # 提取最优参数 best_params <- select_best(tune_results, metric = "accuracy")
8. 用最优参数训练并填充数据
# 更新工作流为最优参数配置 final_wf <- finalize_workflow(wf, best_params) # 训练最终预处理流程 final_prep <- fit(final_wf, data = train) # 生成填充缺失值后的数据集 imputed_train <- final_prep %>% extract_preprocessor() %>% bake(new_data = train)
补充说明
- 若仅需调优
neighbors,可将eps设为固定值(如默认的1e-08),无需标记为tune()。 - 可根据需求替换评估指标,比如用
roc_auc替代accuracy。 - 样本数据量较小,实际场景建议用更大数据集或调整交叉验证折数。
内容的提问来源于stack exchange,提问作者GreenManXY
相关产品推荐
相关产品推荐

