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

mlr3中搜索空间参数依赖配置、调优特征查询及filter.nfeat调参与特征选择的对比咨询

问题1:如何设置依赖于K的D值,保证D≤K且为指定比例

你之前用.extra_trafo的思路方向对,但用法不对。在mlr3里要实现参数值的动态依赖,我们有两种靠谱的方式:

方式一:用trafo函数过滤不合法配置

通过转换函数,让网格搜索自动排除不符合D∈{10%,25%,50%,100%}*K且D≤K的组合:

searchspace = ps(
  importance.filter.nfeat = p_int(lower = 1, upper = length(task$feature_names), id = "K"),
  classif.ranger.max.depth = p_int(lower = 1, upper = length(task$feature_names), id = "D")
)

# 添加转换规则,过滤不合法的(K,D)对
searchspace$trafo = function(x, param_set) {
  k = x$K
  # 计算当前K对应的合法D候选值,取整数且≥1
  valid_d = round(k * c(0.1, 0.25, 0.5, 1))
  valid_d = unique(valid_d[valid_d >= 1 & valid_d <= k])
  
  # 如果当前D不在合法列表里,就排除这个配置
  if (!(x$D %in% valid_d)) {
    return(NULL)
  }
  x
}

方式二:手动生成所有合法配置(更直观)

直接提前生成所有符合要求的(K,D)组合,让网格搜索只遍历这些合法项,避免过滤逻辑:

# 生成所有K的可能值
all_K = seq(1, length(task$feature_names))

# 对每个K生成对应的合法D值
valid_configs = lapply(all_K, function(k) {
  d_options = round(k * c(0.1, 0.25, 0.5, 1))
  d_options = unique(d_options[d_options >= 1 & d_options <= k])
  # 把每个(K,D)对转成配置列表
  lapply(d_options, function(d) {
    list(
      importance.filter.nfeat = k,
      classif.ranger.max.depth = d
    )
  })
})
valid_configs = unlist(valid_configs, recursive = FALSE)

# 直接把合法配置传给调优实例
inst1 = TuningInstanceMultiCrit$new(
  task = task,
  learner = graph_learner,
  resampling = rsmp("cv"),
  measures = msrs(c("classif.ce","classif.bacc","classif.mcc")),
  terminator = trm("evals", n_evals = 50),
  search_space = valid_configs
)

问题2:调优后怎么看实际用的特征?是不是按重要性选的?

查看实际使用的特征

有两种简单的方法可以提取调优后模型用到的特征:

方法一:从最优配置训练的模型中提取

# 获取最优参数配置
best_config = inst1$result_learner_param_vals
# 用最优配置训练完整的图学习器
graph_learner$param_set$values = best_config
graph_learner$train(task)
# 提取filter步骤的筛选结果
filter_step = graph_learner$graph$ops$filter
selected_features = filter_step$state$selected_features
print(selected_features)

方法二:从调优存档中提取(需提前保存模型)

如果创建调优实例时加了store_models = TRUE,可以直接从存档里拿:

# 创建实例时开启模型保存
inst1 = TuningInstanceMultiCrit$new(
  task = task,
  learner = graph_learner,
  resampling = rsmp("cv"),
  measures = msrs(c("classif.ce","classif.bacc","classif.mcc")),
  terminator = trm("evals", n_evals = 50),
  search_space = valid_configs,
  store_models = TRUE
)

# 找到性能最优的模型索引(这里以分类错误率最低为例)
best_idx = which.min(inst1$archive$data$classif.ce)
# 提取对应模型的筛选特征
best_model = inst1$archive$learners[[best_idx]]
selected_features = best_model$graph$ops$filter$state$selected_features
print(selected_features)

是否按重要性排序筛选?

是的!你用的flt("importance")会基于ranger的impurity重要性分数,把特征从高到低排序,然后取前importance.filter.nfeat个。可以用下面的代码验证:

# 单独训练ranger获取特征重要性
ranger_lrn = lrn("classif.ranger", importance = "impurity", predict_type = "prob")
ranger_lrn$train(task)
importance_scores = ranger_lrn$importance()
# 按重要性降序排列特征
sorted_features = names(sort(importance_scores, decreasing = TRUE))
# 对比筛选后的特征,应该是前K个
print(all.equal(selected_features, sorted_features[1:best_config$importance.filter.nfeat]))

问题3:调参importance.filter.nfeat与特征选择的关系,实践中优先选哪个

核心区别

  1. importance.filter.nfeat调参

    • 本质是固定逻辑的Top-K筛选:先按特征重要性排序,再调选多少个(K)作为参数。
    • 优点:速度极快,不需要遍历所有特征子集,适合高维度数据快速缩小范围;逻辑清晰,解释性强。
    • 缺点:只能选连续的Top-K特征,无法发现“非Top-K但组合起来效果更好”的特征子集。
  2. 特征选择(比如你用的RFE)

    • 本质是搜索最优特征子集:可以是任意组合的特征,不一定是Top-K。
    • 优点:能找到更灵活的特征组合,可能挖掘到重要性低但互补的特征,最终性能可能更优。
    • 缺点:计算成本极高,特征数量多的时候搜索空间呈指数级增长,耗时很长。

实践选择建议

  • 优先用importance.filter.nfeat调参的场景:

    • 数据维度极高(上千个特征),特征选择的计算成本无法承受;
    • 更关注模型解释性,需要清晰的特征筛选逻辑;
    • 作为特征选择的前置步骤:先通过Top-K调参把特征从几百降到几十,再做特征选择,平衡效率和性能。
  • 优先用特征选择的场景:

    • 数据维度适中(几百个以内),计算资源充足;
    • 追求最优预测性能,愿意花费时间搜索;
    • 业务场景需要特定特征子集(比如排除某些无关特征,而非只按重要性筛选)。
  • 推荐结合使用:
    大部分场景下,先通过Top-K调参缩小特征范围,再用RFE等方法在子集中搜索最优组合,既能节省时间,又能得到不错的性能。


内容的提问来源于stack exchange,提问作者LengJH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 11:07:29