与R中glmnet和LOOCV相关的小问题

与R中glmnet和LOOCV相关的小问题,r,machine-learning,regression,linear-regression,cross-validation,R,Machine Learning,Regression,Linear Regression,Cross Validation,我试着用cv.glmnet和glmnet的Leave-one-out交叉验证分割来拟合正则化模型(LASSO、Ridge、ElasticNet) 我使用它,数据集有517行13列(其中两个是分类变量)。因变量为“面积” 我想建立一个没有分类变量的模型。然后是计算每个LOOCV运行的系数平均值,以及R平方和均方根的平均值 数据集的最后10行如下所示 tail(wdbc,10) X Y month day FFMC DMC DC ISI temp RH wind rain ar

我试着用cv.glmnet和glmnet的Leave-one-out交叉验证分割来拟合正则化模型(LASSO、Ridge、ElasticNet)

我使用它,数据集有517行13列(其中两个是分类变量)。因变量为“面积”

我想建立一个没有分类变量的模型。然后是计算每个LOOCV运行的系数平均值,以及R平方和均方根的平均值

数据集的最后10行如下所示

tail(wdbc,10)
    X Y month day FFMC   DMC    DC  ISI temp RH wind rain  area
508 2 4   aug fri 91.0 166.9 752.6  7.1 25.9 41  3.6  0.0  0.00
509 1 2   aug fri 91.0 166.9 752.6  7.1 25.9 41  3.6  0.0  0.00
510 5 4   aug fri 91.0 166.9 752.6  7.1 21.1 71  7.6  1.4  2.17
511 6 5   aug fri 91.0 166.9 752.6  7.1 18.2 62  5.4  0.0  0.43
512 8 6   aug sun 81.6  56.7 665.6  1.9 27.8 35  2.7  0.0  0.00
513 4 3   aug sun 81.6  56.7 665.6  1.9 27.8 32  2.7  0.0  6.44
514 2 4   aug sun 81.6  56.7 665.6  1.9 21.9 71  5.8  0.0 54.29
515 7 4   aug sun 81.6  56.7 665.6  1.9 21.2 70  6.7  0.0 11.16
516 1 4   aug sat 94.4 146.0 614.7 11.3 25.6 42  4.0  0.0  0.00
517 6 3   nov tue 79.5   3.0 106.7  1.1 11.8 31  4.5  0.0  0.00
我的代码如下

set.seed(123) 
  data <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/forest-fires/forestfires.csv") 
  data<-data[-(3:4)] 
  nrFolds <- 517
  folds <- rep_len(1:nrFolds, nrow(data))
  for(k in 1:nrFolds) {
      fold <- which(folds == k)
      data.train <- data[-fold,]
      data.test <- data[fold,]
      x.train <- as.matrix(data.train[-11])
      y.train <- as.matrix(data.train[11])
      x.test <- as.matrix(data.test[-11])
      y.test <- as.matrix(data.test[11])
      cv <- cv.glmnet(x.train, y.train, alpha = 0)
      # cv$lambda.min
      model <- glmnet(x.train, y.train, alpha = 0, lambda = cv$lambda.min)
      coef(model) 
      predictions <- model %>% predict(x.test) %>% as.vector()
      RMSE <- RMSE(predictions, data.test$area)
      Rsquare <- R2(predictions, data.test$area)
      LL <- list(cv,model,coef(model),predictions, RMSE,Rsquare)
  }
  LL
这段代码还提供了以下错误

Error in cor(obs, pred, use = ifelse(na.rm, "complete.obs", "everything")) : 
  incompatible dimensions
