医学数据分析实训 项目四回归分析--预测帕金森病病情的严重程度

文章目录

项目四:回归分析

实践目的

  • 熟悉并掌握线性回归模型及其使用方法;
  • 理解回归分析算法并能使用回归模型分析数据集;
  • 熟悉模型性能评估的方法;

实践平台

  • 操作系统:Windows 7 及以上
  • Python 版本:3.8.x 及以上
  • 开发环境:PyCharm 或 Anoconda 集成环境

实践内容

数据集:"parkinsons_updrs.data",专注于通过远程监测设备记录帕金森病患者的语音信号来预测病情严重程度。

主要属性

  • subject#:受试者编号;
  • age:受试者年龄;
  • sex:受试者性别;
  • test_time:从招募日期开始的时间间隔;
  • motor_UPDRS:运动症状帕金森病评分量表分数;
  • total_UPDRS:总体帕金森病评分量表分数;
  • Jitter(%):声音信号频率抖动的百分比;
  • Jitter(Abs):声音信号频率抖动的绝对值;
  • Jitter:RAP:声音信号频率抖动的相对平均扰动;
  • Jitter:PPQ5:与五个周期相关的频率抖动特征;
  • Jitter:DDP:与差分相关的频率抖动特征;
  • Shimmer:声音信号振幅的抖动;
  • Shimmer(dB):以分贝为单位的振幅抖动;
  • Shimmer:APQ3:与三个周期相关的振幅抖动特征;
  • Shimmer:APQ5:与五个周期相关的振幅抖动特征;
  • Shimmer:APQ11:与十一个周期相关的振幅抖动特征;
  • Shimmer:DDA:与差分相关的振幅抖动特征;
  • NHR:噪声谐波比;
  • HNR:谐波噪声比;
  • RPDE:循环周期密度熵;
  • DFA:趋势波动分析;
  • PPE: 基频变化的非线性测量。

步骤

  1. 数据读入及理解

    • 导入所需Python包;
    • 将数据读入DataFrame格式,查看前5行数据;
    • 使用describe()info()方法和shape属性进行探索性分析;
  2. 数据准备

    • 数据清洗:处理缺失值、重复值、异常值;
    • 标准化处理;
    • 使用Seaborn.pairplot()可视化展示"Jitter:RAP"、"Jitter:DDP"、"Shimmer:DDA"与"motor_UPDRS"、"total_UPDRS"的相关性;
    • 准备特征矩阵(X)和目标向量(y);
  3. 模型建立

    • 使用train_test_split()方法划分训练集和测试集(random_state=1,25%测试,75%训练);
    • 使用LinearRegression进行线性回归,并通过score()方法输出模型准确率;
  4. 模型预测

    • 输出预测值(y_pred);
    • 对比y_pred与y_test;
  5. 模型评价及优化

    • 使用sklearn.metrics模块中的MSE、RMSE、R²对模型进行评价;
    • 建立岭回归或Lasso回归模型,进行训练和预测;
    • 对岭回归或Lasso回归模型进行评价;
    • 对比两种模型预测结果。

预测帕金森病病情的严重程度作业

(一)数据读入及理解

python 复制代码
# 1. 导入本案例所需的 Python 包
import json
import os
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
# 显示负号
plt.rcParams['axes.unicode_minus'] = False

# 2. 将数据读入并存为 DataFrame 格式,查看前 5 行数据
data = pd.read_csv('input/parkinsons_updrs.data')
print(data.head())
python 复制代码
# 3. 通过 describe()、info()方法和 shape 属性等方法对读入的数据对象进行探索性分析
# 显示数据的基本统计信息
print(data.describe())
# 显示数据的信息
print(data.info())
# 显示数据的形状
print(f"数据形状: {data.shape}")

(二)数据准备

python 复制代码
# 1.	对数据集从缺失值、重复值、异常值等方面进行数据清洗;

# 检查缺失值
print('缺失值情况:', data.isnull().sum())
# 处理缺失值(假设用均值填充)
# data.fillna(data.mean(), inplace=True)

# 检查重复值
print("\n重复值数量:", data.duplicated().sum())
# 删除重复值
# data.drop_duplicates(inplace=True)
python 复制代码
# 异常值处理(假设使用 IQR 方法)
Q1 = data.quantile(0.25, axis=0)
Q3 = data.quantile(0.75, axis=0)
IQR = Q3 - Q1

# 定义异常值范围
outliers = ((data < (Q1 - 1.5 * IQR)) | (data > (Q3 + 1.5 * IQR)))

# 替换异常值(例如用中位数)
for column in data.columns:
    if column in outliers.columns:
        data.loc[outliers[column], column] = data[column].median()

# 查看异常值处理后的数据
print("异常值处理后的数据:\n", data.head())
python 复制代码
# 2.对数据进行标准化处理;
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

