Lasso回归(Least Absolute Shrinkage and Selection Operator Regression)是一种线性回归模型,通过引入L1正则化(即Lasso惩罚项),对模型中的系数进行压缩,使某些系数缩减至零,从而实现特征选择和模型稀疏性。Lasso回归由Robert Tibshirani提出,主要用于处理变量过多而样本量较少的情况,能够有效防止过拟合并解决多重共线性问题。
Lasso回归的基本原理
Lasso回归通过在目标函数中添加一项L1正则化项,即变量系数的绝对值之和,来压缩模型。这使得一些系数变为零,从而实现特征选择和模型稀疏性。具体来说,Lasso回归的优化目标函数如下:
[ \min_{\beta} \left( \sum_{i=1}^n (y_i - x_i^T \beta)^2 + \alpha \sum_{j=1}^p |\beta_j| \right) ]
其中,( n ) 是样本数量,( p ) 是特征数量,( y_i ) 是实际观测值,( x_i^T \beta ) 是预测值,( \beta ) 是模型参数(系数),( \alpha ) 是L1正则化项的权重。
Lasso回归的应用场景和优缺点
应用场景:
一、特征选择:Lasso回归可以用于选择最重要的特征,通过将不重要的特征系数缩减为零,简化模型并提高模型的泛化能力。
二、多重共线性问题:在存在多重共线性的情况下,Lasso回归可以通过将相关变量的系数变为零来降低其对回归结果的影响。
三、预测建模:在医学研究中,Lasso回归可以选择最相关的指标和变量,建立高效的预测模型。
Lasso回归的优点:
1.特征选择:能够有效进行变量选择,特别是在预测变量数量远大于样本量的情况下。
2.防止过拟合:通过压缩系数,避免模型过于复杂,提高模型的泛化能力。
Lasso回归的缺点:
1.计算复杂度较高:由于L1正则化的非光滑性,优化过程较为复杂,计算成本较高。
2.稳定性问题:由于某些系数可能完全为零,模型的稳定性可能受到影响。
岭回归(Ridge Regression)是一种用于处理多重共线性的有偏估计回归方法,它通过在普通最小二乘法的基础上加入L2正则化项来解决多重共线性问题,从而提高模型的泛化能力和鲁棒性。
基本概念和原理
岭回归通过在最小二乘损失函数中加入L2范数的惩罚项,即模型参数的平方和乘以一个称为岭参数的λ值。这个惩罚项确保了模型参数不会变得过大,从而减少过拟合的风险,提高模型的稳定性和泛化能力。岭回归的损失函数包括两部分:一部分是残差平方和,另一部分是模型参数平方和乘以λ值。
应用场景
岭回归特别适用于那些特征之间高度相关(即多重共线性问题)的数据集。在这种情况下,普通的线性回归模型可能会变得不稳定,并且模型的系数可能会变得非常大。岭回归通过惩罚模型参数,使其保持较小的值,从而使得模型更加稳健。
岭回归的优点:
1.处理多重共线性:岭回归能够有效处理特征之间的强相关性,避免参数估计的不稳定。
2.减少过拟合:通过惩罚大参数,岭回归能够提高模型的泛化能力,减少过拟合的风险。
3.计算简单:岭回归的实现相对简单,不需要复杂的计算过程。
岭回归的缺点:
1.有偏估计:岭回归通过牺牲无偏性来获得更稳定的估计,可能会导致模型预测的偏差。
2.参数选择:选择合适的λ值是一个挑战,不同的λ值会影响模型的性能。
岭回归的实际应用案例
在实际应用中,岭回归常用于生物信息学、金融数据分析等领域,特别是在处理具有高度相关特征的数据时表现出色。例如,在基因表达数据分析中,基因之间的相关性可能导致普通线性回归模型不稳定,此时岭回归可以提供更稳定的参数估计。
弹性网络回归(Elastic Net Regression)是一种结合了L1和L2正则化惩罚的线性回归模型,主要用于处理高维数据和具有多重共线性的特征。它结合了Lasso回归和岭回归(Ridge Regression)的优点,能够在特征选择和模型稳定性之间取得平衡。
基本原理:
弹性网络回归通过在损失函数中同时引入L1和L2正则化项来约束模型的复杂度。L1正则化(Lasso回归)通过惩罚较大的系数来促进稀疏性,有利于特征选择;而L2正则化(岭回归)通过惩罚系数的平方来减少模型的过拟合。通过引入两个正则化参数λ和ρ,弹性网络回归可以在Lasso回归和岭回归之间灵活调节,以适应不同的数据特性。
优点和应用场景:
1.解决多重共线性问题:当特征之间存在高度相关性时,弹性网络回归通过L2正则化可以保留一组相关特征,解决Lasso回归随机选择特征的问题。
2.稳定性:在处理高维数据时,弹性网络回归表现更稳定,不容易受到特征选择的影响。
3.适用于大数据集:由于其计算复杂度较低,弹性网络回归在处理大数据集时更有效率。
弹性网络回归在多个领域有广泛应用,包括金融领域的股票价格预测、汇率变动预测,医学领域的疾病风险预测、药物反应分析,工程领域的建筑物结构稳定性预测,生态学的环境因素分析,以及社会科学的统计数据分析等。
今天我们仍以熟悉的“示例数据集”为例,演示一下Python的sklearn.linear_model库进行lasso回归、岭回归、弹性网络回归操作示例。
Scikit-learn(sklearn)是一个基于Python的开源机器学习库,它建立在NumPy、SciPy和Matplotlib之上,为数据建模提供了一整套工具。
Scikit-learn提供了大量的算法和工具,涵盖了数据挖掘、数据分析和机器学习领域的各种任务,包括分类、回归、聚类、降维等。
主要特点和功能简单易用:
1.Scikit-learn的设计非常简洁,易于上手,即使对于机器学习的新手也能快速掌握。
2.功能强大:它包含了从基础的线性回归、逻辑回归到复杂的支持向量机等多种机器学习算法。
3.集成性好:Scikit-learn与NumPy、Pandas、Matplotlib等Python科学计算库紧密集成,方便进行数据预处理、模型训练和结果可视化。
4.社区活跃:Scikit-learn有一个活跃的开源社区,不断更新和完善库的功能,同时提供丰富的文档和教程资源。
#加载程序包(openpyxl和pandas等)
#使用pandas读取示例数据xlsx文件
import openpyxl
from array import array
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
datala = pd.read_excel(r'C:\Users\L\Desktop\示例数据.xlsx')
# 查看前几行数据
print(datala.head())
# 分离特征和目标变量
X = datala[['指标1', '指标2', '指标3','指标4','指标5','指标6']]
y = datala['结局']
#加载lasso回归、岭回归、弹性网络及交叉验证所需要的库
from sklearn.linear_model import Lasso, Ridge, ElasticNet
from sklearn.datasets import make_regression
from sklearn.model_selection import cross_val_score, cross_val_predict
from sklearn.linear_model import LassoCV, ElasticNetCV
from sklearn.model_selection import KFold
# Lasso回归
alpha = 0.1 # L1惩罚系数
lasso = Lasso(alpha=alpha)
lasso.fit(X, y)
print(f"Lasso coefficient size: {lasso.coef_.size}")
print(f"Lasso coef:{lasso.coef_}")
print(f"Lasso alpha: {lasso.alpha}")
# 针对Lasso的交叉验证得分
lasso_scores = cross_val_score(lasso, X, y, scoring='neg_mean_squared_error', cv=10)
print(f"Lasso neg_mean_squared_error: {lasso_scores.mean()}")
#Lasso回归交叉验证
lassocv = LassoCV(alphas=[alpha], cv=3).fit(X, y)
y_pred_lasso = cross_val_predict(lassocv, X, y, cv=3)
#print(y_pred_lasso)
# 绘制lasso回归系数
lacoefficients =lasso.coef_
plt.figure(figsize=(10,6))
plt.bar(range(len(lacoefficients)),lacoefficients)
plt.title('Lasso coefficients')
plt.xlabel('Feature Index')
plt.ylabel('coefficient value')
plt.show()
# 绘制变量惩罚曲线
plt.figure(figsize=(10, 5))
plt.subplot(1, 1, 1)
plt.title("Lasso CV: $\ alpha=$ Best: %.2f, Mean: %.2f" % (lassocv.alpha_, np.mean(lassocv.mse_path_)))
plt.plot(lassocv.mse_path_, color='blue', marker='o', label='Lasso MSE')
plt.xlabel('Iterations')
plt.ylabel('Mean Squared Error')
plt.legend()
# 岭回归
ridge = Ridge(alpha=alpha)
ridge.fit(X, y)
print(f"Ridge coefficient size: {ridge.coef_.size}")
print(f"Ridge coef:{ridge.coef_}")
print(f"Ridge alpha: {ridge.alpha}")
# 针对岭回归的交叉验证得分
ridge_scores = cross_val_score(ridge, X, y, scoring='neg_mean_squared_error', cv=10)
print(f"Ridge neg_mean_squared_error: {ridge_scores.mean()}")
# 绘制岭回归系数
licoefficients =ridge.coef_
plt.figure(figsize=(10,6))
plt.bar(range(len(licoefficients)),licoefficients)
plt.title('Ridge coefficients')
plt.xlabel('Feature Index')
plt.ylabel('coefficient value')
plt.show()
# 弹性网络
elastic_net = ElasticNet(alpha=alpha, l1_ratio=0.5)
elastic_net.fit(X, y)
print(f"ElasticNet coefficient size: {elastic_net.coef_.size}")
print(f"ElasticNet coef:{elastic_net.coef_}")
print(f"ElasticNet alpha: {elastic_net.alpha}")
print(f"ElasticNet l1_ratio: {elastic_net.l1_ratio}")
# 针对弹性网络的交叉验证得分
elastic_net_scores = cross_val_score(elastic_net, X, y, scoring='neg_mean_squared_error', cv=10)
print(f"ElasticNet neg_mean_squared_error: {elastic_net_scores.mean()}")
#弹性网络回归交叉验证
elastic_netcv = ElasticNetCV(alphas=[alpha], cv=3).fit(X, y)
y_pred_elastic_net = cross_val_predict(elastic_netcv, X, y, cv=3)
#print(y_pred_elastic_net)
# 绘制弹性网络回归系数
encoefficients =elastic_net.coef_
plt.figure(figsize=(10,6))
plt.bar(range(len(encoefficients)),encoefficients)
plt.title('ElasticNet coefficients')
plt.xlabel('Feature Index')
plt.ylabel('coefficient value')
plt.show()
# 绘制变量惩罚曲线
plt.title("ElasticNet CV: $\ alpha=$ Best: %.2f, Mean: %.2f" % (elastic_netcv.alpha_, np.mean(elastic_netcv.mse_path_)))
plt.plot(elastic_netcv.mse_path_, color='blue', marker='o', label='ElasticNet MSE')
plt.xlabel('Iterations')
plt.ylabel('Mean Squared Error')
plt.legend()
# 绘制结果
plt.figure()
plt.scatter(range(1000), y, color='black')
plt.scatter(range(1000), y_pred_lasso, color='blue')
plt.scatter(range(1000), y_pred_elastic_net, color='red')
plt.legend(('Data', 'Lasso', 'Elastic Net'), loc='upper left')
plt.xlabel('Sample index')
plt.ylabel('Target value')
plt.show()
医学统计数据分析分享交流SPSS、R语言、Python、ArcGis、Geoda、GraphPad、数据分析图表制作等心得。承接数据分析,论文修回,医学统计,空间分析,问卷分析业务。若有投稿和数据分析代做需求,可以直接联系我,谢谢!