In addition: Warning message:
In nominalTrainWorkflow(x = x, y = y, wts = weights, info = trainInfo,  :
  There were missing values in resampled performance measures.
更多更新

我还使用
caret
包编写了以下代码(例如Ridge)

set.seed(123)

数据好的,既然你已经说了,问题很明显。每次进入循环时,都会为LL指定一个新值。LL不会保存所有结果,只保存最后一个结果。试一试

LL <- lapply(1:nrFolds, function(k) {
  fold <- which(folds == k)
  data.train <- data[-fold,]
  data.test <- data[fold,]
  x.train <- as.matrix(data.train[-11])
  y.train <- as.matrix(data.train[11])
  x.test <- as.matrix(data.test[-11])
  y.test <- as.matrix(data.test[11])
  cv <- cv.glmnet(x.train, y.train, alpha = 0)
  # cv$lambda.min
  model <- glmnet(x.train, y.train, alpha = 0, lambda = cv$lambda.min)
  coef(model) 
  predictions <- model %>% predict(x.test) %>% as.vector()
  RMSE <- RMSE(predictions, data.test$area)
  Rsquare <- R2(predictions, data.test$area)
  list(CV=cv, model=model, coefs=coef(model), preds=predictions, rmse=RMSE, r2=Rsquare)
})
并不是说它们很好,而是问题在于运行glmnet,而不是如何做出最佳预测

编辑2:关于更新的代码。发生的情况如下:首先用517个零初始化向量
预测。在循环的第一次迭代中,您告诉caret在包含516个样本的训练集上创建517个LOO。插入符号然后返回优化的脊线模型(加上许多您忽略的信息,例如每个测试参数值的RMSE)。然后,对测试集进行预测,这是一个样本。您可以在
预测
向量中输入这一个样本,该向量现在包含1个预测和516个零。然后,您尝试在
预测
(一个预测和516个零的向量)和测试响应(一个值的向量)之间计算R2和RMSE。这并不是意外地失败了。然后将其全部存储在名为
LL
的列表中,该列表将在下次运行循环时被覆盖


我将如何做:删除33%的数据作为验证。使用剩余的66%带插入符号来训练单个模型(使用LOOCV或K-FOLD带插入符号来优化参数)。检查插入符号的输出;确保查看插入符号提供的RMSE(如果使用的不是LOOCV,请查看R²)。然后,在验证集上测试模型的性能。

那么,也许您的期望是错误的;-)说真的,你说“没有我预期的效果”是什么意思?它会抛出错误吗?它的性能低吗?这是怎么一回事?另外,我建议使用插入符号包。你真的不应该手工做你的LOOCV。@一月,非常感谢。我编辑了我的问题。然后,我将查看插入符号包。@1月,请查看我的评论和问题更新。在更新的代码中,您重复前面代码中的错误:每次运行循环时,您都会替换LL。此代码不会产生任何有意义的结果。关于插入符号:这不是人们通常使用它的方式。插入符号在内部执行LOO(或您选择的任何操作),并返回一系列参数的拟合优度的所有可能度量。但是,您在循环中重复运行它,仍然尝试(错误地)自行计算度量值。此外,您还引入了一个新错误,试图在一个(大部分)为零的向量上计算R2。@1月,再次感谢,请查看我的新更新代码。非常感谢您的回答。我试过代码,但R平方总是NA。它也不会将预测存储在一起。此外,我的想法是计算每个解释变量的系数平均值,以及R平方和RMSE的平均值。这对我很有用。当然R2是NA,因为你在这里做LOOCV(每个折叠只包含一个测试样本和(n-1)个训练样本),所以R2不能是其他任何东西。存在预测(它是单个数字!)
set.seed(123)
data <- read.csv("forestfires.csv") 
data<-data[-(3:4)]  
lambda.grid <-10^seq(10,-2, length =100)
alpha.grid<- 0 #Ridge 
control <- trainControl(method="LOOCV")
srchGrd = expand.grid(alpha = alpha.grid, lambda = lambda.grid)
lm_model <- train(area ~ . , data=data, trControl=control,tuneGrid=srchGrd,method = 'glmnet')
lm_model
coef(lm_model$finalModel, lm_model$bestTune$lambda)
LL <- lapply(1:nrFolds, function(k) {
  fold <- which(folds == k)
  data.train <- data[-fold,]
  data.test <- data[fold,]
  x.train <- as.matrix(data.train[-11])
  y.train <- as.matrix(data.train[11])
  x.test <- as.matrix(data.test[-11])
  y.test <- as.matrix(data.test[11])
  cv <- cv.glmnet(x.train, y.train, alpha = 0)
  # cv$lambda.min
  model <- glmnet(x.train, y.train, alpha = 0, lambda = cv$lambda.min)
  coef(model) 
  predictions <- model %>% predict(x.test) %>% as.vector()
  RMSE <- RMSE(predictions, data.test$area)
  Rsquare <- R2(predictions, data.test$area)
  list(CV=cv, model=model, coefs=coef(model), preds=predictions, rmse=RMSE, r2=Rsquare)
})
preds <- sapply(LL, function(x) x$preds)