在我的工作项目中,我使用插入符号包中的rfe函数来进行递归功能消除。我用一个玩具例子来说明我的观点。
library(mlbench)
library(caret)
data(PimaIndiansDiabetes)
rfFuncs$summary <- twoClassSummary
control <- rfeControl(functions=rfFuncs, method="cv", number=10)
results <- rfe(PimaIndiansDiabetes[,1:8], PimaIndiansDiabetes[,9], sizes=c(1:8), rfeControl=control, metric="ROC")
所选的最佳变量基于过程中具有最高auroc且可以由results$optVariables
检索的那些变量。
但是,我要做的是使用“ 1个标准错误规则”来选择较少的功能(下面的代码)。识别出的变量数为4。
# auc that is 1-se from the highest auc
df.results = results$results %>% dplyr::mutate(ROCSE = ROCSD/sqrt(10-1))
idx = which.max(df.results$ROC)
ROC.1se = df.results$ROC[idx] - df.results$ROCSE[idx]
# plot ROC vs feature size
g = ggplot(df.results, aes(x=Variables, y=ROC)) +
geom_errorbar(aes(ymin=ROC-ROCSE, ymax=ROC+ROCSE),
width=.2, alpha=0.4, linetype=1) +
geom_line() +
geom_point()+
scale_color_brewer(palette="Paired")+
geom_hline(yintercept = ROC.1se)+
labs(x ="Number of Variables", y = "AUROC")
print(g)
我确定的变量数为4。现在,我需要知道哪个四个变量。我在下面做了:
results$variables %>% filter(Variables==4) %>% distinct(var)
它显示5个变量!
有人知道我如何检索这些变量吗?基本上,它适用于获取任意数量的所选变量的那些变量。
非常感谢!
答案 0 :(得分:1)
单行答案
如果您知道只希望从rfe重采样中获得最好的4个变量,则将为您提供所需的内容。
results$optVariables[1:4]
# [1] "glucose" "mass" "age" "pregnant"
dplyr
答案
# results$variables %>%
# group_by(var) %>%
# summarize(Overall = mean(Overall)) %>%
# arrange(-Overall)
#
# A tibble: 8 x 2
# var Overall
# <chr> <dbl>
# 1 glucose 34.2
# 2 mass 15.8
# 3 age 12.7
# 4 pregnant 7.92
# 5 pedigree 5.09
# 6 insulin 4.87
# 7 triceps 3.25
# 8 pressure 1.95
为什么您的尝试给出了超过4个变量
您正在过滤40个观测值。最佳4个变量的10倍。最好的4个变量在每次折叠中并不总是相同。因此,要在重新采样中获得最佳的前4个变量,您需要像上面的代码一样在各个方面平均其性能。更简单的是,optVariables
中的变量是按此顺序排序的,因此您只需获取前4个即可(就像我的单行答案一样)。这种情况的证明需要深入研究源代码(如下所示)。
详细信息:深入研究源代码
处理从rfe
之类的函数返回的对象的第一件事是尝试使用print
,summary
或plot
之类的函数。通常会存在自定义方法,这些方法将为您提供非常有用的信息。例如...
# Run rfe with a random seed
# library(dplyr)
# library(mlbench)
# library(caret)
# data(PimaIndiansDiabetes)
# rfFuncs$summary <- twoClassSummary
# control <- rfeControl(functions=rfFuncs, method="cv", number=10)
# set.seed(1)
# results <- rfe(PimaIndiansDiabetes[,1:8], PimaIndiansDiabetes[,9], sizes=c(1:8),
# rfeControl=control, metric="ROC")
#
# The next two lines identical...
results
print(results)
# Recursive feature selection
#
# Outer resampling method: Cross-Validated (10 fold)
#
# Resampling performance over subset size:
#
# Variables ROC Sens Spec ROCSD SensSD SpecSD Selected
# 1 0.7250 0.870 0.4071 0.07300 0.07134 0.10322
# 2 0.7842 0.840 0.5677 0.04690 0.04989 0.05177
# 3 0.8004 0.824 0.5789 0.02823 0.04695 0.10456
# 4 0.8139 0.842 0.6269 0.03210 0.03458 0.05727
# 5 0.8164 0.844 0.5969 0.02850 0.02951 0.07288
# 6 0.8263 0.836 0.6078 0.03310 0.03978 0.07959
# 7 0.8314 0.844 0.5966 0.03075 0.04502 0.07232
# 8 0.8316 0.860 0.6081 0.02359 0.04522 0.07316 *
#
# The top 5 variables (out of 8):
# glucose, mass, age, pregnant, pedigree
嗯,它提供5个变量,但您说的是4。我们可以很快地深入源代码,以探索它是如何计算并将这5个变量作为前5个变量返回的。
print(caret:::print.rfe)
#
# Only a snippet code shown below...
# cat("The top ", min(top, x$bestSubset), " variables (out of ",
# x$bestSubset, "):\n ", paste(x$optVariables[1:min(top,
# x$bestSubset)], collapse = ", "), "\n\n", sep = "")
因此,基本上,它是直接从results$optVariables
中提取前5个变量。怎么填充?
# print(caret:::rfe.default)
#
# Snippet 1 of code...
# bestVar <- rfeControl$functions$selectVar(selectedVars,
bestSubset)
#
# Snippet 2 of code...
# bestSubset = bestSubset, fit = fit, optVariables = bestVar,
好的,optVariables
被rfeControl$functions$selectVar
填充。
print(rfeControl)
#
# Snippet of code...
# list(functions = if (is.null(functions)) caretFuncs else functions,
从上方,我们看到正在使用caretFuncs$selectVar
...
详细信息:填充optVariables
print(caretFuncs$selectVar)
# function (y, size)
# {
# finalImp <- ddply(y[, c("Overall", "var")], .(var), function(x) mean(x$Overall,
# na.rm = TRUE))
# names(finalImp)[2] <- "Overall"
# finalImp <- finalImp[order(finalImp$Overall, decreasing = TRUE),
# ]
# as.character(finalImp$var[1:size])
# }