本节来介绍一下如何使用R语言进行Lasso回归模型分析
❝Lasso回归是一种线性回归的扩展,通过引入L1正则化来精简模型,使得某些系数归零,实现自动的变量选择。这种方法特别适用于高维数据集,帮助防止过拟合并增强模型泛化。在统计和机器学习等多个领域,Lasso因其优异的特征选择能力而受到青睐。通过调整正则化参数允许在准确性和简洁性之间达到最佳平衡。 ❞
Lasso分析可使用glmnet包中的cv.glmnet函数来执行Lasso回归,并通过交叉验证选出最优的正则化参数λ。下面通过R中著名的mtcars数据集来进行展示。
set.seed(123) # 设置种子数
library(glmnet)
library(tidyverse)
library(psych)
data("mtcars") # 加载数据集
y <- mtcars %>% select(mpg) %>%
scale(center = TRUE, scale = FALSE) %>% as.matrix()
# 从mtcars数据集中选取mpg列作为响应变量y,并进行中心化(减去平均值),转换为矩阵格式。
X <- mtcars %>% select(-mpg) %>% as.matrix()
# 从mtcars中选取除mpg外的所有列作为预测变量X,并转换为矩阵格式。
❝在使用cv.glmnet函数时,可以不手动设置lambda参数而使用其默认值。当lambda没有被明确设置时,glmnet会自动生成一个lambda序列,该序列基于提供的数据范围,并尝试找到最佳的lambda。这个自动生成的序列旨在覆盖从最大值(在该lambda下,所有系数均为零)到足够小的值(几乎所有的系数都不会被压缩到零)的范围。 ❞
lasso_cv <- cv.glmnet(X, y, alpha = 1,standardize = TRUE,nfolds = 10)
plot(lasso_cv) # 绘制Lasso回归的交叉验证结果图
> lasso_cv
Call: cv.glmnet(x = X, y = y, nfolds = 10, alpha = 1, standardize = TRUE)
Measure: Mean-Squared Error
Lambda Index Measure SE Nonzero
min 0.5519 25 7.046 1.965 5
1se 1.3993 15 8.839 2.446 3
❝Lambda: 表示不同情况下的lambda值。lambda.min是0.5519,这是使交叉验证的均方误差最小的lambda值;lambda.1se是1.3993,这是在保持模型简洁性的前提下,给出接近最小MSE的一个较大的lambda值。 Index: 表示lambda值在尝试的序列中的位置。 Measure: 这列表示在给定lambda值下通过交叉验证计算得到的均方误差。SE: 表示MSE的标准误差。Nonzero: 表示在给定lambda值下,模型中系数不为零的特征数量。 ❞
❝在实际应用中,lambda.min提供了最小化交叉验证MSE的模型,而lambda.1se则提供了一个在MSE相对较小的同时,模型更为简化的选择。选择哪一个取决于你对模型复杂度和预测准确性之间的权衡。如果偏好更简单的模型(可能牺牲一些准确性),可以选择lambda.1se;如果目标是最小化预测误差,那么lambda.min是更好的选择。 ❞
best_lambda <- lasso_cv$lambda.min
lasso_best <- glmnet(X, y,alpha = 1,lambda = best_lambda,standardize = TRUE)
Call: glmnet(x = X, y = y, alpha = 1, lambda = best_lambda, standardize = TRUE)
Df %Dev Lambda
1 3 82.11 0.8007
❝Df: 代表模型中非零系数的特征数目。 %Dev: 表示模型解释的响应变量方差的百分比,也可以被理解为模型拟合优度的一种衡量。在这里,%Dev是82.11%,表明该Lasso模型能够解释大约82.11%的响应变量方差,这是一个相对较高的值,表示模型拟合得较好。 Lambda: 这是用于拟合模型的lambda参数的值。Lambda为0.8007,这是通过交叉验证确定的最优值,用于在模型复杂性(即系数的数量)和模型拟合之间达到平衡。 ❞
# 定义响应变量和预测变量
y <- mtcars$mpg
X <- as.matrix(mtcars %>% select(-mpg))
# 使用交叉验证执行Lasso回归以确定最佳lambda值
cv_model <- cv.glmnet(X, y, alpha = 1, family = "gaussian")
# 绘制交叉验证误差曲线
plot(cv_model)
# 绘制变量系数随lambda变化的动态过程图
plot(cv_model$glmnet.fit, xvar = "lambda", label = FALSE)
legend("topright", legend = colnames(X), lty = 1, col = 1:ncol(X), cex = 0.7)
❝若cv_model只有单个lambda值的模型,而没有整个lambda序列的结果时。在这种情况下,绘制系数路径图的功能可能不会有结果,因为路径图需要多个lambda值来展示系数如何随lambda变化。 要解决这个问题并得到一个有用的图,可以使用带有多个lambda值的原始cv_model对象来绘制路径图。cv_model对象在交叉验证过程中考虑了多个lambda值,并保存了这些lambda值下的系数,这使得它成为绘制系数路径的理想选择。