ste*_*sou 5 r machine-learning glmnet r-caret
我正在使用插入符号运行弹性净正则化glmnet
。
我将值序列传递给trainControl
alpha和lambda,然后执行repeatedcv
以获得alpha和lambda的最佳调整。
这是一个示例,其中alpha和lambda的最佳调整分别为0.7和0.5:
age <- c(4, 8, 7, 12, 6, 9, 10, 14, 7, 6, 8, 11, 11, 6, 2, 10, 14, 7, 12, 6, 9, 10, 14, 7)
gender <- make.names(as.factor(c(1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1)))
bmi_p <- c(0.86, 0.45, 0.99, 0.84, 0.85, 0.67, 0.91, 0.29, 0.88, 0.83, 0.48, 0.99, 0.80, 0.85,
0.50, 0.91, 0.29, 0.88, 0.99, 0.84, 0.80, 0.85, 0.88, 0.99)
m_edu <- make.names(as.factor(c(0, 1, 1, 2, 2, 3, 2, 0, 1, 1, 0, 1, 2, 2, 1, 2, 0, 1, 1, 2, 2, 0 , 1, 0)))
p_edu <- make.names(as.factor(c(0, 2, 2, 2, 2, 3, 2, 0, 0, 0, 1, 2, 2, 1, 3, 2, 3, 0, 0, 2, 0, 1, 0, 1)))
f_color <- make.names(as.factor(c("blue", "blue", "yellow", "red", "red", "yellow",
"yellow", "red", "yellow","blue", "blue", "yellow", "red", "red", "yellow",
"yellow", "red", "yellow", "yellow", "red", "blue", "yellow", "yellow", "red")))
asthma <- make.names(as.factor(c(1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1)))
x <- data.frame(age, gender, bmi_p, m_edu, p_edu, f_color, asthma)
tuneGrid <- expand.grid(alpha = seq(0, 1, 0.05), lambda = seq(0, 0.5, 0.05))
fitControl <- trainControl(method = 'repeatedcv', number = 3, repeats = 5, classProbs = TRUE, summaryFunction = twoClassSummary)
set.seed(1352)
model.test <- caret::train(asthma ~ age + gender + bmi_p + m_edu + p_edu + f_color, data = x, method = "glmnet",
family = "binomial", trControl = fitControl, tuneGrid = tuneGrid,
metric = "ROC")
model.test$bestTune
Run Code Online (Sandbox Code Playgroud)
我的问题?
当我运行时as.matrix(coef(model.test$finalModel))
,假设会给我与最佳模型相对应的系数,那么我会得到100组不同的系数。
那么,如何获得与最佳调整相对应的系数?
我已经看到了获得最佳模型的建议,coef(model.test$finalModel, model.test$bestTune$lambda)
但是,这将返回NULL系数,无论如何,它将仅返回与lambda相关的最佳调整,而与alpha无关。
编辑:
在互联网上到处搜索之后,我现在所能找到的就是指向正确答案的地方是这篇博客文章,该文章指出,model.test$finalModel
该模型返回对应于最佳alpha调整的模型,并coef(model.test$finalModel, model.caret$bestTune$lambda)
返回对应于最佳alpha调整的系数集。 Lambda的值。如果这是真的,那么这就是我的问题的答案。然而,由于这是一个博客帖子,我找不到任何东西来支持这种说法,我还是持怀疑态度。任何人都可以验证model.test$finalModel
返回与最佳alpha相对应的模型的声明吗?如果是这样,那么这个问题将得到解决。谢谢!
在对您的代码进行了一些操作后,我发现 glmnet 训练根据种子选择不同的 lambda 范围非常奇怪。下面是一个例子:
library(caret)
library(glmnet)
set.seed(13)
model.test <- caret::train(asthma ~ age + gender + bmi_p + m_edu + p_edu + f_color, data = x, method = "glmnet",
family = "binomial", trControl = fitControl, tuneGrid = tuneGrid,
metric = "ROC")
c(head(model.test$finalModel$lambda, 5), tail(model.test$finalModel$lambda, 5))
#output
[1] 3.7796447301 3.4438715094 3.1379274562 2.8591626295 2.6051625017 0.0005483617 0.0004996468 0.0004552595 0.0004148155
[10] 0.0003779645
Run Code Online (Sandbox Code Playgroud)
最佳 lambda 为:
model.test$finalModel$lambdaOpt
#output
#[1] 0.05
Run Code Online (Sandbox Code Playgroud)
这有效:
coef(model.test$finalModel, model.test$finalModel$lambdaOpt)
#12 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -0.03158974
age 0.03329806
genderX1 -1.24093677
bmi_p 1.65156913
m_eduX1 0.45314106
m_eduX2 -0.09934991
m_eduX3 -0.72360297
p_eduX1 -0.51949828
p_eduX2 -0.80063642
p_eduX3 -2.18231433
f_colorred 0.87618211
f_coloryellow -1.52699254
Run Code Online (Sandbox Code Playgroud)
给出最好的 alpha 和 lambda 系数
当使用这个模型来预测一些 y 被预测为 X1 和一些预测为 X2
[1] X1 X1 X0 X1 X1 X0 X0 X1 X1 X1 X0 X1 X1 X1 X0 X0 X0 X1 X1 X1 X1 X0 X1 X1
Levels: X0 X1
Run Code Online (Sandbox Code Playgroud)
现在用你用的种子
set.seed(1352)
model.test <- caret::train(asthma ~ age + gender + bmi_p + m_edu + p_edu + f_color, data = x, method = "glmnet",
family = "binomial", trControl = fitControl, tuneGrid = tuneGrid,
metric = "ROC")
c(head(model.test$finalModel$lambda, 5), tail(model.test$finalModel$lambda, 5))
#output
[1] 2.699746e-01 2.459908e-01 2.241377e-01 2.042259e-01 1.860830e-01 3.916870e-05 3.568906e-05 3.251854e-05 2.962968e-05
[10] 2.699746e-05
Run Code Online (Sandbox Code Playgroud)
lambda 值小 10 倍,这给出了空系数,因为 lambdaOpt 不在测试的 lambda 范围内:
coef(model.test$finalModel, model.test$finalModel$lambdaOpt)
#output
12 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) .
age .
genderX1 .
bmi_p .
m_eduX1 .
m_eduX2 .
m_eduX3 .
p_eduX1 .
p_eduX2 .
p_eduX3 .
f_colorred .
f_coloryellow .
model.test$finalModel$lambdaOpt
#output
0.5
Run Code Online (Sandbox Code Playgroud)
现在,在对该模型进行预测时,仅预测 X0(第一级):
predict(model.test, x)
#output
[1] X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0
Levels: X0 X1
Run Code Online (Sandbox Code Playgroud)
相当奇怪的行为,可能值得报告