前言
心血管疾病是当前全球范围内的重大公共健康问题,其发病率和相关死亡率居高不下。随着生活方式的改变、环境因素的影响以及人口老龄化的加剧,心血管疾病的发病趋势愈加严峻。本文将通过机器学习算法构建预测心血管疾病的模型
一、数据收集
id 账号
Age | Objective Feature | 年龄 以天为单位
Height | Objective Feature | height | int (cm) 身高
Weight | Objective Feature | weight | float (kg) |体重
Gender | Objective Feature | gender | categorical code |性别
Systolic blood pressure | Examination Feature | ap_hi | int |收缩压
Diastolic blood pressure | Examination Feature | ap_lo | int |舒张压
Cholesterol | Examination Feature | cholesterol | 1: normal, 2: above normal, 3: well above normal |胆固醇是否正常
Glucose | Examination Feature | gluc | 1: normal, 2: above normal, 3: well above normal |葡萄糖检测是否正常
Smoking | Subjective Feature | smoke | binary 是否吸烟
Alcohol intake | Subjective Feature | alco | binary |酒精摄入
Physical activity | Subjective Feature | active | binary |体力活动
Presence or absence of cardiovascular disease | Target Variable | cardio | binary |是否患有心血管疾病
二、模型构建
1.引入库
代码如下(示例):
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
from sklearn import metrics, preprocessing
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.svm import SVC
from sklearn.metrics import classification_report
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt
import seaborn as sns
2.数据导入加载
首先加载数据集,并对数据进行基本的探索性分析,包括查看数据的基本信息、统计摘要、特征分布等。
代码如下(示例):
d = pd.read_csv('D:/Anconda/xinxueguan1.csv')
d.head()
d.info()
print(d.isnull().sum())
-
import语句导入需要的库和模块。 使用pd.read_csv()载入数据集。
-
d.head()和d.info()用于查看数据的前几行和基本信息(列数、非空值等)。
-
d.isnull().sum()检查并打印出每列的缺失值数量。
3.数据清洗
在检查数据并剔除其中包含的错误、重复或无效数据,以提高数据质量。
代码如下(示例):
d.drop(d[(d['height'] > d['height'].quantile(0.975)) | (d['height'] < d['height'].quantile(0.025))].index,inplace=True)
d.drop(d[(d['weight'] > d['weight'].quantile(0.975)) | (d['weight'] < d['weight'].quantile(0.025))].index,inplace=True)
d.drop(d[(d['ap_hi'] > d['ap_hi'].quantile(0.975)) | (d['ap_hi'] < d['ap_hi'].quantile(0.025))].index,inplace=True)
d.drop(d[(d['ap_lo'] > d['ap_lo'].quantile(0.975)) | (d['ap_lo'] < d['ap_lo'].quantile(0.025))].index,inplace=True)
len(d)
d[d['ap_lo'] > d['ap_hi']].shape[0]
d.describe()
d['age'] = (d['age'] / 365).round().astype('int')
- 这部分代码进行数据清洗,剔除身高、体重、收缩压、舒张压等异常值。
- 计算数据集长度,检查收缩压高于舒张压的数据数量。
- 输出数据集的描述统计信息。
- 将年龄列的单位从天转换为年,并将其转换为整数类型。
4.特征工程
选择、修改或创建新的特征,以提高模型的性能。
代码如下(示例):
age_edges = [30, 35, 40, 45, 50, 55, 60, 65]
age_labels = [0, 1, 2, 3, 4, 5, 6]
d['age_group'] = pd.cut(d['age'], bins=7, labels=range(7), include_lowest=True, right=True)
d['bmi'] = d['weight'] / ((d['height'] / 100) ** 2)
bmiMin = int(d['bmi'].min())
bmiMax = int(d['bmi'].max())
d['bmi'] = pd.cut(d['bmi'], bins=6, labels=range(6), right=True, include_lowest=True)
d['map'] = ((2 * d['ap_lo']) + d['ap_hi']) / 3
mapMin = int(d['map'].min())
mapMax = int(d['map'].max())
d['map'] = pd.cut(d['map'], bins=6, labels=range(6), right=True, include_lowest=True)
- 定义年龄的分组边界和标签,根据年龄分组生成新的age_group列。
- 计算并生成BMI(体质指数)列,并进行分桶处理。
- 计算并生成MAP(平均动脉压)列,并进行分桶处理。
5.数据可视化和分析
使用图表和可视化方法探索数据,寻找模式、趋势和关联,进行统计分析,以更深入地理解数据。
代码如下(示例):
plt.figure(figsize=(10, 8))
sns.heatmap(d.corr(), annot=True, cmap='Spectral', fmt=".2f", linewidths=.5)
plt.title('Correlation Matrix')
plt.show()
- 绘制特征之间相关性的热力图,以便分析它们之间的相关关系。
6.模型准备和训练
(1)数据集划分:将数据分为训练集、验证集和测试集。
(2)数据编码:对分类数据进行编码。
代码如下(示例):
d_og = d
d = d.drop(['height', 'weight', 'ap_hi', 'ap_lo', 'age'], axis=1)
le = preprocessing.LabelEncoder()
d = d.apply(le.fit_transform)
- 备份原始数据集。
- 删除不需要的数值型特征列(身高、体重、收缩压、舒张压、年龄)。
- 使用LabelEncoder()对分类特征进行编码,以便后续模型训练。
7.随机森林模型构建和优化
随机森林算法
随机森林(Random Forest)算法是一种集成学习方法,通常用于分类和回归任务。它通过构建多个决策树(Decision Tree)来提高预测的准确性和稳定性。
关键特点:
集成学习:
随机森林是一种集成学习方法,通过组合多个弱学习器(决策树)来形成一个强大的预测模型。
决策树基础:
每棵决策树基于随机抽样的训练数据集和特征集进行训练,每个节点的分裂基于最大化信息增益或基尼系数等准则。
随机性:
在构建每棵树时,随机森林引入了两种随机性:
Bootstrap抽样:从原始训练数据集中随机有放回地抽取样本,用于每棵树的训练。
特征随机选择:每次分裂节点时,从所有特征中随机选择一个子集,作为节点分裂的候选特征。
预测结果:
对于分类问题,随机森林通过投票或平均值来确定最终的分类结果。
对于回归问题,随机森林则通过所有树的预测结果的平均值来得出最终的预测值。
容易并行化处理:
由于每棵树可以独立构建,因此随机森林易于并行化处理,能够有效利用多核CPU来加速训练过程。
工作原理:
随机抽样:
从训练集中随机抽取一定比例的样本,有放回地抽样形成一个子集(称为Bootstrap样本集),用于每棵树的训练。
随机选择特征:
在每棵树的节点分裂时,从所有特征中随机选择一个子集作为候选特征集,以减少每棵树的相关性,提高整体模型的多样性。
树的生长:
每棵树都尽可能地生长到最大深度或直到节点中的样本都属于同一类别(对于分类问题)或节点中的样本误差低于某个阈值(对于回归问题)。
集成预测:
对于分类问题,随机森林通过投票机制确定最终的分类结果。
对于回归问题,随机森林通过平均每棵树的预测值来得出最终的预测结果。
优势:
高准确性:通过集成多个决策树,减少过拟合风险,提高模型的预测准确性。
适用于大数据集:能够有效处理大规模数据集,具备良好的扩展性。
对异常值和缺失值不敏感:由于随机抽样和多棵树的投票机制,对数据中的异常值和缺失值具有较好的鲁棒性。
代码如下(示例):
x = d.drop(['cardio', 'gender', 'alco'], axis=1)
y = d['cardio']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20, random_state=1)
rfModel = RandomForestClassifier(random_state=1)
rfModel.fit(x_train, y_train)
rf_pred = rfModel.predict(x_test)
rf_accuracy = metrics.accuracy_score(y_test, rf_pred) * 100
- 定义特征变量x和目标变量y。
- 将数据集分割为训练集和测试集。
- 初始化随机森林分类器,并使用训练数据拟合模型,并计算初始的预测准确率。
8.模型优化和评估
模型调优:通过调整模型的参数来改善模型的性能。
模型评估:使用验证集评估模型的性能,调整模型参数。或使用交叉验证技术,以确保模型的稳健性。
代码如下(示例):
param_grid = {
'n_estimators': [100, 200, 300, 500],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10, 20],
'min_samples_leaf': [1, 2, 4, 8],
'max_features': ['sqrt', 'log2', None],
}
rf_best_params = {
'n_estimators': [100],
'max_depth': [10],
'min_samples_split': [10],
'min_samples_leaf': [1],
'max_features': [None],
}
rf_gridsearch = GridSearchCV(estimator=rfModel, param_grid=rf_best_params, cv=5, scoring='accuracy', n_jobs=-1)
rf_gridsearch.fit(x_train, y_train)
best_params = rf_gridsearch.best_params_
best_estimator = rf_gridsearch.best_estimator_
rf_pred_CV = best_estimator.predict(x_test)
rf_accuracy_cv = metrics.accuracy_score(y_test, rf_pred_CV) * 100
classification_report_str = classification_report(y_test, rf_pred_CV, digits=4)
- 定义随机森林分类器的参数网格和最佳参数组合。
- 使用网格搜索GridSearchCV寻找最佳参数。
- 输出最佳参数和最佳估算器,并使用最佳模型进行预测和评估。
- 输出随机森林模型的混淆矩阵和分类报告,以评估模型在测试集上的性能。
9.结果展示
绘制随机森林模型的混淆矩阵热力图,直观显示模型预测结果的准确性。
代码如下(示例):
plt.figure(figsize=(6, 4))
sns.heatmap(pd.DataFrame(cnf_matrix), annot=True, cmap="YlGnBu", fmt='g')
plt.title('Confusion matrix: RF')
plt.ylabel('Actual label')
plt.xlabel('Predicted label')
运行结果
总结
从数据加载和清洗,到特征工程、模型构建、优化和评估,构成了一个完整的机器学习流程。