2017-10-09 160 views
0

我有一组预测是部分相关的,我想将它们减少到一个功能集并使用简化模型进行预测。我能找到一个很好的拉姆达使用glmnet组预测的k倍交叉验证

> require(glmnet); require(glmnetUtils) 
> cvfit <- cv.glmnet(
+   SpeakerGroup ~ Age +transient_mean +syllablerate+syllablerate_sd+intensitysfraction_mean + NucleusPercentVoiced_mean +NucleusPercentVoiced_sd +OnsetPercentVoiced_mean + OnsetPercentVoiced_sd +Shim + Jitt +intensityslope+rateslope + APQ3 +APQ5+DDP_A+RAP +PPQ5 +DDP, nfolds = 20 
+   ,family="binomial",data=curr.df,type.measure = "class") 
> 
> plot(cvfit) 

使用(见的形象在这里:https://umu.box.com/s/9rt60v3btfo8qhz870vludv6whxlgfx0 imgur不工作对我来说)。

> cbind(coef.cv.glmnet(cvfit, s = "lambda.1se"),coef.cv.glmnet(cvfit, s = "lambda.min")) 
20 x 2 sparse Matrix of class "dgCMatrix" 
            1   1 
(Intercept)    -1.229948 -0.84290372 
Age      .   .   
transient_mean    .   .   
syllablerate    .  -0.31636610 
syllablerate_sd   .   .   
intensitysfraction_mean .   .   
NucleusPercentVoiced_mean .   .   
NucleusPercentVoiced_sd .   .   
OnsetPercentVoiced_mean .   0.01119326 
OnsetPercentVoiced_sd  .   .   
Shim      .   .   
Jitt      .   8.09912574 
intensityslope    .  -1.68472631 
rateslope     .   .   
APQ3      .   .   
APQ5      .   .   
DDP_A      .   .   
RAP      .   .   
PPQ5      .   .   
DDP      .   .   
> 

好,这种模式得到了我一套,我想,以评估预测组成员(两种可能的群体)的术语是否准确,特异性等预测的。

> require(resamplr) # https://github.com/jrnold/resamplr 
> # compute 5 folds that have the same balance between groups as the original data set 
> curr.df %>% group_by(SpeakerGroup) %>% crossv_kfold(k=5,stratify=TRUE) -> folds 
> 

我可以计算模型

> folds <- folds %>% mutate(model = map(train, ~ glmnet(
+   SpeakerGroup ~ Age + transient_mean +syllablerate+syllablerate_sd+intensitysfraction_mean +NucleusPercentVoiced_sd +OnsetPercentVoiced_mean + OnsetPercentVoiced_sd + Jitt +intensityslope + APQ3 +DDP_A,data=.,family="binomial"))) 

(你可以在这里找到导致folds对象https://umu.box.com/s/ktxbba4ptzf3hke8g5ze6qgvt0rv42fp

现在,我要根据每个模型和测试数据建立预测通过5倍程序。

> 
> predicted <- folds %>% mutate(predicted =map2(model, test, ~ predict(.x, data = .y,type="response",s=cvfit$lambda.min))) 

我我创了一个错误:

Error in mutate_impl(.data, dots) : 
    Evaluation error: argument "data" is missing, with no default. 

我为此感到困惑,因为我提供了一个data说法。

有什么想法可以在这里出错?

是否有一种更简单的方法来获得GLMNET模型的5倍交叉验证的标准2x2混淆矩阵?

谢谢!

弗雷德里克

+0

修改的错误 - 你是过于复杂与dplyr语法的东西。这是简单的循环会很好的地方。其次,模型是无关紧要的。在给定预测的情况下,您可以计算任何阈值的任何度量。另外,提醒'cv.glmnet'已经在模型中进行了交叉验证。 –

+0

看来'glmnetUtils'中的'glmnet.formula'有一些问题,与'purrr :: map'不太匹配。 –

+0

但你说得对 - cv.glmnet确实做了k-fold交叉验证。那么问题是我如何提取拟合的值。我需要它们来研究预测误差的分布。 –

回答

0

如上评论指出的,cv.glmnet过程已经是交叉验证。问题是我看不到从模型中提取拟合值的方法。

以供将来参考,这个工程

cvfit <- cv.glmnet(
     <description of model>... ,type.measure = "auc",keep=TRUE) 

主要的一点是keep=TRUE它允许你以后提取参数。

currInd <- match(cvfit$lambda.min,cvfit$glmnet.fit$lambda) 
# There is also a 'cvfit$lambda.1se' to have a look at 
    cutoff <- 0.5 
    predicted <- cut(as.numeric(cvfit$fit.preval[,currInd]),c(-1000,cutoff,1000),labels=<your labels>) 

它给你一个预测向量,使用你的截断值,然后你可以与实际值进行比较。

我确实希望有一个标准化的方式来做到这一点,而不需要手动提取参数,但它是存在的。至少这是有效的。

0

在回答你的问题“是否有一种更简单的方法来获得标准2x2混淆矩阵的GLMNET模型的5倍交叉验证?”,您可以通过caret包简单地做到这一点,如下图所示。该代码还根据要求输出特异性,准确性等。

免责声明:代码是从“A short introduction to the caret package

library(caret) 
library(mlbench) # for the Sonar dataset 
data(Sonar) #response is "Class" 

# Split data into test and train 
train_inds = createDataPartition(y = Sonar$Class, p = .75, list = FALSE) 
X_train = Sonar[train_inds, ] 
X_test = Sonar[-train_inds, ] 

# Fit model using 5-fold cross validation to get optimal alpha and lambda 
ctrl = trainControl(method = "cv", number = 5) 
fit = train(Class ~ ., data = X_train, method = "glmnet", 
       preProc = c("center", "scale"), 
       trControl = ctrl) 
fit # print optimal values of alpha and lambda 

# Get confusion matrix for test data (as well as specificity, accuracy etc) 
yhats <- predict(fit, newdata = X_test, type = "raw") 
confusionMatrix(yhats, X_test$Class)