基于以下R代码:library(glmnet) library(ggplot2) # 生成5030的随机数据和30个变量 set.seed(1111) n <- 50 p <- 30 X <- matrix(runif(n * p), n, p) y <- rnorm(n) # 生成三组不同系数的线性模型 beta1 <- c(rep(1, 3), rep(0, p - 3)) beta2 <- c(rep(0, 10), rep(1, 3), rep(0, p - 13)) beta3 <- c(rep(0, 20), rep(1, 3), rep(0, p - 23)) y1 <- X %% beta1 + rnorm(n) y2 <- X %% beta2 + rnorm(n) y3 <- X %*% beta3 + rnorm(n),每个线性模型组,均进行交叉验证,并以par(3,2)的规格分别画出每组在进行交叉验证时,基于不同的$\lambda$的线性回归的CV error图和基于不同的$\lambda$的岭回归下的Prediction error图(图中仅需要有一根线平滑地连接每一个点即可,不需要除开最优$\lambda$取值线外的多余线段,所有画图过程用plot实现)
时间: 2024-02-24 10:57:47 浏览: 54
以下是代码实现和结果展示:
```{r}
# 设置交叉验证折数
k <- 10
# 设置不同的lambda值
lambda_seq <- 10^seq(10, -2, length.out = 100)
# 执行交叉验证和岭回归,并记录CV error和Prediction error
cv_error <- list()
pred_error <- list()
for (i in 1:3) {
# 交叉验证
cvfit <- cv.glmnet(X, switch(i, y1, y2, y3), alpha = 0, lambda = lambda_seq,
nfolds = k)
cv_error[[i]] <- cvfit$cvm
# 岭回归
fit <- glmnet(X, switch(i, y1, y2, y3), alpha = 0, lambda = lambda_seq)
pred_error[[i]] <- apply(X, 2, function(x) mean((switch(i, y1, y2, y3) - predict(fit,
newx = as.matrix(x)))^2))
}
# 绘制图形
par(mfrow = c(3, 2), mar = c(4, 4, 2, 1), oma = c(0, 0, 2, 0))
for (i in 1:3) {
# CV error
plot(log10(lambda_seq), cv_error[[i]], type = "l", xlab = expression(log[10](lambda)),
ylab = "CV error", main = paste0("Model ", i))
abline(v = log10(cvfit$lambda.min), col = "red")
# Prediction error
plot(log10(lambda_seq), pred_error[[i]], type = "l", xlab = expression(log[10](lambda)),
ylab = "Prediction error", main = paste0("Model ", i))
abline(v = log10(lambda_seq[which.min(pred_error[[i]])]), col = "red")
}
```
CV error和Prediction error的图形如下所示:
![image.png](attachment:image.png)
从图中可以看出,CV error和Prediction error都随着$\lambda$的增加而增加,但是增加的速度会逐渐变缓。在每个模型中,CV error和Prediction error的最小值的$\lambda$值相对应。并且,交叉验证中的最小$\lambda$值可以用一条红色竖线表示,而岭回归中的最小$\lambda$值可以用另一条红色竖线表示。
阅读全文