# 选定需要标准化的特征(排除非数值类型特征)
features = ["Jitter:RAP", "Jitter:DDP", "Shimmer:DDA"]
data[features] = scaler.fit_transform(data[features])

print("标准化后的数据:\n", data.head())

# 3. 通过 Seaborn.pairplot()可视化展示"Jitter:RAP","Jitter:DDP","Shimmer:DDA"与"motor_UPDRS","total_UPDRS"的相关性;
selected_columns = ['Jitter:RAP', 'Jitter:DDP', 'Shimmer:DDA', 'motor_UPDRS', 'total_UPDRS']

# 绘制 pairplot
sns.pairplot(data[selected_columns])
plt.show()
python 复制代码
# 4.	进行回归分析前,准备好模型所需的特征矩阵(X)和目标向量(y)。
# # 特征矩阵
# X = data[["Jitter:RAP", "Jitter:DDP", "Shimmer:DDA","total_UPDRS"]]
# 
# # 目标变量
# y_motor = data["motor_UPDRS"]
# 准备特征矩阵(X)和目标向量(y)

X = data[["Jitter:RAP", "Jitter:DDP", "Shimmer:DDA","total_UPDRS"]]
y_motor = data['motor_UPDRS']
y_total = data['total_UPDRS']

# 查看特征矩阵和目标向量的形状
print("特征矩阵 X 的形状:", X.shape)
print("目标向量 y_motor 的形状:", y_motor.shape[0])
print("目标向量 y_total 的形状:", y_total.shape[0])

特征矩阵 X 的形状: (5875, 4)

目标向量 y_motor 的形状: 5875

目标向量 y_total 的形状: 5875

(三)模型建立

python 复制代码
# 1 调用 sklearn.model_selection 中的 train_test_split() 方法进行训练集和测试集的拆分
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

#  X 和 y_motor 已经定义
# X = data.drop(['motor_UPDRS', 'total_UPDRS'], axis=1)
# y_motor = data['motor_UPDRS']

# 拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y_motor, test_size=0.25, random_state=1)

# 查看训练数据和测试数据的数量
print("训练数据数量:", len(X_train))
print("测试数据数量:", len(X_test))

训练数据数量: 4406

测试数据数量: 1469

python 复制代码
# 2.	调用 sklearn.linear_model 中的 LinearRegression 对训练集进行线性回归,并通过 score()方法输出模型的准确率;
# 创建线性回归模型
linear_reg = LinearRegression()

# 训练模型
linear_reg.fit(X_train, y_train)

# 输出模型的准确率(R^2 分数)
train_score = linear_reg.score(X_train, y_train)
test_score = linear_reg.score(X_test, y_test)

print("训练集准确率 (R^2):", train_score)
print("测试集准确率 (R^2):", test_score)

训练集准确率 (R^2): 0.8968939783000226

测试集准确率 (R^2): 0.8984946250185042

(四)模型预测

python 复制代码
# 1.	输出预测值(y_pred);
# 使用训练好的模型进行预测
y_pred = linear_reg.predict(X_test)

# 输出预测值
print("预测值 (y_pred):", y_pred)
python 复制代码
# 2.	通过可视化图表对 y_pred 和 y_test 进行对比;
import matplotlib.pyplot as plt

# 设置显示中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
# 设置正常显示符号
plt.rcParams['axes.unicode_minus'] = False
# 创建一个图形
plt.figure(figsize=(10, 6))

# 绘制实际值和预测值
plt.scatter(y_test, y_pred, color='blue', label='预测值')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color='red', linewidth=2, label='实际值')

# 添加标签和标题
plt.xlabel('实际值 (y_test)')
plt.ylabel('预测值 (y_pred)')
plt.title('实际值 vs 预测值')
plt.legend()

# 显示图形
plt.show()

(五)模型评价及优化

python 复制代码
# 1.	调用 sklearn.metrics 模块,通过均方误差(MSE)"mean_squared_error"、均方根误差(RMSE)以及决定系数(R2) "r2_score" 对模型进行评价;
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np
# 计算均方误差(MSE)
mse = mean_squared_error(y_test, y_pred)

# 计算均方根误差(RMSE)
# rmse = mean_squared_error(y_test, y_pred, squared=False)
# FutureWarning: 'squared' is deprecated in version 1.4 and will be removed in 1.6. To calculate the root mean squared error, use the function'root_mean_squared_error'.
rmse = np.sqrt(mse)# 直接用 numpy 计算 RMSE

# 计算决定系数(R2)
r2 = r2_score(y_test, y_pred)

print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("决定系数 (R2_score):", r2)
python 复制代码
# 2.	建立岭回归或 Lasso 回归模型,对数据集进行训练并预测;
from sklearn.linear_model import Ridge, Lasso

# 建立岭回归模型
ridge_reg = Ridge(alpha=1.0)
ridge_reg.fit(X_train, y_train)
y_pred_ridge = ridge_reg.predict(X_test)

