r - 有什么方法可以根据 R 中的 wilcoxon 测试选择单变量特征?
问题描述
我打算用来care::sbf
做单变量特征选择,我的输入是具有多个变量(又名,它的列)、候选特征列表和标签(又名,分类变量)的数据框。阅读caret
包文档后,我尝试使用sbf
,sbfController
进行功能选择,但在下面遇到错误:
contrasts<-
( , value = contr.funs*tmp*
[1 + isOF[nn]]) 中的错误:
对比只能应用于具有 2 个或更多级别的因子
谁能指出我如何解决这个错误?caret::sbf
使用什么来做特征选择是正确的?任何想法?
可重现的例子:
这是关于公共要点的可重现示例,我将其用作输入。
我目前的尝试:
library(caret)
library(e1071)
library(randomForest)
df=read.csv("df.csv", header=True)
sbfCtrl <- sbfControl(method = 'cv', number = 10, returnResamp = 'final', functions = caretFuncs, saveDetails = TRUE)
model <- sbf(form= ventil_status~ .,
data= df,
methods='knn',
trControl=trainControl(method = 'cv', classProbs = TRUE),
tuneGrid=data.frame(k=1:10),
sbfControl=sbfControl(functions = sbfCtrl,
methods='repeatedcv', number = 10, repeats = 10))
print(model)
print(model$fit$results)
> model <- sbf(ventil_status~ ., data=df, sizes=c(1,5,10,20),
+ method= 'knn', trControl=trainControl(method = 'cv', classProbs = TRUE),
+ tuneGrid = data.frame(k=1:10),
+ sbfControl=sbfCtrl)
Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) :
contrasts can be applied only to factors with 2 or more levels
我用谷歌搜索了这个错误,但仍然无法克服它。任何想法使上述代码工作?使用 进行过滤器选择的正确方法是什么caret::sbf
?
我想要的是输出数据框必须具有附加的 p 值的选定功能。所以这是我的尝试:
newdf <- df[ , -which(names(df) %in% c("subject"))]
p_value_vector <- sapply(names(newdf), function(i)
tryCatch(
wilcox.test(newdf[newdf$ventil_status %in% "0", i],
newdf[newdf$ventil_status %in% "1", i],
na.action(na.omit))$p.value),
warning = function(w) return(NA),
error = function (e) return(NA)
)
预期输出:
我期待具有选定特征的输出数据框,其中返回的 p 值wilcox.test
应附加到相应的特征。有什么想法可以在 r 中实现吗?如何caret::sbf
正确操作特征选择?任何想法?
这是我的 R 会话信息:
> sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggpubr_0.2.5 magrittr_1.5 reshape2_1.4.3
[4] forcats_0.5.0 purrr_0.3.3 readr_1.3.1
[7] tibble_2.1.3 tidyverse_1.3.0 stringr_1.4.0
[10] dplyr_0.8.5 scales_1.1.0 tidyr_1.0.2
[13] aws.s3_0.3.20 randomForest_4.6-14 e1071_1.7-3
[16] mlbench_2.1-1 caret_6.0-86 ggplot2_3.3.0
[19] lattice_0.20-38
解决方案
对于使用 sbf,您可以使用 caretSBF,然后添加您喜欢定义的分数和过滤器:
library(mlbench)
library(caret)
knnSBF = caretSBF
knnSBF$summary <- twoClassSummary
knnSBF$score <- function(x, y) {
wilcox.test(x ~ y)$p.value
}
knnSBF$filter <- function(score, x, y) {
score <= 0.05
}
然后定义训练参数和 sbf 参数:
sbfCtrl <- sbfControl(method = "cv",number = 3,
functions = knnSBF,saveDetails = TRUE)
trn_grid <- expand.grid(k=c(2,6,10))
trCtrl <- trainControl(method = "cv",number = 3,
classProbs = TRUE,verboseIter = TRUE)
然后运行火车:
data(Sonar)
y = Sonar$Class
x = Sonar[,-ncol(Sonar)]
set.seed(111)
model1 <- sbf(x,y,trControl = trCtrl,
sbfControl = sbfCtrl,
method = "knn",
tuneGrid = trn_grid)
model1$variables
$selectedVars
[1] "V1" "V2" "V3" "V4" "V5" "V6" "V8" "V9" "V10" "V11" "V12" "V13"
[13] "V14" "V20" "V21" "V22" "V36" "V37" "V42" "V43" "V44" "V45" "V46" "V47"
[25] "V48" "V49" "V50" "V51" "V52" "V54" "V58"
$selectedVars
[1] "V4" "V5" "V6" "V9" "V10" "V11" "V12" "V13" "V14" "V20" "V21" "V22"
[13] "V28" "V31" "V34" "V35" "V36" "V37" "V43" "V44" "V45" "V46" "V47" "V48"
[25] "V49" "V51" "V52"
$selectedVars
[1] "V1" "V2" "V3" "V4" "V5" "V6" "V7" "V8" "V9" "V10" "V11" "V12"
[13] "V13" "V14" "V21" "V22" "V23" "V34" "V35" "V36" "V37" "V43" "V44" "V45"
[25] "V46" "V47" "V48" "V49" "V50" "V51" "V52" "V53" "V56" "V58"
我不认为他们会返回 p 值,尽管我可能是错的。使用上面的示例,您可以计算 p 值
p_value_vector <- apply(x,2,function(i)wilcox.test(i~y)$p.value)
推荐阅读
- python - TensorFlow Keras Metrics 未显示
- python - 无法分配“
]>": "Mark.MarkOwner" 必须是 "Child" 实例 - symfony - 在 GraphQL 中使用自定义标识符时的 OneToMany 关系返回空/错误数据
- java - 如何逃脱'|' JBehave 中的角色
- html - 如何在 Windows 中使用 C 提交表单
- python-3.x - 如何在 Python 中更新文本文件的值
- http - WebSocket 连接:它可以遵循以前的 HTTP/1.1 请求/响应吗?
- python - 如何在 PyQt5 的选项卡小部件中添加堆叠布局?
- python - 是否可以在标题中创建带有 href 的绘图(matplotlib)?
- angular - Angular9/Typescript3.8/Babylon4.1.0 - Typescript 编译错误 - 找不到模块'react'/找不到命名空间'JSX'