从插入符号的火车功能中提取预测

问题描述

我正在尝试复制 missuse 的工作answer,以便从插入符号的火车功能提取预测。我使用的是弹性网,但无法获得。

以下是可重现的示例:

require(caret)   
require(glmnet)

x = matrix(rnorm(100 * 20),100,20)   
set.seed(3) 
g = sample(c(0,1),replace = TRUE)

df = as.data.frame(x) 
g_f = as.factor(g) 
df$g_f = g_f

train_control <- trainControl(   
method="cv",number = 3,savePredictions = T)

sorozat = seq(0,1,0.25)

search_grid <- expand.grid(   
alpha = sorozat,lambda = sorozat )

set.seed(3) 
fit2 <- train(g_f ~ .,data = df,trControl = train_control,tuneGrid = search_grid,preProc = c("BoxCox","center","scale"),method = "glmnet")

而我的尝试却给出了错误

prediction2 <- predict(fit2$finalModel,data = predict(fit2$preProcess,df))$prediction

predict.glmnet中的错误(fit2 $ finalModel,data = dict(fit2,df)): 您需要提供“ newx”的值

下面是我如何获得预测的方法。但是如果混淆矩阵,我怎么能确定它是否正确呢?

# CM ver.1
pred_f = predict(fit2,df)
cm = as.data.frame(pred_f)
cm$g = g_f
table(cm)
      g
pred_f  0  1
     0 29  9
     1 15 47

与模型提供的不同吗?

# CM ver.2
confusionMatrix(fit2)$table
          Reference
Prediction  0  1
         0 23 16
         1 21 40

在此先感谢您的帮助!

编辑:添加了混淆矩阵的输出

解决方法

链接的答案不适用于glmnet,因为predict.glmnet具有一些特殊之处:

predict.glmnet的数据参数称为newx,必须为矩阵。

除此之外,此预测函数使用所有拟合的lambda来创建预测,因此,如果要获得最佳预测,则必须指定。另外,建议将响应设置为您的链接:

在您的示例中,最佳拟合值为alpha = 0.5和lambda = 0.25。 alpha设置在模型内部,但必须在预测期间指定lambda。

但是首先我们必须预处理测试数据(与链接的答案相同):

predict(fit2$preProcess,df)

这将返回带有类列的数据帧,因此为了将其提供给predict.glmnet,必须删除响应列(因子)并将数据帧转换为矩阵:

as.matrix(predict(fit2$preProcess,df)[,-21])

现在以最佳λ为0.25调用predict.glmnet并将预测类型设置为class:

library(glmnet)
prediction2 <- predict(fit2$finalModel,newx = as.matrix(predict(fit2$preProcess,-21]),type = "class",s = 0.25)

head(prediction2)
     1  
[1,] "0"
[2,] "1"
[3,] "0"
[4,] "0"
[5,] "0"
[6,] "0"

编辑:回答有关混淆矩阵差异的已编辑问题。

当您在confusionMatrix的输出上调用train时,则从重采样过程中的失格预测获得结果矩阵-由于这些是测试集预测,因此偏差较小。

当您对所有数据拟合模型(这是fit2$finalModel)并使用它对正在创建的列车集合预测进行预测的同一数据时-由于模型使用了这些拟合,因此存在很大的偏差观察。这就是与在confusionMatrix上调用fit2相比,这种情况下对角线总和要少得多的原因。有时将这种情况称为过拟合-模型可以更好地预测已经看到的数据。

简而言之

`confusionMatrix(fit2)`

从异常预测中产生一个混淆矩阵。可以用作模型选择的指标。

同时

confusionMatrix(as.factor(prediction2),g_f)

基于对火车数据的模型预测,生成高度偏差的混淆矩阵。不应将其用作模型选择的指标。

EDTI2::我只是想到这可能是XY problem

如果您只想要交叉验证的预测,则可以简单地使用:

fit2$pred

如果要计算这些的AUC,则应在trainControl中指定您要的类概率:

train_control <- trainControl(   
  method="cv",number = 3,savePredictions = TRUE,classProbs = TRUE)

另一个需要注意的是,类级别必须是有效的变量名称,因此0和1之类的数字将不起作用,一个简单的解决方法是:

df$g_f <- factor(df$g_f,levels = c(0,1),labels = c("zero","one"))

合适之后:

set.seed(3) 
fit2 <- train(g_f ~ .,data = df,trControl = train_control,tuneGrid = search_grid,preProc = c("BoxCox","center","scale"),method = "glmnet")

预测在fit2$pred中:

head(fit2$pred)
#output
  pred  obs rowIndex      zero       one alpha lambda Resample
1  one  one        2 0.4513397 0.5486603     0      1    Fold1
2 zero zero        4 0.5764889 0.4235111     0      1    Fold1
3 zero  one        5 0.5154925 0.4845075     0      1    Fold1
4  one  one        6 0.4836418 0.5163582     0      1    Fold1
5 zero zero        7 0.5199623 0.4800377     0      1    Fold1
6  one zero        8 0.4770536 0.5229464     0      1    Fold1

这些预测适用于所有经过测试的超参数组合,以获取性能最佳的超参数:

library(tidyverse)

fit2$pred %>%
  filter(alpha == fit2$bestTune$alpha&
         lambda == fit2$bestTune$alpha) -> best_preds

有两种方法可以从这些预测中获取指标。

方法1.您可以使用组合的折叠预测(频率较低,但在数据集较小时很有用,因此折叠性能差异很大)可以做到这一点

pROC::roc(best_preds$obs,best_preds$one)$auc
#output
Area under the curve: 0.6631

方法2。您可以按平均和折算来计算(更常见,插入符号在内部用于任何度量标准:

library(tidyverse)

best_preds %>%
  group_by(Resample) %>%
  summarise(auc = as.numeric(pROC::roc(obs,one)$auc))
#output
  Resample   auc
  <chr>    <dbl>
1 Fold1    0.592
2 Fold2    0.757
3 Fold3    0.614

上面是每折AUC

求平均值:

best_preds %>%
  group_by(Resample) %>%
  summarise(auc = as.numeric(pROC::roc(obs,one)$auc)) %>%
  ungroup() %>%
  summarise(mean_auc = mean(auc))
#output
  mean_auc
     <dbl>
1    0.654