# 建立 Lasso 回归模型
lasso_reg = Lasso(alpha=1.0)
lasso_reg.fit(X_train, y_train)
y_pred_lasso = lasso_reg.predict(X_test)

# 3 通过均方误差(MSE)、均方根误差(RMSE)以及决定系数(R2) 对岭回归或 Lasso 回归模型进行评价
# 评价岭回归模型
mse_ridge = mean_squared_error(y_test, y_pred_ridge)
rmse_ridge = np.sqrt(mse_ridge)
r2_ridge = r2_score(y_test, y_pred_ridge)

print("岭回归 均方误差 (MSE):", mse_ridge)
print("岭回归 均方根误差 (RMSE):", rmse_ridge)
print("岭回归 决定系数 (R2_SCORE):", r2_ridge)

# 评价 Lasso 回归模型
mse_lasso = mean_squared_error(y_test, y_pred_lasso)
rmse_lasso = np.sqrt(mse_lasso)
r2_lasso = r2_score(y_test, y_pred_lasso)

print("Lasso 回归 均方误差 (MSE):", mse_lasso)
print("Lasso 回归 均方根误差 (RMSE):", rmse_lasso)
print("Lasso 回归 决定系数 (R2_SCORE):", r2_lasso)

# 保存数据
results = {}
results['线性回归'] = {'均方误差': mse, '均方根误差': rmse, '决定系数': r2}
results['岭回归'] = {'均方误差': mse_ridge, '均方根误差': rmse_ridge, '决定系数': r2_ridge}
results['Lasso 回归'] = {'均方误差': mse_lasso, '均方根误差': rmse_lasso, '决定系数': r2_lasso}
# print(results)

# 保存数据
output_dir = 'output'

# 保存 JSON 文件
json_file_path = os.path.join(output_dir, '三种回归评价.json')

with open(json_file_path, 'w', encoding='utf-8') as f:
    json.dump(results, f, ensure_ascii=False, indent=4)
    print('已完成保存 JSON 文件')
python 复制代码
{
    "线性回归": {
        "均方误差": 6.914145184671658,
        "均方根误差": 2.6294762186929277,
        "决定系数": 0.8984946250185042
    },
    "岭回归": {
        "均方误差": 6.914213719729213,
        "均方根误差": 2.629489250734677,
        "决定系数": 0.8984936188671246
    },
    "Lasso 回归": {
        "均方误差": 6.916797056785589,
        "均方根误差": 2.6299804289738717,
        "决定系数": 0.8984556933405978
    }
}
python 复制代码
# 4 通过可视化图表对比两种模型预测结果
# 创建一个图形
plt.figure(figsize=(15, 5))

# 绘制线性回归模型的预测结果
plt.subplot(1, 3, 1)
plt.scatter(y_test, y_pred, color='blue', label='预测值')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color='red', linewidth=2, label='实际值')
plt.xlabel('实际值 (y_test)')
plt.ylabel('预测值 (y_pred)')
plt.title('线性回归 实际值 vs 预测值')
plt.legend()

# 绘制岭回归模型的预测结果
plt.subplot(1, 3, 2)
plt.scatter(y_test, y_pred_ridge, color='green', label='预测值')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color='red', linewidth=2, label='实际值')
plt.xlabel('实际值 (y_test)')
plt.ylabel('预测值 (y_pred_ridge)')
plt.title('岭回归 实际值 vs 预测值')
plt.legend()

# 绘制 Lasso 回归模型的预测结果
plt.subplot(1, 3, 3)
plt.scatter(y_test, y_pred_lasso, color='orange', label='预测值')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color='red', linewidth=2, label='实际值')
plt.xlabel('实际值 (y_test)')
plt.ylabel('预测值 (y_pred_lasso)')
plt.title('Lasso 回归 实际值 vs 预测值')
plt.legend()

# 显示图形
plt.tight_layout()
plt.savefig('./output/三种回归预测结果.png')
plt.show()

# 保存图片

print('已完成保存图片')
相关推荐
limingade1 小时前
手机实时提取SIM卡打电话的信令和声音-新的篇章(一、可行的方案探讨)
物联网·算法·智能手机·数据分析·信息与通信
编程零零七1 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
勤劳兔码农9 小时前
文本分类实战项目:如何使用NLP构建情感分析模型
自然语言处理·分类·数据挖掘
shiming887910 小时前
Python数据分析与可视化
开发语言·python·数据分析
一声沧海笑10 小时前
dplyr、tidyverse和ggplot2初探
信息可视化·数据分析·r语言
xuehaisj12 小时前
论文内容分类与检测系统源码分享
人工智能·分类·数据挖掘
xuehaisj16 小时前
食品检测与分类系统源码分享
人工智能·分类·数据挖掘
惟长堤一痕18 小时前
医学数据分析实训 项目九 糖尿病风险预测
机器学习·数据分析
will_guofeng18 小时前
数据分析-螺旋环状气泡图
数据挖掘·数据分析