r - mlr:比较 getFilteredFeatures 和generateFilterValuesData 的输出时出现意外结果

标签 r mlr

我使用两种不同的方法来获取过滤器选择的功能。我期望这些方法返回相同的值,但它们没有这样做,我不明白为什么。使用第二种方法的原因是我可以访问用于选择特征的分数,而不仅仅是所选特征的名称。

该过滤器是一个单变量模型评分过滤器,使用 Cox 模型来衡量性能,并选择前 5 个特征。我创建了一个重新采样实例,以便两种方法在每个折叠中使用相同的样本。

第一种方法是通常的方法 - 使用 makeFilterWrapper 将过滤器包装在 Lasso 模型周围,并通过 resample 的提取选项调用 getFilteredFeatures。我的理解是 getFilteredFeatures 返回过滤器选择的特征,然后再传递给 Lasso 模型。

在第二种方法中,我使用subsetTask 创建 getFilteredFeatures 将在每个 CV 折叠中使用的相同子任务,然后调用generateFilterValuesData 来获取过滤器生成的值。每个折叠中此列表中的前 5 个值应与每个折叠中的 getFilteredFeatures 返回的值匹配,但事实并非如此。这是为什么?

library(survival)
#> Warning: package 'survival' was built under R version 3.5.3
library(mlr)
#> Loading required package: ParamHelpers

data(veteran)
task_id = "VET"
vet.task <- makeSurvTask(id = task_id, data = veteran, target = c("time", "status"))
vet.task <- createDummyFeatures(vet.task)

inner = makeResampleDesc("CV", iters=2, stratify=TRUE)  # Tuning
outer = makeResampleDesc("CV", iters=2, stratify=TRUE)  # Benchmarking

set.seed(24601)
resinst = makeResampleInstance(desc=outer, task=vet.task)

cox.lrn <- makeLearner(cl="surv.coxph", id = "coxph", predict.type="response")
lasso.lrn  <- makeLearner(cl="surv.cvglmnet", id = "lasso", predict.type="response", alpha = 1, nfolds=5)

filt.uni.lrn = 
  makeFilterWrapper(
    lasso.lrn, 
    fw.method="univariate.model.score", 
    perf.learner=cox.lrn,
    fw.abs = 5
  )
#Method 1
res = resample(learner=filt.uni.lrn, task=vet.task, resampling=resinst, measures=list(cindex), extract=getFilteredFeatures)
#> Resampling: cross-validation
#> Measures:             cindex
#> [Resample] iter 1:    0.7458904
#> [Resample] iter 2:    0.6575813
#> 
#> Aggregated Result: cindex.test.mean=0.7017359
#> 
res$extract
#> [[1]]
#> [1] "karno"              "diagtime"           "celltype.squamous" 
#> [4] "celltype.smallcell" "celltype.adeno"    
#> 
#> [[2]]
#> [1] "karno"              "diagtime"           "age"               
#> [4] "celltype.smallcell" "celltype.large"

#Method 2
for (i in 1:2) {
  subt = subsetTask(task=vet.task, subset = resinst$train.inds[[i]])
  print(generateFilterValuesData(subt, method="univariate.model.score", perf.learner=cox.lrn))
}
#> FilterValues:
#> Task: VET
#>                 name    type                 method     value
#> 2              karno numeric univariate.model.score 0.6387665
#> 7 celltype.smallcell numeric univariate.model.score 0.6219512
#> 8     celltype.adeno numeric univariate.model.score 0.5700000
#> 5              prior numeric univariate.model.score 0.5456522
#> 6  celltype.squamous numeric univariate.model.score 0.5316206
#> 4                age numeric univariate.model.score 0.5104603
#> 1                trt numeric univariate.model.score 0.5063830
#> 3           diagtime numeric univariate.model.score 0.4760956
#> 9     celltype.large numeric univariate.model.score 0.3766520
#> FilterValues:
#> Task: VET
#>                 name    type                 method     value
#> 2              karno numeric univariate.model.score 0.6931330
#> 9     celltype.large numeric univariate.model.score 0.6264822
#> 7 celltype.smallcell numeric univariate.model.score 0.5269058
#> 6  celltype.squamous numeric univariate.model.score 0.5081967
#> 8     celltype.adeno numeric univariate.model.score 0.5064655
#> 4                age numeric univariate.model.score 0.4980237
#> 1                trt numeric univariate.model.score 0.4646018
#> 3           diagtime numeric univariate.model.score 0.4547619
#> 5              prior numeric univariate.model.score 0.4527897

reprex package (v0.3.0) 于 2019 年 10 月 2 日创建

最佳答案

你在这里混淆了两件事。

情况 1(嵌套重采样)

在嵌套重采样的外部折叠中选择的特征是根据内部重采样的最佳性能折叠确定的。

  1. 折叠 1(内部) -> 使用过滤器计算前 5 个特征 -> 计算模型性能
  2. 折叠 2(内部) -> 使用过滤器计算前 5 个特征 -> 计算模型性能
  3. 检查哪个内折叠具有最佳性能(假设折叠 1)-> 从此折叠中提取前 5 个特征,以便在外折叠中进行模型拟合

因此,过滤器值实际上不会在外层折叠上计算,而只会在内层折叠上计算。您基本上是在问“根据内循环的过滤器给我前 5 个特征,并仅在外层折叠中训练模型”。由于过滤器值不会在外层再次重新计算,因此您只能返回要素名称,而没有值。

情况2(直接计算过滤器值)

在这里,您直接在两个外折上生成过滤器值。由于观察结果与嵌套重采样中的内部折叠不同(情况 1),因此您的 Lasso 学习器将得出不同的过滤器分数(模型拟合发生在不同的观察结果中),并且可能会产生不同的排名。


IIUC 您的想法是,为嵌套重采样设置中的每个外层折叠再次生成过滤器值。事实并非如此,也不会带来任何好处,因为在内部折叠的优化过程中已经选择了适合模型的特征。

对于外层折叠,模型仅使用内循环建议的选定特征进行训练。同样的逻辑也适用于调整:“给我内循环所有折叠的最佳超参数(我会告诉你如何做),然后使用这些设置在外折叠上拟合模型”。

也许这有助于将此逻辑转移到调整中:您也不会在每个外层折叠上独立调用 tuneParams() 并假设您得到的超参数与内部嵌套重采样优化返回的超参数相同想出来,不是吗?

关于r - mlr:比较 getFilteredFeatures 和generateFilterValuesData 的输出时出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58201011/

相关文章:

r - 在 azure-ml : Where can stdout and stderr logs be found? 中调试 R 脚本(或者为什么它们是空的?)

r - Xgboost 在 R 中使用 mlr 实现生存

r - 如何解释通过 randomForestSRC::vimp 生成的变量重要性图?

R mlr - 从训练数据子集和整个测试数据(不是整个训练数据)创建学习曲线?

r 单元格中的热图值 - 包 ComplexHeatmap

r - 在 RMarkdown 的输出中显示代码块名称

r - 绘制两个 xts 对象

r - 将索引函数应用于矩阵行中的每个值

r - 如何在 R 中使用 mlr 保存水模型?