与R中glmnet和LOOCV相关的小问题
我试着用cv.glmnet和glmnet的Leave-one-out交叉验证分割来拟合正则化模型(LASSO、Ridge、ElasticNet) 我使用它,数据集有517行13列(其中两个是分类变量)。因变量为“面积” 我想建立一个没有分类变量的模型。然后是计算每个LOOCV运行的系数平均值,以及R平方和均方根的平均值 数据集的最后10行如下所示与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
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)