Python进行lasso回归、岭回归、弹性网络回归操作示例

文摘   2025-01-23 07:12   山东  


什么是lasso回归?

‌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、数据分析图表制作等心得。承接数据分析,论文修回,医学统计,空间分析,问卷分析业务。若有投稿和数据分析代做需求,可以直接联系我,谢谢!





医学统计数据分析
分享交流SPSS、R语言、Python、ArcGis、Geoda、GraphPad、数据分析图表制作等心得。承接数据分析,论文修回,医学统计,空间分析,问卷分析业务。若有投稿和数据分析代做需求,可以直接联系我,谢谢!
 最新文章