仅用于站内搜索,没有排版格式,具体信息请跳转上方微信公众号内链接
你一生中可能已经多次听说过糖尿病。它如此普遍地流行。根据国际糖尿病联合会的数据,2024年有超过340万人死于糖尿病。这相当于全球各类死亡人数的9. 3%。2024年,20-79岁成年人糖尿病患者最多的国家是中国、印度和美国。世界卫生组织(WHO)进一步指出,这种严重的疾病是2021年女性死亡的主要原因之一(具体而言,位列第八)。
那么,糖尿病到底是什么呢?糖尿病并非像常见的误区所说的那样,只是吃太多糖或碳水化合物而引起的疾病。
糖尿病是一种严重的慢性疾病,当人体无法产生足够的胰岛素或无法有效利用已产生的胰岛素时,就会引发血糖升高。糖尿病的主要类型包括1型糖尿病、2型糖尿病和妊娠期糖尿病。1型糖尿病是一种自身免疫性疾病,会导致胰腺中胰岛素分泌细胞的破坏,而2型糖尿病主要与胰岛素抵抗有关。妊娠期糖尿病发生在怀孕期间,通常在分娩后消退。
在本文中,我们将深入探讨一个专注于预测患者糖尿病的机器学习项目。该项目的主要目标是利用患者健康指标准确预测罹患糖尿病的可能性,从而促进早期发现并改善患者预后。
我们在执行此项目时采取的步骤如下:
理解数据
收集数据
数据清洗和验证
探索性数据分析
特征预处理
模型训练
模型评估
特征重要性
测试虚拟数据
我必须戴上我的侦探眼镜,深入医疗保健领域——不仅以学生和专业人士的身份,也以患者的身份。对我来说,这才是数据科学的真正意义所在:从微观和宏观两个层面,全面理解你正在解决的问题。它还需要深厚的同理心——将人置于你构建的每一个解决方案的核心。
背景:一家流动医疗诊所希望使用基本健康指标对糖尿病患者进行预筛查,以减少医院拥挤并关注高危人群。
问题描述:使用EDA发现显著影响糖尿病风险的因素。开发一个分类模型,根据BMI、血糖水平、胰岛素水平和年龄等属性预测一个人是否患有糖尿病。
一旦确定了最终目标,下一步就是收集与该目标相符的标记数据。[因版面限制,只展示部分代码,本项目的数据集和完整代码获取:@公众号:数据STUDIO原文《机器学习实战:糖尿病预测分析及可视化》文末打赏任意金额便可获取]。该数据集最初来自美国国家糖尿病、消化和肾脏疾病研究所。需要特别指出的是,这里的所有患者均为至少21岁的皮马印第安血统女性。
工作流程的第一步是导入必要的库。我们首先导入进行分析所需的模块和库。
然后将数据加载到notebook中
数据集中字段含义:
Pregnancies:怀孕次数
Glucose:口服葡萄糖耐量试验(OGTT)中2小时血浆葡萄糖浓度
BloodPressure:舒张压(毫米汞柱)
SkinThickness:三头肌皮褶厚度(毫米)
Insulin:2小时血清胰岛素(μU/ml)。
BMI:(体重(公斤)/(身高(米)²)
DiabetesPedigreeFunction:根据家族史,对个人糖尿病遗传易感性进行数值估计。范围从0. 08到2.42。
Age:数据集中患者的年龄
Outcome:类别变量(0或1)指示患者是非糖尿病患者(0)还是糖尿病患者(1)
我们从数据集的形状中获得了768个观测值(行)和9个属性(列)
在开始任何建模或分析之前,必须仔细验证和清理数据——这是数据科学中经常被低估的关键步骤。首先,我们用放大镜检查是否存在空值或缺失值、重复值或异常值。
乍一看,所有768行数据在所有属性上都显示为非空。然而,这并不一定意味着数据集是干净的。它仅仅意味着没有表示为NaN的缺失值。在类似的医学数据集中,可以使用诸如之类的占位符值0来表示缺失数据,尤其是在葡萄糖、胰岛素或BMI等领域,因为的值0在生理学上是不可信的。
我们已经在数据集中观察到了一些异常零,为了确认这一点,我们做了以下操作:
df. describe().T
我们可以看到,尽管患者0怀孕的可能性很大,但情况不应该如此,尤其是在血糖、胰岛素或BMI、血压和皮肤厚度等领域。
进一步探究,我们制作了一个汇总表,显示了这些异常值的频率
这些0值在SkinThickness和Insulin等属性中出现很多次,并且可能极大地影响其数据分布
我们的数据集中没有重复的行
上图旨在检查每个属性分布的偏度,以确定用什么统计量来填充这些0值。对于对称分布(例如,SkinThickness&Glucose),我们稍后会用平均值替换这些缺失值NaN,然后再用平均值填充这些空值;而对于偏斜分布(例如,Insulin,BloodPressure和BMI),我们使用中位数来最小化误差。
左偏(负偏):如果低端(左侧)的尾部比右侧长或更长,则该分布被视为左偏分布。在这种情况下,大多数数据值会向高端(右侧)聚集,而少数低异常值会使均值向下倾斜。因此,平均值通常小于中位数。
右偏(正偏):右偏分布的尾部(右侧)较长或拉伸。这表明大多数数据点都集中在低端(左侧),而一些高离群值会将平均值向上拉高。在这种情况下,平均值通常大于中位数。
正态分布:关于均值对称的概率分布
还可以用以下图表示:
怀孕高峰期约为1-2次。平均怀孕次数约为3. 85次,标准差为3. 37次。这一特征表现为正偏度,偏度为0. 90。
葡萄糖水平大多在100至125毫克/分升之间,平均值约为120毫克/分升,标准差为32。分布接近对称,偏度为0. 17。
舒张压的中心倾向接近60-80mmHg,平均值为69mmHg,分布(标准差)约为。它显示出负偏度,其偏度值为-1. 84
皮肤厚度平均值约为20. 54毫米,标准偏差为。数据接近对称,偏度值为0. 11
胰岛素水平主要集中在0左右,但平均值上升到79. 80左右,表明数据呈正偏度分布。偏度值为2. 27,标准偏差为115. 24,相对较高。
体重指数值集中在30-40附近,平均体重指数为32,标准差为7. 88。根据-0. 43的偏度值,分布呈现轻微的负偏斜
糖尿病谱系系数在0. 3-0. 4附近最为常见,平均值为0. 47,标准差为0. 33。
年龄在20-30岁左右达到峰值,平均年龄约为33. 27岁,标准偏差为11. 76。数据分布呈右偏态,偏度值为1. 13。
探索性数据分析(EDA)就像拼图游戏一样——数据科学家需要运用他们的分析直觉。在这个阶段,我们开始使用可视化、汇总和统计工具来解答数据背后的what,how,where以及why。在这个阶段,我分析了数据集的结构、分布和关系,以发现有意义的模式并识别糖尿病的潜在预测因子。
怀孕:怀孕次数的平均值约为4次,中位数为3次,众数为1次,数值范围为0至17次,标准差为3. 37次。
葡萄糖:葡萄糖水平平均约为120. 89mg/dl,中位数为117. 00mg/dl,众数为99. 00mg/dl。数值范围从0到199mg/dl,标准差为31. 97mg/dl。
血压:平均血压约为69. 105毫米汞柱,中位数为72. 00毫米汞柱,众数为70. 00毫米汞柱。测量范围为0至122mmHg,标准差为19. 356mmHg。
皮肤厚度:皮肤厚度的平均值为20. 536毫米,中位数为23. 00毫米,众数为0. 00毫米。范围为0至99毫米,标准差为15. 95毫米。
胰岛素:胰岛素水平平均约为79. 80单位,中位数为30. 50单位,众数为0. 00单位。范围为0至846单位,标准差为115. 24单位。
体重指数:平均体重指数(BMI)为31. 993,中位数和众数均为32. 00。数值范围从0到67. 10,标准差为7. 884。
糖尿病谱系函数:糖尿病血统函数的平均值为0. 472,中位数为0. 372,众数为0. 254。数值介于0. 08和2.42之间,标准差为0. 331。
年龄:平均年龄为33. 24岁,中位数为29. 00岁,众数为22. 00岁。年龄范围在21至81岁之间,标准差为11. 76岁。
怀孕次数中位数约为3-4,有几个较高的离群值(如15+怀孕)。0这样的值不是离群值,这是合乎逻辑的。
葡萄糖中位数约为110-120。由于数值较高(高达约200),出现了明显的右斜。包括0在内的极低值为异常值–在医学上难以置信,可能是数据缺失或错误。
血压中位数约为70-75mmHg。有几个值为0,明显是异常值,不符合生理学原理。血压分布比较对称,但这些0值需要清理。
皮肤厚度中值约为23-25mm。0的数量非常多–强烈表明数据缺失或有误。也有一些上限离群值(约100),但主要问题是0。
胰岛素极度右偏。数值差异巨大,有许多离群值(高达800+)。0很常见,可能表示数据缺失–在现实世界的数据集中,胰岛素经常缺失。
体重指数中位数约为32。0值也是异常值–不太可能对体重指数有效。其他方面呈右偏分布,但分布相当紧凑。
糖尿病谱系系数中位数约为0. 4。右偏,有许多轻度和极端异常值(>1. 5)。没有明显的无效值,但该属性的差异很大。
年龄中位数约为29-30。右偏,尾部延伸至80岁。没有明显的无效异常值;分布看起来很自然。
怀孕糖尿病患者的怀孕次数往往较多。结果=1的怀孕次数中位数更高。糖尿病患者的分布范围更广。
血糖明显区别:糖尿病患者的血糖水平明显更高。在该数据集中,葡萄糖是一个强有力的指标–IQR的重叠极少。两组中都有异常值,但非糖尿病组的异常值更大。
血压中位数相当接近,但糖尿病患者的数值略高。非糖尿病组的异常值较低。总体而言,血压可能不是一个强有力的区分指标。
皮肤厚度糖尿病患者和非糖尿病患者之间的差异很微妙。两组的中位数和均方根值相似。糖尿病患者的几个异常值延伸得更远,但这一特征似乎不那么具有决定性。
胰岛素两组的差异都很大,都有很多异常值。糖尿病患者的中位数似乎略高,但重叠程度较大。
体重指数糖尿病患者的体重指数普遍较高。两组之间的中位数有明显变化。分布略偏右,有一些异常值,但这是一个有用的特征。
糖尿病谱系系数糖尿病组的平均值较高。糖尿病患者中有许多高值异常值,表明遗传风险更大。虽然分布有所重叠,但这一特征有助于预测。
年龄糖尿病患者往往年龄较大。中位数和IQRs有明显差异,糖尿病组的高端值更多。这一特征似乎非常相关。
从上图可以看出,我们有500名非糖尿病患者和268名糖尿病患者。这使得分布不平衡(即数据集中的目标变量或类别没有被平等地表示出来),如果处理不当,可能会导致潜在的偏差或泛化能力差。
上方的条形图显示了每个数值特征的平均值,并以Outcome变量(指示一个人是否患有糖尿病)分隔开。这有助于理解两组之间每个健康指标的平均值有何差异。我们注意到,糖尿病
患者和非糖尿病患者的胰岛素、血糖、年龄和BMI水平之间存在明显的一致性。这表明上述指标是患者患糖尿病的明确指标。妊娠期的一致性表明,有过多次妊娠的女性患妊娠期糖尿病的风险更高。
从非对角线(散点图)中发现:
葡萄糖似乎是一个非常重要的特征。在大多数涉及葡萄糖的散点图中,两个结果类别有明显的分离,橙色/红色(可能是“糖尿病”)点一般出现在葡萄糖值较高的地方
葡萄糖与胰岛素:存在正相关。随着葡萄糖的增加,胰岛素也会增加。糖尿病\“组通常显示较高的葡萄糖和胰岛素值。
葡萄糖与体重指数:呈正相关。较高的葡萄糖通常与较高的体重指数相关。糖尿病\“组的血糖和体重指数通常较高。
葡萄糖与年龄的关系:总体趋势是,葡萄糖水平越高,年龄就越大,尤其是“糖尿病”结果。
体重指数似乎也是一个很好的区分特征。
体重指数与血压:存在正相关关系,体重指数越高,血压越高。
体重指数与年龄:可能存在微弱的正相关。
怀孕次数与年龄:存在正相关,正如预期的那样,年龄越大的人怀孕次数越多。
胰岛素及其分布:涉及胰岛素的散点图突显了其奇特的分布。许多点聚集在零点附近,这是用零值计算的缺失数据。对于非零胰岛素值,与葡萄糖呈正相关,这表明随着葡萄糖水平的升高,人体会分泌更多的胰岛素来控制葡萄糖水平,但对于糖尿病患者来说,这种反应可能不足或无效。
皮肤厚度与体重指数:皮肤厚度与体重指数之间有很强的正相关性,这在生理学上是意料之中的,因为两者都与身体脂肪有关。
血压及其影响:虽然血压显示了一些趋势,但它本身似乎并不像葡萄糖或体重指数那样具有强烈的区分作用。
上图给出了属性之间的相关性矩阵,范围从-1(强负相关性)、0(无相关性)和+1(强正相关性)。
与结果的相关性:
Glucose和Outcome之间存在中等强度的正相关性。这是完全可以预料到的,因为高血糖水平是糖尿病的主要指标。这表明,随着血糖水平的升高,出现积极结果(糖尿病)的可能性也会增大。
BMI和Outcome之间存在中等强度的正相关性。
BMI较高通常意味着患糖尿病的风险较高。
Age和Outcome之间存在微弱的正相关性。患糖尿病的风险通常会随着年龄的增长而增加。
Pregnancies和Outcome之间存在微弱的正相关性,这可能与妊娠期糖尿病或多胎妊娠可能与以后患2型糖尿病的风险较高有关。
为了增强可解释性并揭示数据中更深层次的模式,我根据既定的医疗保健分层,将几个连续的健康指标转化为具有临床意义的类别。这一步骤可以实现更直观的分析和可视化,尤其是在比较不同人群的糖尿病结果时。
Age按照生命阶段分为以下几个组:青年(21-30岁)、中年早期(31-40岁)、中年晚期(41-50岁)、老年早期(51-60岁)和老年(61岁以上)。
BMI使用WHO标准分类对值进行分组:体重过轻(<18. 5)、正常(18. 5–24. 9)、超重(25–29. 9)和肥胖(30+)。
根据BloodPressure舒张压截断值,将血压分为临床范围:低血压、正常血压、高血压前期和1-2期高血压。
二元变量Outcome被映射到更易读的标签——糖尿病和非糖尿病,以便图表和表格更加清晰。
Glucose分为两个主要诊断范围:
正常(<140mg/dL)
糖耐量受损(140-199mg/dL)。这些阈值反映了2小时口服葡萄糖耐量测试(OGTT)中使用的标准指南,有助于识别可能处于糖尿病前期的个体。
根据Insulin胰岛素敏感性和抵抗性的临床解释,将水平分为四类:
<30μU/mL—可能存在胰岛素缺乏,
30–100μU/mL—正常2小时血清胰岛素反应
100–150μU/mL—胰岛素抵抗的早期迹象
150μU/mL—严重的胰岛素抵抗。定义的分箱既反映了诊断范围,也反映了数据集中观察到的分布。使用right=False确保每个类别的上限不重叠
虽然这DiabetesPedigreeFunction并非传统意义上的临床指标,但它有助于根据家族史了解患者的糖尿病遗传易感性。为了更直观地分析这一特征,我将连续的DPF值划分为四个分类箱。这些分类箱有助于突出显示遗传风险的增加与数据集中糖尿病患病率之间的关联。
现在,进入分类图表:
这张堆叠条形图显示了两组血糖类别中糖尿病阳性和阴性结果的百分比。它告诉我们,血糖受损的糖尿病患者比例要高得多。因此,这再次印证了我们的假设:血糖是最终糖尿病结果的关键决定因素。所有年龄段的人都应定期进行血糖检测,即使患者尚未患糖尿病。
从两个饼图来看,老年人在我们的数据集中没有得到充分体现,因此我们可以对这个年龄段的分析持保留态度。
这张水平条形图展示了各年龄段糖尿病状况的分布情况。由此可见,患糖尿病的风险较高的人群是中年早期(31-40岁)和老年早期(51-60岁)。因此,强烈建议在40岁这个门槛上进行早期检测和监测。
由此可见,BMI肥胖人群最容易患糖尿病。因此,对患者采取积极的体重管理策略是最可行的解决方案。
妊娠次数与糖尿病患病率之间似乎存在某种关联。随着妊娠次数的增加,确诊患有糖尿病的女性比例也显著增加。这进一步表明,多次妊娠的女性患妊娠期糖尿病的风险可能更大。
从上面的多条形图中可以看出,在谱系功能较高的人群中,糖尿病患者的相对比例往往较高。这也表明遗传易感性可能是一个影响因素。
从我理解数据的背景来看,糖尿病患者患高血压的可能性是普通人的两倍。这更像是糖尿病的后遗症,而非病因。糖尿病会损伤肾脏,导致水盐潴留,进而导致血压升高。因此,糖尿病对高血压前期和一期高血压患者的影响更为显著。
胰岛素抵抗通常是血糖水平受损的先兆。这意味着抵抗力显著的个体最容易患糖尿病,超过一半的严重抵抗女性患有糖尿病。这个问题可以通过定期检测患者的胰岛素水平来解决。100mU/mL应作为进一步监测和采取早期预防措施的标志。
由于血糖和胰岛素是手动设置的属性,我们使用了屏蔽函数、运算符和位置寻址来整合先前创建的Glucose_Category和Insulin_Category列中的信息。这可以根据患者的血糖和胰岛素水平识别特定的亚组,并仅关注属于这些定义的高血糖和胰岛素抵抗组的患者。
这里的数字高得惊人,如果病人的血糖水平处于这些高值范围之间,那么他们患糖尿病的可能性就很大
完成整个EDA后,需要准备用于建模的数据。首先,我们准备用于训练机器学习模型的特征(自变量)。在监督学习中,我们将数据集分为特征(用于进行预测的数据)和目标变量(我们想要预测的内容)。
独立特征之间的相关性:Glucose和Insulin之间存在相对较强的正相关性。这在生物学上是合理的,因为胰岛素会根据血糖水平释放以调节血糖水平。SkinThickness和BMI是独立特征之间最强的相关性之一。这很合理,因为皮褶厚度测量值通常用于计算或与BMI相关。Pregnancies和Age也暗示了强烈的正相关性。这是合乎逻辑的,因为女性随着年龄的增长通常会怀孕更多次。
标准化是机器学习中常见的预处理步骤,旨在确保值较大的特征不会对模型造成不成比例的影响。这可以通过将数据变换为平均值为0、标准差为1来实现。
再次,你还记得我们说过这个数据集不平衡吗?你的模型可能倾向于多数类,即使你获得了很高的准确率,也可能在关键的地方表现不佳。95%的准确率可能掩盖了模型从未正确预测少数类(重要的类)的事实——而当它真正重要时,这可能会带来灾难性的后果。因此,我们不应该关注准确率,而是应该评估这些模型的指标:精度、准确率、F-1分数和AUC(曲线下面积)。
精确度是:“模型每次说‘糖尿病’时,有多少人实际上是糖尿病患者?”——如果你的模型说有10个人是糖尿病患者,但实际上只有6个人是糖尿病患者,那么你的精确度就是0. 6(非糖尿病患者也是如此)
召回率是:“在所有实际的糖尿病病例中,模型捕获了多少个?”——这对于非糖尿病类别也存在)
F1分数是:“精确度和召回率之间的平衡点在哪里?”——这通常是不平衡数据集的最佳指标。它是精确度和召回率的调和平均值。为了获得较高的F1分数,你的召回率和精确度也必须很高。
AUC是:“模型能多好地区分类别(例如,是与否)?”——这个值介于0到1之间。这往往会对模型的整体性能进行排名
为了评估机器学习模型的性能,必须将数据集拆分为两部分:用于训练模型的训练集,以及用于评估模型在未知数据上表现的测试集。我们将数据集的20%分配给测试集,80%分配给训练集。我们使用Scikit-learn的训练-测试拆分功能来执行此操作。
因为这是一个分类模型,所以我们将使用决策树、随机森林等分类模型。
我们从逻辑回归开始:
现在我们尝试随机森林
接下来是决策树:
K最近邻分类器下一步:
我们对比了多个模型训练效果如图所示:
我们对随机森林和决策树模型执行了GridSearch和RandomizedSearchCV,希望在评估期间获得更好的F1分数。
以下是所有模型的最终表现:
调整随机森林(随机搜索)在少数结果中表现最佳,而KNN在多数结果中表现最佳。我们选择部署调整随机森林来测试我们的虚拟数据,但这还有待观察。
这是所有使用的模型的2*4混淆矩阵
这有助于我们对每个模型在训练和测试中使用的属性进行排名,以确定或选择类别。
由此可以肯定的是:血糖是预测患者糖尿病的首要决定因素。BMI、年龄和胰岛素也是预测结果的关键属性。
测试一下:
你看到这张气泡图了吗?它告诉我们,在血糖和BMI水平较高时,有一簇大的橙色气泡(结果=1),这表明BMI和血糖值较高的老年人更有可能获得积极的结果。你会注意到,许多大的紫色圆圈位于血糖轴的下方。这意味着他们可能年龄较大、体重较重——但他们的血糖水平不高,所以他们不是糖尿病患者。
大橙色(上图)=高BMI+高血糖+年龄较大=高风险
大紫色(下图)=可能年纪大或BMI高,但血糖正常或有其他保护因素
最上象限的圆圈大多巨大且呈橙色。这告诉我们,胰岛素抵抗和血糖升高(见上图)的情况不容乐观。这几乎肯定会导致糖尿病,或者至少是定时炸弹。这里大多数负面结果的血糖和胰岛素水平都正常。
现在,令人瞠目结舌的事情发生了!因为我喜欢风险分析,所以我们喜欢用几率来衡量概率。我们建立了一个简单的风险评分系统,如果BMI>30,则+1;如果血糖>140,则+1;如果年龄>40,则+1;如果胰岛素>150,则+1;如果怀孕次数>3,则+1。我们计算了每个分数对应的糖尿病发病率,并将其列在0-1范围内的热图上(根据符合的属性,分数越接近1,患者患糖尿病的风险就越大)。
即使只超过3个阈值,患者也或多或少有可能患有糖尿病。超过4个阈值是一个巨大的灾难性危险信号,我们希望迅速找到干预措施,而超过5个阈值几乎肯定是糖尿病
我们将一个虚拟数据集传递给模型,以测试该患者是阳性还是阴性。我们将数据以数组的形式传递,顺序与数据字典中的顺序相同,然后缩放数据,使用部署的模型执行预测,并评估两种结果的确定性概率。请看下面的代码:
预计这位患者最有可能患有糖尿病——我叫她Anaya
这是一个显示Anaya的用户资料及其病史的仪表板
我们还做了一个交互式的,要求用户输入。我们收集了用户(例如患者)的医疗输入,对输入进行预处理,使其与经过训练的机器学习模型(例如本例中的KNN)使用的格式相匹配,预测患者是否可能患有糖尿病,并显示结果的概率和解释。
我们利用try-except验证块来确保数据float仅在数据类型中被接受并附加到列表数组中patient_data
在这里,你可以看到,即使它预测患者可能患有糖尿病,也并不像第一个例子那样确定。所以,谁知道呢?这可能是假阳性(也可能不是)。
当我们继续探索健康与机器学习的交集时,记住:每个数据点不仅仅是一个统计数据;它代表着一个人类的故事。
长按👇关注-数据STUDIO-设为星标,干货速递