如何用随机生成数据实现岭/套索回归交叉验证?解决代码报错
解决岭回归交叉验证的报错问题
问题重现
用户编写了如下R代码,尝试用随机生成的数据执行岭回归交叉验证:
library(leaps) library(glmnet) set.seed(7) x <- runif(100,0,1) y <- 1 + 2*x^2 + 4*x^3 + x^4 + rnorm(100,0,1) data_1<- data.frame(x,y) xridge<- model.matrix(y~x+I(x^2)+I(x^3)+I(x^4)+I(x^5)+I(x^6)+I(x^7)+I(x^8)+I(x^9)+I(x^10), data = data_1) yridge<-data_1$y crossval<-cv.glmnet(xridge, yridge, alpha=0)
运行时触发报错:
Error in glmnet(x, y, weights = weights, offset = offset, lambda = lambda, : number of observations in y (0) not equal to the number of rows of x (100)
错误原因
实际问题并非model.matrix移除NA导致y全为NA,而是变量名冲突:
- 你在
model.matrix的公式里用了y~,同时glmnet包的函数参数中也有一个名为y的参数。 - 这种命名冲突导致
cv.glmnet调用时,误将公式中的y识别为参数的y,而非你定义的yridge向量,最终出现观测数不匹配的错误。
解决方法
有两种简单的修正方式:
方式1:重命名数据框中的响应变量
把生成的data_1里的y列改名,避免和函数参数冲突:
library(leaps) library(glmnet) set.seed(7) x <- runif(100,0,1) y_val <- 1 + 2*x^2 + 4*x^3 + x^4 + rnorm(100,0,1) data_1<- data.frame(x, y_val) xridge<- model.matrix(y_val~x+I(x^2)+I(x^3)+I(x^4)+I(x^5)+I(x^6)+I(x^7)+I(x^8)+I(x^9)+I(x^10), data = data_1) yridge<-data_1$y_val crossval<-cv.glmnet(xridge, yridge, alpha=0)
方式2:构造仅含预测变量的矩阵
model.matrix里可以只写预测变量部分,无需带响应变量:
library(leaps) library(glmnet) set.seed(7) x <- runif(100,0,1) y <- 1 + 2*x^2 + 4*x^3 + x^4 + rnorm(100,0,1) data_1<- data.frame(x,y) # 仅构造预测变量矩阵,去掉公式中的响应变量y~ xridge<- model.matrix(~x+I(x^2)+I(x^3)+I(x^4)+I(x^5)+I(x^6)+I(x^7)+I(x^8)+I(x^9)+I(x^10), data = data_1) yridge<-data_1$y crossval<-cv.glmnet(xridge, yridge, alpha=0)
验证
运行修正后的代码,crossval会正常生成交叉验证结果,你可以用plot(crossval)查看lambda的选择情况,或用coef(crossval)提取最优lambda对应的系数。
内容的提问来源于stack exchange,提问作者stupidperson
相关产品推荐
相关产品推荐

