You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:06:03