基于数据挖掘的医疗疾病预测分析及可视化
一、项目背景与总体目标
本项目题目为:“基于数据挖掘的医疗疾病预测分析及可视化”。
依托 Kaggle 医疗健康数据集,通过数据挖掘、机器学习与可视化技术,对患者的疾病类型、医疗费用和健康状态进行建模预测,并构建一个基于 Web 的交互式分析与决策支持系统。
系统整体目标:
- 数据层面:对 55,500 条、15 个字段的医疗记录进行清洗、预处理与特征工程,构建人口学、疾病、诊疗行为与费用等多维特征体系。
- 模型层面:采用逻辑回归、随机森林与 XGBoost 三类算法,分别对疾病类型(分类)、医疗费用(回归)、健康状态(分类)进行建模与优化。
- 系统层面:基于 Streamlit 搭建 Web 端预测与可视化平台,提供数据概览、疾病预测、费用预测、健康状态预测与模型说明等功能模块。
二、数据集说明
2.1 数据来源与规模
数据来源:Kaggle 医疗健康数据集,本地处理后保存为 algorithm/modified_healthcare_dataset.csv。
数据规模:
- 样本数:55,500 条患者记录
- 字段数:15 个核心字段
主要字段及含义:
| 字段名 | 含义 | 类型 | 示例 |
|---|---|---|---|
Name | 患者姓名 | 字符串 | Bobby Jackson |
Age | 年龄 | 数值型 | 19 |
Gender | 性别 | 类别型 | Male / Female |
Blood Type | 血型 | 类别型 | A+ / O- / AB+ 等 |
Medical Condition | 疾病类型 | 类别型 | Flu, Cancer, Diabetes 等 |
Date of Admission | 入院日期 | 日期型 | 2024-01-31 |
Doctor | 主治医生 | 字符串 | Matthew Smith |
Hospital | 医院 | 字符串 | Northwestern Memorial … |
Insurance Provider | 保险公司 | 字符串 | Blue Cross, Medicare 等 |
Billing Amount | 医疗费用 | 数值型 | 2212.27 |
Room Number | 病房号 | 数值型 | 328 |
Admission Type | 入院类型 | 类别型 | Emergency / Routine 等 |
Discharge Date | 出院日期 | 日期型 | 2024-02-07 |
Medication | 药物治疗方案 | 字符串 | Azithromycin 等 |
Test Results | 检查/健康状态 | 类别型 | Normal / Abnormal / Inconclusive |
Length of Stay | 住院天数 | 数值型 | 7 |
在算法实现中,通过 COLUMNS_CONFIG 将其中的关键字段映射为四大特征体系:
- 人口学特征:年龄 (
Age)、性别 (Gender)、血型 (Blood Type) - 疾病特征:疾病类型 (
Medical Condition) - 诊疗行为特征:住院天数 (
Length of Stay)、入院类型 (Admission Type) 等 - 费用特征:医疗费用 (
Billing Amount)、保险类型 (Insurance Provider)
三、数据预处理与特征工程
3.1 预处理总体流程
预处理逻辑主要实现在 algorithm/algorithm.ipynb 的 preprocess_data 函数和 streamlit_app.py 的 preprocess_data 函数中,包含以下步骤:
- 字段筛选:只保留与建模强相关的特征:
Age、Gender、Blood Type、Medical Condition、Length of Stay、Billing Amount、Test Results。 - 缺失值处理:
- 数值型字段:使用 中位数(median) 填充;
- 类别型字段:使用 众数(most_frequent) 填充。
- 异常值检测与剔除:
- 使用 局部异常因子(Local Outlier Factor, LOF) 对数值特征进行异常检测,剔除异常样本(污染率约 1%)。
- 特征编码:
- 对除目标字段之外的类别特征进行 One-Hot 编码 (
pd.get_dummies),避免算法直接处理字符串; - 保留
Medical Condition与Test Results原始形式,作为分类任务的预测目标。
- 对除目标字段之外的类别特征进行 One-Hot 编码 (
- 标准化与数值特征选择:
- 在建模阶段统一只使用编码后数据中的数值型特征(
int64、float64列),保证与 Scikit-learn / XGBoost 的输入要求一致。
- 在建模阶段统一只使用编码后数据中的数值型特征(
3.2 数值特征相关性分析
在 notebook 中使用 Seaborn 绘制数值特征的相关性热力图,以便直观理解不同指标之间的线性相关关系:

图示说明:
- 每一个方格表示一对数值特征之间的 Pearson 相关系数;
- 颜色由蓝到红分别表示负相关到正相关,颜色越深代表相关性越强;
- 通过该图可以识别出与
Billing Amount(医疗费用)关系紧密的特征,辅助后续特征筛选与模型解释。
3.3 费用相关重要特征分析
项目中利用随机森林回归模型对费用影响因素进行了特征重要性评估,并将结果可视化为条形图(此图在 notebook 中输出,对应的思路在系统中用于解释特征贡献)。
随机森林通过统计各特征在决策树分裂中的“减小不纯度”的贡献,得到特征重要性分数,从而帮助我们判断哪些变量对费用预测起主要作用,如住院天数、疾病类型、保险公司等。
四、建模与算法原理
4.1 任务划分
本项目共设计了三个主要预测任务:
- 任务一:疾病类型预测(多分类)
- 目标列:
Medical Condition - 算法:逻辑回归、随机森林、XGBoost(三个分类模型)
- 目标列:
- 任务二:医疗费用预测(回归)
- 目标列:
Billing Amount - 算法:随机森林回归、XGBoost 回归
- 目标列:
- 任务三:健康状态预测(多分类)
- 目标列:
Test Results(Normal / Abnormal / Inconclusive) - 算法:随机森林、XGBoost 分类模型
- 目标列:
训练/测试划分采用 8:2 分层采样(对分类任务分层),并使用 5 折交叉验证 + 网格搜索(GridSearchCV) 优化超参数。
4.2 逻辑回归(Logistic Regression)
逻辑回归是基于对数几率(logit)的线性模型,适用于二分类和多分类任务:
[
P(y=k \mid x) = \frac{\exp(w_k^\top x + b_k)}{\sum_j \exp(w_j^\top x + b_j)}
]
项目中:
- 使用
max_iter=1000保证收敛; - 采用 L2 正则化,惩罚项控制模型复杂度,防止过拟合;
- 通过网格搜索调整正则化强度
C和求解器solver。
疾病类型预测中,逻辑回归模型的混淆矩阵如下图所示:

图示说明:
- 横轴为模型预测的疾病类别,纵轴为真实疾病类别;
- 对角线上的值越大,表示相应类别预测越准确;
- 非对角元素反映了模型的混淆情况(例如把 Flu 预测成 Infections 的样本数)。
4.3 随机森林(Random Forest)
随机森林是基于 Bagging 的集成学习方法,通过构建多棵决策树并进行投票/平均来提升鲁棒性:
- 分类随机森林:多数投票决定最终类别;
- 回归随机森林:多棵树的预测结果取平均。
项目中随机森林的关键超参数包括:
n_estimators:决策树数量(如 100、200);max_depth:树的最大深度;min_samples_split:内部节点再划分所需的最小样本数。
疾病类型随机森林混淆矩阵:

健康状态随机森林混淆矩阵:

图示说明:
- 与逻辑回归类似,随机森林在多分类任务中往往具有更强的非线性拟合能力;
- 从混淆矩阵可以看出,对于样本较多的疾病/健康状态类别,随机森林的识别率显著提高。
随机森林回归在医疗费用任务中的效果可用真实值–预测值散点图展示:

图示说明:
- 横轴为真实医疗费用,纵轴为模型预测的医疗费用;
- 虚线表示理想情况(预测值=真实值);
- 散点越贴近对角线,说明预测越准确,偏离程度反映模型误差大小。
随机森林特征重要性条形图:

图示说明:
- 横轴为特征重要性得分,纵轴为特征名称;
- 分数越高表示该特征对模型决策影响越大;
- 如住院天数、某些疾病类型的 one-hot 特征、保险类型等,对费用预测具有显著贡献。
4.4 XGBoost
XGBoost(Extreme Gradient Boosting)是基于梯度提升(Gradient Boosting)的高效树模型,核心思想是:
- 逐棵构建弱学习器(CART 树),每一棵树拟合前一轮残差;
- 通过二阶导数近似和正则化项优化目标函数,提高泛化能力;
- 支持多线程并行、列采样、缺失值处理等工程优化。
项目中:
- 对疾病类型和健康状态使用
XGBClassifier(objective="multi:softprob"); - 对医疗费用使用
XGBRegressor(objective="reg:squarederror"); - 通过网格搜索调整
n_estimators、max_depth、learning_rate、subsample等参数; - 对于字符串标签(如疾病名、健康状态),使用
LabelEncoder先编码为数值类别,再进行训练和预测。
疾病类型 XGBoost 混淆矩阵:

健康状态 XGBoost 混淆矩阵:

医疗费用 XGBoost 回归散点图:

图示说明:
- 相比随机森林,XGBoost 在多分类任务上对类别边界更敏感,能够在高维特征空间下学习更复杂的决策边界;
- 在回归任务中,XGBoost 利用梯度提升机制通常能取得更好的 R² 与更低的 RMSE。
五、模型评估指标与结果分析
在 algorithm/algorithm.ipynb 中,针对分类与回归任务分别采用不同的指标体系:
5.1 分类任务评估指标
- 准确率(Accuracy):预测正确样本数 / 总样本数;
- 精确率(Precision):预测为正类的样本中,有多少是真正的正类;
- 召回率(Recall):真实正类样本中,有多少被模型正确识别;
- F1 值(F1-score):精确率与召回率的调和平均,综合平衡两者;
- AUC(ROC 曲线下面积):对二分类或多分类的整体区分能力进行度量;
- 混淆矩阵:直观展示各类别的 TP/FP/FN 分布。
通过对逻辑回归、随机森林与 XGBoost 三种模型的对比,可以得到:
- 随机森林和 XGBoost 的宏平均 F1 值明显高于逻辑回归,更适合处理非线性特征较多的医疗数据;
- 对于样本量较少的小类别,模型容易出现混淆,需要通过类别权重调整或采样技术进一步优化。
5.2 回归任务评估指标
- R²(决定系数):评估模型对方差的解释能力,越接近 1 越好;
- RMSE(均方根误差):预测误差的平方平均根,越小说明预测越精确。
项目中使用:
r2 = r2_score(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
通过随机森林回归与 XGBoost 回归散点图可以看到,两种模型都能较好拟合主要费用区间,但在极端高费用样本上仍存在一定偏差,有必要在实际应用中结合业务规则和风险容忍度进行解释。
六、数据库设计与字段说明
虽然本项目主要基于 CSV 文件进行分析与建模,但为了后续系统部署与扩展,这里给出一套推荐的关系型数据库表结构设计(以 MySQL 为例)。
6.1 患者信息表 t_patient
| 字段名 | 类型 | 长度 | 允许空 | 主键/唯一 | 说明 |
|---|---|---|---|---|---|
id | INT | 11 | 否 | 主键,自增 | 内部唯一编号 |
name | VARCHAR | 50 | 否 | 患者姓名 | |
gender | CHAR | 1 | 否 | 性别(M/F) | |
age | INT | 3 | 否 | 年龄 | |
blood_type | VARCHAR | 5 | 是 | 血型 | |
insurance_id | INT | 11 | 是 | 外键 | 关联保险表 |
6.2 疾病与就诊记录表 t_visit
| 字段名 | 类型 | 长度 | 允许空 | 主键/唯一 | 说明 |
|---|---|---|---|---|---|
id | INT | 11 | 否 | 主键,自增 | 就诊记录编号 |
patient_id | INT | 11 | 否 | 外键 | 对应 t_patient.id |
medical_condition | VARCHAR | 50 | 否 | 疾病类型 | |
admission_type | VARCHAR | 20 | 否 | 入院类型(急诊/常规等) | |
hospital | VARCHAR | 100 | 否 | 医院名称 | |
doctor | VARCHAR | 50 | 是 | 主治医生 | |
date_admission | DATE | 否 | 入院日期 | ||
date_discharge | DATE | 是 | 出院日期 | ||
length_of_stay | INT | 4 | 否 | 住院天数 | |
medication | VARCHAR | 100 | 是 | 用药方案 | |
test_results | VARCHAR | 20 | 否 | 检查结果/健康状态 |
6.3 费用信息表 t_billing
| 字段名 | 类型 | 长度 | 允许空 | 主键/唯一 | 说明 |
|---|---|---|---|---|---|
id | INT | 11 | 否 | 主键,自增 | 费用记录编号 |
visit_id | INT | 11 | 否 | 外键 | 对应 t_visit.id |
billing_amount | DECIMAL | 10,2 | 否 | 医疗费用 | |
insurance_id | INT | 11 | 是 | 外键 | 关联 t_insurance.id |
room_number | INT | 4 | 是 | 病房号 |
6.4 保险信息表 t_insurance
| 字段名 | 类型 | 长度 | 允许空 | 主键/唯一 | 说明 |
|---|---|---|---|---|---|
id | INT | 11 | 否 | 主键,自增 | 保险公司编号 |
provider_name | VARCHAR | 100 | 否 | 唯一 | 保险公司名称 |
通过上述 3~4 张表的主外键关系,可以将原 CSV 结构化存储到数据库中,便于后续进行多维统计与高并发访问;模型训练阶段可以通过 SQL 查询将数据导出到 Pandas 进行进一步处理。
七、系统目录结构与技术栈说明
项目主要目录结构如下:
program/
├── algorithm/
│ ├── algorithm.ipynb # 算法实现与模型训练 notebook
│ ├── modified_healthcare_dataset.csv # 预处理后的 Kaggle 医疗数据集
│ ├── streamlit_app.py # Streamlit 可视化与预测系统
│ └── models/ # 训练好的模型文件 (*.pkl)
├── explaination/
│ ├── 详解.md # 当前文档(项目详解)
│ └── images/
│ ├── algorithm/ # 算法相关图表截图
│ └── system/ # 系统界面截图
└── ...
7.1 技术栈概述
- Python 3.x:核心开发语言;
- Pandas / NumPy:数据读取、清洗与特征工程;
- Scikit-learn:逻辑回归、随机森林、数据划分、交叉验证与网格搜索;
- XGBoost:高性能梯度提升树模型,提升分类与回归任务效果;
- Matplotlib & Seaborn:模型评估图、相关性热力图、散点图、箱线图等可视化;
- Streamlit:快速搭建 Web 端交互式数据分析与预测系统;
- streamlit-echarts(可选):用于更加炫酷的交互图表(如 ECharts 饼图/柱状图)。
八、系统界面与功能详解
系统前端全部由 algorithm/streamlit_app.py 构建,主要分为五大页面:
8.1 数据概览与可视化页面
界面截图:

功能说明:
- 顶部展示关键统计指标:样本数量、字段数量、疾病类型数、平均医疗费用;
- 左侧绘制 年龄分布饼图,展示 0–17、18–35、36–50、51–65、65+ 各年龄段占比;
- 右侧绘制 疾病–费用关联条形图,显示 Top 15 疾病的平均医疗费用差异;
- 下方可展开查看前 20 条原始数据,便于对字段含义与数据质量进行直观理解;
- 侧边栏支持按 疾病类型、年龄范围、性别 进行全局筛选,所有图表与预测模块都会联动更新。
8.2 疾病类型预测页面
界面截图:


该模块分为两个标签页:
-
单个患者预测:
- 用户从筛选后的数据集中选择一条患者记录(姓名 + 年龄 + 疾病);
- 选择模型算法(逻辑回归 / 随机森林 / XGBoost);
- 系统给出该患者的 预测疾病类型,并以条形图展示各疾病类型预测概率;
- 同时在表格中展示当前患者的关键信息(年龄、性别、疾病、住院天数、费用等)。
-
疾病分布分析:
- 显示 疾病类型样本量 Top 15 条形图,支持按筛选条件自动更新;
- 绘制 各疾病类型费用分布箱线图,展示同一疾病下费用的中位数、四分位数与极端值情况,有助于发现高费用疾病和费用离散度。
8.3 医疗费用预测页面
界面截图:

同样划分为两个标签页:
-
单个患者费用预测:
- 选择模型(随机森林回归 / XGBoost 回归);
- 选择一条患者记录,系统给出 预测医疗费用;
- 若原数据中有真实费用,同时展示真实值与误差(预测–真实),便于直观看到模型精度。
-
费用分布分析:
- 医疗费用直方图 + KDE 曲线:展示整体费用分布特征(是否右偏、是否存在长尾等);
- 住院天数 vs 医疗费用散点图:观察住院时间与费用之间的相关趋势,不同疾病类型可用颜色区分。
8.4 健康状态预测页面
界面截图:

功能同样分为两个标签页:
-
单个患者预测:
- 基于随机森林或 XGBoost 对
Test Results(Normal / Abnormal / Inconclusive)进行预测; - 显示预测健康状态和各状态的概率分布。
- 基于随机森林或 XGBoost 对
-
健康状态分布分析:
- 绘制 健康状态分布条形图,展示不同检查结果的样本数量;
- 若同时存在疾病列,则绘制 疾病类型 × 健康状态 的堆叠柱状图,显示每种疾病下 Normal/Abnormal 的占比。
8.5 模型与系统说明页面
界面截图:

内容概述:
- 简要介绍数据处理、模型训练与 Streamlit 系统构建的技术路线;
- 说明模型文件命名约定与保存路径(例如
disease_type_RandomForest.pkl等); - 给出推荐使用流程:运行 notebook 训练并保存模型 → 启动 Streamlit 应用 → 进行可视化分析与预测。
九、使用流程与实现思路总结
9.1 使用流程
-
准备环境:安装 Python、Anaconda,并在虚拟环境中安装所需依赖(Pandas、Scikit-learn、XGBoost、Streamlit 等)。
-
运行 notebook:打开
algorithm/algorithm.ipynb,按顺序执行:- 数据加载与预处理;
- 特征关联分析与重要性评估;
- 三个预测任务的模型训练与网格搜索;
- 调用
save_models(...)将最优模型保存到algorithm/models/。
-
启动 Web 系统:在项目根目录执行:
streamlit run algorithm/streamlit_app.py -
在浏览器中使用系统:
- 通过侧边栏设置疾病类型、年龄、性别等筛选条件;
- 浏览数据概览与可视化图表;
- 在各预测模块选择患者并查看预测结果及概率/误差;
- 在“模型与系统说明”页面阅读技术路线与模型文件说明。
9.2 实现思路小结
- 数据层:以 CSV 为数据源,通过 Pandas + Scikit-learn 完成清洗、特征工程与建模;
- 模型层:逻辑回归负责基准线模型,随机森林与 XGBoost 作为主力模型,通过交叉验证和网格搜索寻优;
- 评估层:分类任务以 Accuracy/F1/AUC + 混淆矩阵为主,回归任务以 R² + RMSE + 真实 vs 预测散点图为主;
- 系统层:Streamlit 将 notebook 中的算法逻辑封装为 Web API,结合侧边筛选、主界面图表和预测表单,实现一体化的“医疗疾病预测分析及可视化”系统;
- 扩展层:通过给出关系型数据库表设计和模型持久化方案,为今后接入真实医院 HIS/EMR 系统、构建在线预警和决策支持平台提供基础。
至此,项目在数据预处理、特征工程、模型构建与评估、系统设计与可视化、数据库设计等方面形成了一条完整而可复用的医疗数据挖掘技术路线,可为临床疾病预警、费用管理和健康管理提供数据支撑与实践案例。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)