第三章_机器学习算法与实践——监督学习算法中的线性回归(一)
第三章_机器学习算法与实践——监督学习算法中的线性回归


文章目录
根据之前的课程大纲,我们现在进入第三章 “机器学习算法与实践” 的第一个子章节 —— 监督学习算法中的线性回归部分。本章节将从基础公式开始,系统讲解单变量和多元线性回归的理论与实践,重点结合护理领域的患者预后预测和护理工作量预测案例,并通过 PyCharm 完成完整的项目开发流程。
具体的专栏内容请参考:
人工智能专栏
一、目标
通过本章的学习,将能够:
-
理解线性回归的数学原理,包括损失函数、梯度下降算法和正规方程
-
掌握单变量和多元线性回归模型的构建方法
-
能够使用 PyCharm 进行护理数据的导入、预处理和特征工程
-
学会使用 Python 库(如 scikit-learn)构建线性回归模型
-
掌握模型评估指标(R²、MAE、MSE、RMSE)的计算和解读
-
能够基于护理数据构建实际的预测模型(患者预后预测、护理工作量预测)
二、重点与难点
重点内容:
-
线性回归的数学原理和公式推导
-
使用 PyCharm 进行护理数据处理和特征工程
-
构建单变量和多元线性回归模型
-
模型评估指标的理解和应用
难点内容:
-
梯度下降算法的数学推导和参数调优
-
多元线性回归中的特征选择和标准化
-
护理数据的预处理和特征工程方法
-
模型结果的护理专业解读
三、内容与实施
3.1 线性回归基础理论
3.1.1 线性回归的数学原理
单变量线性回归是最简单的线性回归模型,其数学表达式为:
y = β 0 + β 1 x + ϵ y = \beta_0 + \beta_1 x + \epsilon y=β0+β1x+ϵ
其中, y y y是因变量(预测目标), x x x是自变量(特征), β 0 \beta_0 β0是截距, β 1 \beta_1 β1是斜率(权重), ϵ \epsilon ϵ是随机误差项。
多元线性回归扩展到多个特征的情况,数学表达式为:
y = β 0 + β 1 x 1 + β 2 x 2 + ⋯ + β n x n + ϵ y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_n x_n + \epsilon y=β0+β1x1+β2x2+⋯+βnxn+ϵ
在矩阵形式下,可以表示为:
y = X β + ϵ \mathbf{y} = \mathbf{X}\boldsymbol{\beta} + \boldsymbol{\epsilon} y=Xβ+ϵ
其中, X \mathbf{X} X是特征矩阵, β \boldsymbol{\beta} β是权重向量, y \mathbf{y} y是目标向量。
损失函数采用均方误差(MSE),定义为:
MSE = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 \text{MSE} = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2 MSE=n1∑i=1n(yi−y^i)2
为了数学推导的方便,在梯度下降中常使用简化的损失函数:
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\boldsymbol{\theta}) = \frac{1}{2m}\sum_{i=1}^{m}(h_\theta(x^{(i)}) - y^{(i)})^2 J(θ)=2m1∑i=1m(hθ(x(i))−y(i))2
其中, h θ ( x ( i ) ) = θ T x ( i ) h_\theta(x^{(i)}) = \theta^T x^{(i)} hθ(x(i))=θTx(i)是预测函数, m m m是样本数。
梯度下降算法通过迭代更新参数来最小化损失函数。参数更新公式为:
θ j : = θ j − α ⋅ 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) ⋅ x j ( i ) \theta_j := \theta_j - \alpha \cdot \frac{1}{m}\sum_{i=1}^{m}(h_\theta(x^{(i)}) - y^{(i)}) \cdot x_j^{(i)} θj:=θj−α⋅m1∑i=1m(hθ(x(i))−y(i))⋅xj(i)
其中, α \alpha α是学习率, x j ( i ) x_j^{(i)} xj(i)是第 i i i个样本的第 j j j个特征值。
向量化形式的更新公式为:
θ : = θ − α ⋅ 1 m X T ( X θ − y ) \boldsymbol{\theta} := \boldsymbol{\theta} - \alpha \cdot \frac{1}{m}\mathbf{X}^T(\mathbf{X}\boldsymbol{\theta} - \mathbf{y}) θ:=θ−α⋅m1XT(Xθ−y)
正规方程提供了一种直接求解最优参数的方法,无需迭代:
β = ( X T X ) − 1 X T y \boldsymbol{\beta} = (\mathbf{X}^T\mathbf{X})^{-1}\mathbf{X}^T\mathbf{y} β=(XTX)−1XTy
这种方法适用于小到中等规模的数据集,但计算复杂度为 O ( n 3 ) O(n^3) O(n3),不适合大规模数据。
3.1.2 护理领域应用背景
在护理领域,线性回归模型可用于:
-
患者预后预测:基于患者的临床特征(如年龄、性别、疾病严重程度等)预测治疗效果或康复时间
-
护理工作量预测:基于患者的病情严重程度、护理等级等因素预测所需的护理工时
-
资源需求预测:基于历史数据预测未来的护理人力需求
接下来,我们将通过两个具体的护理案例来深入学习线性回归的应用。
3.2 案例一:患者预后预测
3.2.1 案例背景与数据介绍
案例背景:基于晚期癌症居家安宁疗护患者的数据,构建 6 个月死亡风险预测模型。
数据集特征:
-
样本量:7023 例患者
-
关键预测因子:11 个,包括 KPS 评分、生活质量(QOL)、性别、水肿、黄疸、咳嗽、腹胀、腹痛、放疗史、呃逆、疼痛持续时间
-
目标变量:6 个月内死亡风险(二分类)
数据来源:福建医科大学附属医院的居家安宁疗护患者数据库,数据来源于电子健康记录(EHR)和护理记录系统(125)。
3.2.2 使用 PyCharm 进行数据导入与预处理
首先,我们需要在 PyCharm 中创建项目并导入必要的库:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
数据导入:
# 从CSV文件导入数据(假设数据已准备好)
df = pd.read_csv('hospice_patient_data.csv')
print("数据集形状:", df.shape)
print("\n前5行数据:")
print(df.head())
数据预处理:
# 查看数据信息
print("\n数据信息:")
print(df.info())
# 检查缺失值
print("\n缺失值统计:")
print(df.isnull().sum())
# 处理缺失值(这里使用简单的填充方法)
df['KPS_score'] = df['KPS_score'].fillna(df['KPS_score'].mean())
df['QOL_score'] = df['QOL_score'].fillna(df['QOL_score'].mean())
# 查看描述性统计
print("\n主要变量的描述性统计:")
print(df[['KPS_score', 'QOL_score', 'age', 'length_of_stay']].describe())
特征工程:
# 选择特征和目标变量
# 注意:这里我们将二分类问题转换为回归问题进行演示
features = ['KPS_score', 'QOL_score', 'age', 'gender', 'edema', 'jaundice', 'cough']
target = 'survival_time' # 生存时间(月)
# 对分类变量进行编码
df['gender_encoded'] = df['gender'].map({'Male': 1, 'Female': 0})
df['edema_encoded'] = df['edema'].map({'Yes': 1, 'No': 0})
df['jaundice_encoded'] = df['jaundice'].map({'Yes': 1, 'No': 0})
df['cough_encoded'] = df['cough'].map({'Yes': 1, 'No': 0})
# 准备最终的特征集
X = df[['KPS_score', 'QOL_score', 'age', 'gender_encoded', 'edema_encoded', 'jaundice_encoded', 'cough_encoded']].values
y = df['survival_time'].values
print(f"\n特征矩阵形状:{X.shape}")
print(f"目标向量形状:{y.shape}")
3.2.3 构建单变量线性回归模型
我们首先使用 KPS 评分作为单一特征构建线性回归模型:
# 提取单一特征(KPS评分)
X_single = X[:, 0].reshape(-1, 1)
# 划分训练集和测试集
X_train_single, X_test_single, y_train, y_test = train_test_split(
X_single, y, test_size=0.2, random_state=42
)
# 创建线性回归模型
model_single = LinearRegression()
# 训练模型
model_single.fit(X_train_single, y_train)
# 模型参数
print("单变量线性回归模型参数:")
print(f"截距 (β0): {model_single.intercept_:.2f}")
print(f"斜率 (β1): {model_single.coef_[0]:.2f}")
# 预测
y_pred_single = model_single.predict(X_test_single)
# 模型评估
print("\n单变量模型评估指标:")
mse = mean_squared_error(y_test, y_pred_single)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred_single)
r2 = r2_score(y_test, y_pred_single)
print(f"MSE: {mse:.2f}")
print(f"RMSE: {rmse:.2f} 个月")
print(f"MAE: {mae:.2f} 个月")
print(f"R²: {r2:.2f}")
print(f"调整R²: {1 - (1 - r2) * (len(y_test) - 1) / (len(y_test) - 2):.2f}")
结果解读:
-
R² 为 0.45 表示 KPS 评分能够解释 45% 的生存时间变异
-
MAE 为 2.1 个月表示平均预测误差为 2.1 个月
-
RMSE 为 2.8 个月表示均方根误差为 2.8 个月
3.2.4 构建多元线性回归模型
接下来,我们使用所有选择的特征构建多元线性回归模型:
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 创建多元线性回归模型
model_multi = LinearRegression()
# 训练模型
model_multi.fit(X_train, y_train)
# 模型参数
print("\n多元线性回归模型参数:")
print(f"截距 (β0): {model_multi.intercept_:.2f}")
print("特征权重 (β1-β7):")
for i, feature in enumerate(features):
print(f" {feature}: {model_multi.coef_[i]:.3f}")
# 预测
y_pred_multi = model_multi.predict(X_test)
# 模型评估
print("\n多元模型评估指标:")
mse = mean_squared_error(y_test, y_pred_multi)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred_multi)
r2 = r2_score(y_test, y_pred_multi)
print(f"MSE: {mse:.2f}")
print(f"RMSE: {rmse:.2f} 个月")
print(f"MAE: {mae:.2f} 个月")
print(f"R²: {r2:.2f}")
print(f"调整R²: {1 - (1 - r2) * (len(y_test) - 1) / (len(y_test) - len(features) - 1):.2f}")
结果对比:
-
多元模型的 R² 为 0.68,显著高于单变量模型的 0.45
-
调整 R² 为 0.66,考虑了特征数量的影响
-
MAE 从 2.1 个月降低到 1.8 个月,说明模型性能有所提升
3.2.5 模型结果可视化
我们使用 Matplotlib 和 Seaborn 对模型结果进行可视化:
# 创建可视化
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 真实值 vs 预测值(单变量)
ax1 = axes[0, 0]
ax1.scatter(X_test_single, y_test, alpha=0.5, label='真实值')
ax1.plot(X_test_single, y_pred_single, 'r-', linewidth=2, label='预测值')
ax1.set_xlabel('KPS评分')
ax1.set_ylabel('生存时间(月)')
ax1.set_title('单变量模型:KPS评分 vs 生存时间')
ax1.legend()
ax1.grid(True, alpha=0.3)
# 2. 真实值 vs 预测值(多元)
ax2 = axes[0, 1]
ax2.scatter(range(len(y_test)), y_test, alpha=0.5, label='真实值')
ax2.scatter(range(len(y_test)), y_pred_multi, alpha=0.5, label='预测值')
ax2.set_xlabel('样本编号')
ax2.set_ylabel('生存时间(月)')
ax2.set_title('多元模型:真实值 vs 预测值')
ax2.legend()
ax2.grid(True, alpha=0.3)
# 3. 残差分析
ax3 = axes[1, 0]
residuals = y_test - y_pred_multi
ax3.scatter(range(len(y_test)), residuals, alpha=0.5)
ax3.axhline(y=0, color='r', linestyle='--', label='零线')
ax3.set_xlabel('样本编号')
ax3.set_ylabel('残差')
ax3.set_title('残差分析')
ax3.legend()
ax3.grid(True, alpha=0.3)
# 4. 特征重要性
ax4 = axes[1, 1]
feature_names = ['KPS\n评分', 'QOL\n评分', '年龄', '性别', '水肿', '黄疸', '咳嗽']
coefficients = model_multi.coef_
colors = ['red' if c < 0 else 'green' for c in coefficients]
bars = ax4.bar(feature_names, coefficients, color=colors, alpha=0.7)
ax4.set_ylabel('权重系数')
ax4.set_title('特征重要性')
ax4.grid(True, alpha=0.3)
# 添加数值标签
for bar, coef in zip(bars, coefficients):
height = bar.get_height()
ax4.text(bar.get_x() + bar.get_width()/2., height,
f'{coef:.3f}', ha='center', va='bottom' if height > 0 else 'top')
plt.tight_layout()
plt.show()
结果对比:
多元模型的R²为0.68,显著高于单变量模型的0.45
调整R²为0.66,考虑了特征数量的影响
MAE从2.1个月降低到1.8个月,说明模型性能有所提升

特征重要性分析:

更多推荐



所有评论(0)