使用tidymodels调优KNN模型后,loss_accuracy无变量重要性结果
解决DALEX model_parts计算KNN分类器变量重要性为空的问题
问题根源
loss_accuracy是为回归任务设计的损失函数,不适用于分类任务。分类任务下,需要使用衡量"性能下降"的损失函数,比如loss_one_minus_accuracy(即1 - 准确率),因为model_parts通过对比移除变量前后的损失变化来计算重要性,分类任务中准确率越高性能越好,转化为损失后,移除重要变量会导致损失上升,这样才能得到有效的重要性数值。
修正步骤
- 替换损失函数为分类任务专用的
loss_one_minus_accuracy - 确保
explain_tidymodels的输入数据和标签格式正确
修改后的完整代码
library(tidyverse) library(tidymodels) library(DALEXtra) tidymodels_prefer() df <- iris # 数据拆分 set.seed(2023) splits <- initial_split(df, strata = Species, prop = 4/5) df_train <- training(splits) df_test <- testing(splits) # 构建工作流 df_rec <- recipe(Species ~ ., data = df_train) knn_model <- nearest_neighbor(neighbors = tune()) %>% set_engine("kknn") %>% set_mode("classification") df_wflow <- workflow() %>% add_model(knn_model) %>% add_recipe(df_rec) # 贝叶斯调优 set.seed(2023) knn_res <- df_wflow %>% tune_bayes( metrics = metric_set(accuracy), resamples = vfold_cv(df_train, strata = "Species", v = 2), control = control_bayes(verbose = TRUE, save_pred = TRUE)) # 拟合最优模型 best_k <- knn_res %>% select_best("accuracy") knn_mod <- df_wflow %>% finalize_workflow(best_k) %>% fit(df_train) # 创建解释器对象 prepped_train <- df_rec %>% prep() %>% bake(new_data = NULL) knn_exp <- explain_tidymodels( model = extract_fit_parsnip(knn_mod), data = prepped_train %>% select(all_predictors()), y = prepped_train$Species, verbose = FALSE ) # 计算变量重要性(使用分类任务损失函数) set.seed(2023) vip <- model_parts( knn_exp, type = "variable_importance", loss_function = loss_one_minus_accuracy, B = 20 # 可选:增加迭代次数提升稳定性 ) plot(vip)
额外说明
loss_one_minus_accuracy会将准确率转化为"损失":移除重要变量时,1-准确率会上升,变量重要性得分即为该上升值,得分越高说明变量越重要。- 若需要自定义分类损失函数,可参考DALEX文档编写符合要求的函数(输入为真实标签和预测标签,输出为标量损失值)。
内容的提问来源于stack exchange,提问作者bioblackgeorge
相关产品推荐
相关产品推荐

