糖尿病是一种影响全球数百万人的严重疾病。因此,及时准确地预测这种疾病至关重要,因为它可能导致其他危及生命的疾病并发症。高血糖水平是这种疾病中最常见的主要原因。本项目的目标是使用PyCaret构建一个预测糖尿病的模型。
PyCaret是一个开源库,包含多个分类器和回归器,可以快速选择表现最佳的算法。这使得能够在几分钟内在选择的笔记本环境中准备和部署模型。
本项目使用的数据集是Kaggle上的Pima Indians Diabetes Dataset,该数据集最初由国家糖尿病、消化系统和肾脏疾病研究所提供。数据集和项目代码均可在GitHub仓库中找到。该数据集用于预测患者是否可能根据输入参数如年龄、葡萄糖、血压、胰岛素、BMI等患上糖尿病。数据中的每一行都提供了有关患者的相关信息。需要注意的是,这里的所有患者都是至少21岁的Pima印第安人后裔的女性。
数据集包含768个个体数据,具有9个特征集。所有特征的详细描述如下:
首先,需要导入所有所需的库和数据集。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
import plotly.offline as py
import plotly.express as px
import plotly.io as pio
import plotly.graph_objs as go
import math
from scipy.stats import norm, skew
import warnings
warnings.filterwarnings('ignore')
导入数据集后,现在可以进行EDA(探索性数据分析)。
import pandas as pd
df_diab = pd.read_csv("diabetes.csv")
print(df_diab.info())
数据集中大约有35%的条目有患糖尿病的可能性。让可视化数据集中提供的这8个特征——
fig, axs = plt.subplots(4, 2, figsize=(15,12))
axs = axs.flatten()
sns.distplot(df_diab['Pregnancies'],rug=True,color='#38b000',ax=axs[0])
sns.distplot(df_diab['Glucose'],rug=True,color='#FF9933',ax=axs[1])
sns.distplot(df_diab['BloodPressure'],rug=True,color='#522500',ax=axs[2])
sns.distplot(df_diab['SkinThickness'],rug=True,color='#66b3ff',ax=axs[3])
sns.distplot(df_diab['Insulin'],rug=True,color='#FF6699',ax=axs[4])
sns.distplot(df_diab['BMI'],color='#e76f51',rug=True,ax=axs[5])
sns.distplot(df_diab['DiabetesPedigreeFunction'],color='#03045e',rug=True,ax=axs[6])
sns.distplot(df_diab['Age'],rug=True,color='#333533',ax=axs[7])
plt.show()
数据集中包含零值和一些无效值,即逻辑上不可能的值,如葡萄糖、胰岛素、BMI或血压值为0。在清理数据集时,可以删除这些不一致的值,或者用更合适的值范围替换它们。由于“皮肤厚度”和“胰岛素水平”列中有很多零值;删除这些将导致数据集大大缩小。因此,对于本项目,用均值替换NaN值,以保持数据集的大小不变。此外,“用均值替换”的方法也适用于“BMI”、“葡萄糖”或“血压”特征。
bmi_outliers=df_diab[df_diab['BMI']>40]
bmi_outliers['BMI'].shape
由于异常值的数量大于总样本的10%,不会删除它们。相反,让用均值替换BMI异常值(BMI>40)。
df_diab["BMI"] = df_diab["BMI"].apply(lambda x: df_diab.BMI.mean() if x>40 else x)
使用相关性矩阵,可以得到变量之间依赖性的完整图景以及它们对结果的影响。在这里,可以看到“葡萄糖”特征与结果有很强的相关性,这是预期的。除此之外,其他参数似乎没有很强的相关性。这就是为什么在训练模型时可能无法删除某些特征。
现在已经完成了数据集的预处理,让在PyCaret中设置模型。首先,让安装PyCaret。在虚拟环境中运行命令‘pip install pycaret’安装PyCaret非常简单,只需几分钟。
# 安装PyCaret
pip install pycaret
‘setup’是使用PyCaret库的第一个也是唯一一个强制性步骤。这一步负责所有训练模型前所需的数据准备工作。初始化设置后,它会列出输入特征的所有数据类型。如果特征的数据类型正确,只需按‘Enter’键继续。
diab = setup(data = df_diab,target = 'Outcome',normalize=True, session_id=1)
PyCaret默认使用70:30的比例进行训练-测试拆分,可以通过在设置模型时传递‘train-size’参数来修改。使用不同的拆分比例可能会对模型性能产生有趣的影响。
由于数据集中的特征有不同的尺度,因此肯定需要对数据集进行归一化,以确保在训练和测试模型时获得更好的结果。让设置‘normalize=True’,以便PyCaret进行归一化。
‘结果’变量在预测类别‘0’和‘1’中显示出轻微的不平衡,总共768个样本中。这种偏差可以通过使用SMOTE等抽样技术在未来调整模型时进行调整。
现在可以使用‘compare_models’函数开始训练过程。这个函数将训练库中的所有算法,并列出多个性能指标。
compare_models()
由于随机森林分类器的准确性相对于其他分类器来说比较高,让使用随机森林分类器构建模型。在这里,可以使用‘fold’参数定义折数,并通过‘tune_model’语句调整模型。
rf = create_model('rf', fold = 10)
通过打印‘tuned_rf’语句,可以获得所需的最佳超参数。
tuned_rf = tune_model(rf)
tuned_rf
PyCaret库不仅为提供了不同的模型和性能指标,还提供了类别预测误差、混淆矩阵、精确度-召回曲线等许多其他选项。
plot_model(tuned_rf, plot = 'auc')
plot_model(tuned_rf, plot = 'pr')
plot_model(tuned_rf, plot = 'confusion_matrix')
模型可以通过PyCaret中的一行代码使用SHAP值和相关图轻松解释。
interpret_model(tuned_rf)
上述图表显示了SHAP值。颜色表示影响,即深粉色表示高影响,浅蓝色表示低影响。进一步了解后,可以看到葡萄糖变量对糖尿病有很高的影响,而BMI对糖尿病有低且负面的影响。
要可视化模型的所有可能方式,可以使用PyCaret的‘evaluate_model’函数,它将在一个窗口中为提供所有选项。
evaluate_model(tuned_rf)
模型预测:
predict_model(tuned_rf);
随机森林分类器的准确性接近82.68%,这种方法和机器学习模型在协助医疗专业人员提供预测方面看起来是有希望的。此外,在根据机器学习模型确定最终健康诊断之前,必须更加关注解释混淆矩阵,因为假阳性和假阴性可能有风险。