岭回归(Ridge Regression)与LASSO回归(Least Absolute Shrinkage and Selection Operator Regression)的原理分别如下:
一、岭回归原理
定义:
岭回归是一种专用于共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法。
它通过放弃最小二乘法的无偏性,以损失部分信息、降低精度为代价,来获得更为符合实际、更可靠的回归方法。
原理:
在传统的最小二乘法中,当自变量之间存在多重共线性(即高度相关性)时,会导致回归系数的估计不稳定。
岭回归通过在损失函数中加入一个正则化项(通常是参数的平方和),来解决多重共线性问题。
引入的正则化项会约束回归系数的大小,降低模型的复杂度,防止过拟合。
数学表达:
通常表示为在损失函数中加上一个与回归系数平方和成正比的项,即RSS + λ∑β_i^2,其中RSS是残差平方和,λ是正则化参数,β_i是回归系数。
特点:
岭回归方程的R平方值可能会稍低于普通回归分析,但回归系数的显著性往往明显高于普通回归。
在存在共线性问题和病态数据偏多的研究中有较大的实用价值。
二、LASSO回归原理
定义:
LASSO回归是一种线性回归的改进方法,主要用于数据分析和特征选择。
它通过在传统线性回归损失函数中加入一个L1正则化项(即参数的绝对值之和)来实现特征选择和防止过拟合。
原理:
LASSO回归将某些回归系数精确地压缩到0,从而实现特征选择的目的,使模型更为简洁。
L1正则化项会对回归系数进行惩罚,当正则化参数λ较大时,更多的系数会被压缩为0。
数学表达:
通常表示为在损失函数中加上一个与回归系数绝对值之和成正比的项,即RSS + λ∑|β_i|,其中RSS是残差平方和,λ是正则化参数,β_i是回归系数。
特点:
LASSO回归具有参数收缩与特征选择的能力,能够降低模型的复杂度,防止过拟合。
特别适合于具有大量特征但样本量有限的数据集。
正则化参数λ的选择对模型效果有显著影响,通常通过交叉验证等方法来确定。
总结:岭回归和LASSO回归都是对线性回归的改进,通过引入正则化项来解决多重共线性问题、防止过拟合和进行特征选择。岭回归使用L2正则化(参数的平方和),而LASSO回归使用L1正则化(参数的绝对值之和)。这两种方法在不同的场景下都有广泛的应用。
# 导入第三方模块
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Ridge,RidgeCV
import matplotlib.pyplot as plt
# 读取糖尿病数据集
diabetes = pd.read_excel(r'C:\Users\Administrator\Desktop\diabetes.xlsx', sep = '')
# 构造自变量(剔除患者性别、年龄和因变量)
predictors = diabetes.columns[2:-1]
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(diabetes[predictors], diabetes['Y'],
test_size = 0.2, random_state = 1234 )
# 构造不同的Lambda值
Lambdas = np.logspace(-5, 2, 200)
# 构造空列表,用于存储模型的偏回归系数
ridge_cofficients = []
# 循环迭代不同的Lambda值
for Lambda in Lambdas:
ridge = Ridge(alpha = Lambda, normalize=True)
ridge.fit(X_train, y_train)
ridge_cofficients.append(ridge.coef_)
# 绘制Lambda与回归系数的关系
# 中文乱码和坐标轴负号的处理
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 设置绘图风格
plt.style.use('ggplot')
plt.plot(Lambdas, ridge_cofficients)
# 对x轴作对数变换
plt.xscale('log')
# 设置折线图x轴和y轴标签
plt.xlabel('Lambda')
plt.ylabel('Cofficients')
# 图形显示
plt.show()
# 岭回归模型的交叉验证
# 设置交叉验证的参数,对于每一个Lambda值,都执行10重交叉验证
ridge_cv = RidgeCV(alphas = Lambdas, normalize=True, scoring='neg_mean_squared_error', cv = 10)
# 模型拟合
ridge_cv.fit(X_train, y_train)
# 返回最佳的lambda值
ridge_best_Lambda = ridge_cv.alpha_
ridge_best_Lambda
# 导入第三方包中的函数
from sklearn.metrics import mean_squared_error
# 基于最佳的Lambda值建模
ridge = Ridge(alpha = ridge_best_alpha, normalize=True)
ridge.fit(X_train, y_train)
# 返回岭回归系数
pd.Series(index = ['Intercept'] + X_train.columns.tolist(),data = [ridge.intercept_] + ridge.coef_.tolist())
# 预测
ridge_predict = ridge.predict(X_test)
# 预测效果验证
RMSE = np.sqrt(mean_squared_error(y_test,ridge_predict))
RMSE
# 导入第三方模块中的函数
from sklearn.linear_model import Lasso,LassoCV
# 构造空列表,用于存储模型的偏回归系数
lasso_cofficients = []
for Lambda in Lambdas:
lasso = Lasso(alpha = Lambda, normalize=True, max_iter=10000)
lasso.fit(X_train, y_train)
lasso_cofficients.append(lasso.coef_)
# 绘制Lambda与回归系数的关系
plt.plot(Lambdas, lasso_cofficients)
# 对x轴作对数变换
plt.xscale('log')
# 设置折线图x轴和y轴标签
plt.xlabel('Lambda')
plt.ylabel('Cofficients')
# 显示图形
plt.show()
# LASSO回归模型的交叉验证
lasso_cv = LassoCV(alphas = Lambdas, normalize=True, cv = 10, max_iter=10000)
lasso_cv.fit(X_train, y_train)
# 输出最佳的lambda值
lasso_best_alpha = lasso_cv.alpha_
lasso_best_alpha
# 基于最佳的lambda值建模
lasso = Lasso(alpha = lasso_best_alpha, normalize=True, max_iter=10000)
lasso.fit(X_train, y_train)
# 返回LASSO回归的系数
pd.Series(index = ['Intercept'] + X_train.columns.tolist(),data = [lasso.intercept_] + lasso.coef_.tolist())
# 预测
lasso_predict = lasso.predict(X_test)
# 预测效果验证
RMSE = np.sqrt(mean_squared_error(y_test,lasso_predict))
RMSE
# 导入第三方模块
from statsmodels import api as sms
# 为自变量X添加常数列1,用于拟合截距项
X_train2 = sms.add_constant(X_train)
X_test2 = sms.add_constant(X_test)
# 构建多元线性回归模型
linear = sms.formula.OLS(y_train, X_train2).fit()
# 返回线性回归模型的系数
linear.params
# 模型的预测
linear_predict = linear.predict(X_test2)
# 预测效果验证
RMSE = np.sqrt(mean_squared_error(y_test,linear_predict))
RMSE