01-logistic回归模型的
lasso回归、岭回归、弹性网络回归代码
Logistic回归的正则化变体
-Lasso回归(L1正则化)
概念:在logistic回归基础上加入L1正则化项
原理:通过绝对值惩罚项实现特征选择和系数压缩
思想:`损失函数 + λ∑|β|`,可将不重要的特征系数压缩为0
应用:高维数据、特征选择、简化模型
-岭回归(L2正则化)
概念:在logistic回归基础上加入L2正则化项
原理:通过平方惩罚项控制系数大小
思想:`损失函数 + λ∑β²`,防止过拟合,提高泛化能力
应用:多重共线性数据、防止过拟合
-弹性网络(Elastic Net)
概念:结合L1和L2正则化的混合方法
原理:`损失函数 + λ₁∑|β| + λ₂∑β²`
思想:兼具特征选择和防止过拟合的优点
应用:高维数据且特征间高度相关的情况
一、导入库,设置中文字体支持。
二、读取示例数据集,数据预处理(如分类变量转虚拟变量)。
三、准备自变量和因变量,特征标准化。
四、设置正则化参数范围。
五、分别进行Lasso、岭回归、弹性网络回归分析,包括交叉验证选择最佳参数。
六、重新训练模型。
七、创建结果表格,显示系数。
八、生成变量重要性图和正则化路径图。
九、开始创建Word报告。
Python代码实现了一个完整的逻辑回归正则化分析流程,专注于使用Lasso回归、岭回归和弹性网络回归来处理二元分类问题,并通过自动化步骤从数据预处理到报告生成。
# pip install pandas numpy scikit-learn matplotlib seaborn python-docx openpyxl
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegressionCV, LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import accuracy_score, roc_auc_score, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns
from docx import Document
from docx.shared import Inches
import os
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 创建结果文件夹
results_dir = os.path.expanduser("~/Desktop/Results模型-lasso")
if not os.path.exists(results_dir):
os.makedirs(results_dir)
# 读取数据
data = pd.read_excel("~/Desktop/示例数据.xlsx")
# 数据预处理
# 将分类变量转换为虚拟变量
categorical_cols = ['指标8', '肥胖程度', '教育水平', '血型']
data = pd.get_dummies(data, columns=categorical_cols, drop_first=False)
# 准备自变量和因变量
X = data.drop(['序号', '结局'], axis=1)
y = data['结局']
# 特征名称(用于后续结果展示)
feature_names = X.columns.tolist()
# 标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_scaled = pd.DataFrame(X_scaled, columns=feature_names)
# 设置正则化参数范围
Cs = np.logspace(-4, 4, 100) # C是1/λ,所以需要取倒数
# 获取系数
ridge_coef = ridge_final.coef_[0]
best_lambda_en = 1 / best_C_en
# 使用最佳参数重新训练模型
en_final = LogisticRegression(
C=best_C_en,
penalty='elasticnet',
solver='saga',
l1_ratio=best_l1_ratio,
random_state=42,
max_iter=10000
)
en_final.fit(X_scaled, y)
# 获取系数
en_coef = en_final.coef_[0]
# 创建结果表格
results_df = pd.DataFrame({
'Variable': ['(Intercept)'] + feature_names,
'Lasso_coef': np.concatenate([[lasso_final.intercept_[0]], lasso_coef]),
'Ridge_coef': np.concatenate([[ridge_final.intercept_[0]], ridge_coef]),
'EN_coef': np.concatenate([[en_final.intercept_[0]], en_coef])
})
# 保存结果表格
results_df.to_csv(os.path.join(results_dir, 'regression_results.csv'), index=False, encoding='utf-8-sig')
# 创建变量重要性图 (基于Lasso回归)
lasso_importance = pd.DataFrame({
'Variable': feature_names,
'Importance': np.abs(lasso_coef)
}).sort_values('Importance', ascending=False)
plt.figure(figsize=(12, 10))
plt.barh(range(len(lasso_importance)), lasso_importance['Importance'], align='center')
plt.yticks(range(len(lasso_importance)), lasso_importance['Variable'])
plt.xlabel('系数绝对值')
plt.title('变量重要性 (基于Lasso回归)')
plt.tight_layout()
plt.savefig(os.path.join(results_dir, 'variable_importance.jpg'), dpi=300, bbox_inches='tight')
plt.savefig(os.path.join(results_dir, 'variable_importance.pdf'), bbox_inches='tight')
plt.close()
# 创建前20个最重要变量图
top_20 = lasso_importance.head(20)
plt.figure(figsize=(12, 8))
plt.barh(range(len(top_20)), top_20['Importance'], align='center')
plt.yticks(range(len(top_20)), top_20['Variable'])
plt.xlabel('系数绝对值')
plt.title('前20个最重要变量 (基于Lasso回归)')
plt.tight_layout()
plt.savefig(os.path.join(results_dir, 'variable_importance_top20.jpg'), dpi=300, bbox_inches='tight')
plt.savefig(os.path.join(results_dir, 'variable_importance_top20.pdf'), bbox_inches='tight')
plt.close()
# 创建正则化路径图 (使用不同C值计算系数)
print("创建正则化路径图...")
C_values = np.logspace(-2, 2, 50)
lasso_path = np.zeros((len(C_values), len(feature_names)))
ridge_path = np.zeros((len(C_values), len(feature_names)))
for i, C in enumerate(C_values):
# Lasso路径
lasso_temp = LogisticRegression(
C=C,
penalty='l1',
solver='liblinear',
random_state=42,
max_iter=10000
)
lasso_temp.fit(X_scaled, y)
lasso_path[i, :] = lasso_temp.coef_[0]
# Ridge路径
ridge_temp = LogisticRegression(
C=C,
penalty='l2',
solver='liblinear',
random_state=42,
max_iter=10000
)
ridge_temp.fit(X_scaled, y)
ridge_path[i, :] = ridge_temp.coef_[0]
# 绘制Lasso路径图
plt.figure(figsize=(10, 6))
for i in range(len(feature_names)):
plt.plot(C_values, lasso_path[:, i], label=feature_names[i] if i < 10 else"")
plt.xscale('log')
plt.xlabel('C (1/λ)')
plt.ylabel('系数值')
plt.title('Lasso回归系数路径')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.savefig(os.path.join(results_dir, 'lasso_coefficient_path.jpg'), dpi=300, bbox_inches='tight')
plt.savefig(os.path.join(results_dir, 'lasso_coefficient_path.pdf'), bbox_inches='tight')
plt.close()
# 绘制Ridge路径图
plt.figure(figsize=(10, 6))
for i in range(len(feature_names)):
plt.plot(C_values, ridge_path[:, i], label=feature_names[i] if i < 10 else"")
plt.xscale('log')
plt.xlabel('C (1/λ)')
plt.ylabel('系数值')
plt.title('岭回归系数路径')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.savefig(os.path.join(results_dir, 'ridge_coefficient_path.jpg'), dpi=300, bbox_inches='tight')
plt.savefig(os.path.join(results_dir, 'ridge_coefficient_path.pdf'), bbox_inches='tight')
plt.close()
# 创建Word报告
print("创建Word报告...")
doc = Document()
# 添加标题
doc.add_heading('正则化Logistic回归分析报告', 0)
doc.add_paragraph(f'生成日期: {pd.Timestamp.now().strftime("%Y-%m-%d")}')
doc.add_paragraph()
# 添加数据概览
doc.add_heading('数据概览', level=1)
doc.add_paragraph(f'样本量: {len(data)}')
doc.add_paragraph(f'结局变量分布: 0 = {sum(y == 0)}, 1 = {sum(y == 1)}')
doc.add_paragraph()
# 添加方法说明
doc.add_heading('分析方法', level=1)
doc.add_paragraph('本报告使用了三种正则化Logistic回归方法:')
doc.add_paragraph('- Lasso回归 (L1正则化): 同时进行变量选择和正则化')
doc.add_paragraph('- 岭回归 (L2正则化): 主要用于处理多重共线性问题')
doc.add_paragraph('- 弹性网络回归: Lasso和岭回归的折中方法')
doc.add_paragraph('所有分类变量已转换为虚拟变量进行处理。')
doc.add_paragraph()
# 添加最佳参数值
doc.add_heading('最佳参数值', level=1)
doc.add_paragraph(f'Lasso回归最佳C值: {best_C_lasso:.4f} (λ = {best_lambda_lasso:.4f})')
doc.add_paragraph(f'岭回归最佳C值: {best_C_ridge:.4f} (λ = {best_lambda_ridge:.4f})')
doc.add_paragraph(f'弹性网络回归最佳C值: {best_C_en:.4f} (λ = {best_lambda_en:.4f}), 最佳l1_ratio: {best_l1_ratio:.2f}')
doc.add_paragraph()
# 添加结果表格
doc.add_heading('回归系数结果', level=1)
doc.add_paragraph('下表展示了三种方法的系数估计:')
# 创建表格
table = doc.add_table(rows=1, cols=4)
table.style = 'Table Grid'
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '变量'
hdr_cells[1].text = 'Lasso系数'
hdr_cells[2].text = '岭回归系数'
hdr_cells[3].text = '弹性网络系数'
# 添加数据行
for _, row in results_df.iterrows():
row_cells = table.add_row().cells
row_cells[0].text = str(row['Variable'])
row_cells[1].text = f"{row['Lasso_coef']:.4f}"
row_cells[2].text = f"{row['Ridge_coef']:.4f}"
row_cells[3].text = f"{row['EN_coef']:.4f}"
doc.add_paragraph()
# 添加变量重要性说明
doc.add_heading('变量重要性', level=1)
doc.add_paragraph('基于Lasso回归的系数绝对值,前10个最重要变量排序如下:')
for i, (_, row) in enumerate(lasso_importance.head(10).iterrows(), 1):
doc.add_paragraph(f'{i}. {row["Variable"]} ({row["Importance"]:.4f})')
doc.add_paragraph()
doc.add_paragraph('完整变量重要性图表已保存至Results模型-lasso文件夹。')
# 添加图片说明
doc.add_heading('模型可视化', level=1)
doc.add_paragraph('系数路径图展示了随着正则化参数变化,模型系数的收缩情况。')
doc.add_paragraph('所有可视化图表已保存至Results模型-lasso文件夹。')
# 保存Word文档
doc.save(os.path.join(results_dir, 'regression_analysis_report.docx'))
print("分析完成!所有结果已保存到Results模型-lasso文件夹中,包括:")
print("- 三种回归方法的系数路径图 (JPG和PDF格式)")
print("- 变量重要性图 (JPG和PDF格式)")
print("- 回归系数结果表格 (CSV格式)")
print("- 完整分析报告 (Word格式)")
- 代码首先导入必要的Python库并设置中文字体支持,以确保分析环境正确配置。
- 随后读取一个示例数据集,并进行数据预处理,包括将分类变量转换为虚拟变量,以准备数据用于建模。
- 接着准备自变量和因变量,并对特征进行标准化处理,以提高模型性能。
- 代码设置了正则化参数范围,并分别进行Lasso回归、岭回归和弹性网络回归分析;对于每种方法,都使用交叉验证来选择最佳参数(如C值或l1_ratio),并基于最佳参数重新训练模型。
- 此外,代码创建了结果表格来显示不同回归方法的系数,并生成了可视化输出,如变量重要性图和正则化路径图,以辅助结果解读。
- 最后,代码开始创建一个Word报告,整合分析结果和图表,实现成果的自动化输出。
Python常用库
-数据读取(如pandas)、
-机器学习建模(如scikit-learn)、
-可视化(如matplotlib)
-报告生成(如python-docx)
- 整段代码的应用:
- 该代码适用于需要处理高维数据或避免过拟合的二元分类场景,例如在医学研究、金融风险预测或社会科学中评估变量重要性并构建稳健的预测模型。
- 自动化流程增强了分析的可重复性和效率,适合用于教学演示、快速原型开发或生成学术报告中的模型结果。
- 通过正则化方法(如Lasso和弹性网络),代码有助于变量筛选和模型优化,为决策支持提供基础。
医学统计数据分析分享交流SPSS、R语言、Python、ArcGis、Geoda、GraphPad、数据分析图表制作等心得。承接数据分析,论文返修,医学统计,机器学习,生存分析,空间分析,问卷分析业务。若有投稿和数据分析代做需求,可以直接联系我,谢谢!
“医学统计数据分析”公众号右下角;
找到“联系作者”,
可加我微信,邀请入粉丝群!
有临床流行病学数据分析
如(t检验、方差分析、χ2检验、logistic回归)、
(重复测量方差分析与配对T检验、ROC曲线)、
(非参数检验、生存分析、样本含量估计)、
(筛检试验:灵敏度、特异度、约登指数等计算)、
(绘制柱状图、散点图、小提琴图、列线图等)、
机器学习、深度学习、生存分析
等需求的同仁们,加入【临床】粉丝群。
疾控,公卫岗位的同仁,可以加一下【公卫】粉丝群,分享生态学研究、空间分析、时间序列、监测数据分析、时空面板技巧等工作科研自动化内容。
有实验室数据分析需求的同仁们,可以加入【生信】粉丝群,交流NCBI(基因序列)、UniProt(蛋白质)、KEGG(通路)、GEO(公共数据集)等公共数据库、基因组学转录组学蛋白组学代谢组学表型组学等数据分析和可视化内容。
或者可扫码直接加微信进群!!!
精品视频课程-“医学统计数据分析”视频号付费合集
在“医学统计数据分析”视频号-付费合集兑换相应课程后,获取课程理论课PPT、代码、基础数据等相关资料,请大家在【医学统计数据分析】公众号右下角,找到“联系作者”,加我微信后打包发送。感谢您的支持!!
【二分类因变量机器学习】图文教程
往期推荐:【监测预警自动化】系列教程
往期推荐:样本含量估计(样本量计算与功效分析)
往期推荐:SPSS、R语言、Python等临床数据分析专题
往期推荐:科研图表绘制专题
往期推荐:重复测量数据分析专题
往期推荐:生信分析、基因测序数据、实验室数据专题
往期推荐:生存分析及机器学习
往期推荐:时间序列分析
往期推荐:地统计分析-GIS、地图、相关、聚类、回归
往期推荐:科研自动化探究
往期推荐:趣味阅读
统计评书系列

