使用 Intel® Distribution for Python 进行肝病患者数据集分类
本文着重介绍了在 Intel® Xeon® 可扩展处理器上使用 Intel® Distribution for Python* 对印度肝病患者数据集进行分类的实现。
摘要
本文着重介绍了在 Intel® Xeon® 可扩展处理器上使用 Intel® Distribution for Python* 对印度肝病患者数据集进行分类的实现。采用了各种预处理步骤来分析它们对机器学习分类问题的影响。通过各种特征,肝病患者分类旨在预测一个人是否患有肝病。无需手动干预即可早期确定疾病,这将为医疗领域的人们提供极大的支持。使用 SMOTE 作为预处理方法和随机森林算法作为分类器获得了良好的结果。
引言
肝脏是人体中最大的实器官,执行多项重要功能。其主要功能包括制造必需的蛋白质和凝血因子、代谢脂肪和碳水化合物等。
过量饮酒、病毒、摄入受污染的食物和药物等是肝脏疾病的主要原因。在早期阶段,症状可能可见,也可能不可见。如果未在早期阶段诊断,肝脏疾病可能导致危及生命的状况。
在印度,根据世界卫生组织于 2014 年 5 月发布的最新数据,肝脏疾病死亡占总死亡人数的 2.44%。此外,印度每年约有 100 万人被诊断出患有肝脏疾病。随着越来越多的人患上这种疾病,迫切需要寻找早期检测这些疾病的方法。这不仅能挽救生命,而且随着技术的发展,还能使医疗治疗更准确、更快速。此外,病例的增加也有助于在应用技术时构建数据库。
分类是处理医疗领域此类问题的有效技术。利用可用的特征值,分类器可以预测一个人是否患有肝病。这种能力将有助于医生提前识别疾病。始终建议减少 **第一类错误**(第一类错误是指在原假设实际为真时拒绝了原假设),因为错误的诊断可能导致致命的状况。
在本实验中,在构建和训练模型进行比较之前,尝试了各种预处理方法。在 Intel Xeon 可扩展处理器上使用 Intel Distribution for Python 中的 scikit-learn*、numpy 和 scipy* 等计算库来创建预测模型。
环境设置
表 1 描述了用于进行实验的环境设置。
表 1. 环境设置
安装 | 版本 |
---|---|
Processor | Intel® Xeon® Gold 6128 处理器 3.40 GHz |
系统 | CentOS* (7.4.1708) |
每个插槽的核心数 | 6 |
Anaconda*(带 Intel 通道) | 4.3.21 |
Intel® Distribution for Python* | 3.6.3 |
Scikit-learn* | 0.19.0 |
Numpy | 1.13.3 |
Pandas | 0.20.3 |
数据集描述
印度肝病患者数据集是从印度安得拉邦东北地区收集的。这是一个二元分类问题,类别标记为肝病患者(在数据集中表示为 1)和无肝病患者(表示为 2)。有 10 个特征,如表 2 所列。
表 2. 数据集描述
属性名称 | 属性描述 |
---|---|
V1 | 患者年龄。年龄超过 89 岁的患者均列为 90 岁。 |
V2 | 患者性别 |
V3 | 总胆红素 |
V4 | 直接胆红素 |
V5 | Alkphos 碱性磷酸酶 |
V6 | Sgpt 丙氨酸氨基转移酶 |
V7 | Sgot 天冬氨酸氨基转移酶 |
V8 | 总蛋白 |
V9 | 白蛋白 |
V10 | A/G 比率,白蛋白与球蛋白比率 |
类 | 肝病患者或否 |
方法论
已采用以下图示的方法来执行肝病患者数据集分类实验。
数据分析
在对可用数据执行任何处理之前,建议进行数据分析。此过程包括数据可视化、识别异常值和倾斜的预测变量。这些任务有助于检查数据,从而发现数据集中缺失的值和不相关的信息。执行数据清理过程来处理这些问题并确保数据质量。更深入地了解数据集有助于识别有用信息并支持决策。
印度肝病患者数据集包含 583 条记录,其中 416 条是肝病患者的记录,其余是无肝病患者的记录。该数据集有 10 个特征,其中只有一个分类数据(V2 - 患者性别)。数据集的最后一列表示每个样本所属的类别(肝病患者或非肝病患者)。值为 1 表示该人患有肝病,值为 2 表示该人没有肝病。数据集中没有缺失值。
图 2 显示了患有肝病的患者和无肝病的患者数量的可视化,而图 3 表示数据集中男性和女性人口的可视化。数字变量的直方图由图 4 表示。
数据预处理
某些数据集包含不相关信息、噪声、缺失值等。应妥善处理这些数据集,以获得更好的数据挖掘过程结果。数据预处理包括数据清理、准备、转换和降维,将原始数据转换为适合进一步处理的形式。
实验的主要目标是展示各种预处理方法在分类之前对数据集的影响。应用了不同的分类算法来比较结果。
一些预处理包括
- 归一化:此过程将每个特征缩放到给定范围内。使用 sklearn 包中的
preprocessing.MinMaxScaler()
函数执行此操作。 - 分配分位数范围:
pandas.qcut
函数用于基于分位数的离散化。根据样本分位数或排名,对变量进行离散化并分配一些分类值。 - 过采样:此技术用于处理不平衡数据集。过采样用于生成少样本类别中的新样本。SMOTE 用于过采样数据。SMOTE 通过识别特定样本提出多种变体。使用
imblearn.over_sampling
中的SMOTE()
函数来实现。 - 欠采样:处理不平衡数据的另一种技术是欠采样。此方法用于减少目标类别中的样本数量。ClusterCentroids 用于欠采样。K-means 算法用于此方法以减少样本数量。使用
imblearn.under_sampling
包中的ClusterCentroids()
函数。 - 二元编码:此方法将分类数据转换为数值形式。当特征列具有二元值时使用。在肝病患者数据集中,V2 列(性别)的值为 male/female,它被二元编码为“0”和“1”。
- 独热编码:将分类特征映射到一组值为“1”或“0”的列,以表示该特征的存在或不存在。在这里,在为某些特征(V1、V3、V5、V6、V7)分配分位数范围后,应用独热编码以 1 和 0 的形式表示它们。
特征选择
特征选择主要应用于大型数据集以降低高维度。这有助于识别数据集中最重要的特征,可用于模型构建。在印度肝病患者数据集中,应用随机森林算法来可视化特征重要性。使用 sklearn.ensemble
包中的 ExtraTreesClassifier()
函数进行计算。图 5 显示了使用森林树的特征重要性。从图中可以清楚地看出,最重要的特征是 V5(Alkphos 碱性磷酸酶),最不重要的特征是 V2(性别)。
删除不重要的特征有助于减少处理时间,而不会显著影响模型的准确性。这里删除 V2(患者性别)、V8(总蛋白)、V10(A/G 比率,白蛋白与球蛋白比率)和 V9(白蛋白),以减少模型构建的特征数量。
模型构建
使用了一系列分类器来创建各种分类模型,这些模型可用于预测。将数据集的一部分用于训练模型,其余部分用于测试。在本实验中,90% 的数据用于训练,10% 用于测试。由于应用了 StratfiedShuffleSplit
(scikit-learn 中的一个函数)来分割训练-测试数据,因此每个类别的样本比例得以保留,即在此情况下,每个类别的 90% 样本用于训练,其余 10% 来自每个类别用于测试。使用了 scikit-learn 包中的分类器来构建模型。
预测
可以使用训练模型来预测新输入的标签。分析了准确率和 F1 分数,以了解模型在训练过程中学习得有多好。
模型评估
可以使用多种方法来评估模型的性能。交叉验证、混淆矩阵、准确率、精确率、召回率等是一些流行的性能评估指标。
仅凭准确率无法评估模型的性能,因为存在误导的可能性。因此,本实验在评估时考虑了 F1 分数和准确率。
观察和结果
为了找出特征选择对肝病患者数据集的影响,分析了有和没有特征选择时的准确率和 F1 分数(见表 3)。
在分析结果后,推断出除随机森林分类器外,删除最不重要的特征并未对结果产生显着变化。因为特征选择有助于减少处理时间,所以在进一步处理技术之前应用了它。
表 3. 有无特征选择时的性能
分类器 | 无特征选择 | 有特征选择 | ||||
---|---|---|---|---|---|---|
准确性 | F1 分数 | 准确性 | F1 分数 | |||
患者有 肝病 |
患者无 肝病 |
患者有 肝病 |
患者无 肝病 |
|||
随机森林分类器 | 71.1186 | 0.81 | 0.37 | 74.5762 | 0.84 | 0.44 |
Ada Boost 分类器 | 74.5762 | 0.83 | 0.52 | 72.8813 | 0.82 | 0.43 |
决策树分类器 | 66.1016 | 0.76 | 0.41 | 67.7966 | 0.77 | 0.49 |
多项式朴素贝叶斯 | 47.4576 | 0.47 | 0.47 | 49.1525 | 0.5 | 0.48 |
高斯朴素贝叶斯 | 62.7118 | 0.65 | 0.61 | 61.0169 | 0.62 | 0.6 |
K-邻近分类器 | 72.8813 | 0.83 | 0.33 | 72.8813 | 0.83 | 0.33 |
SGD 分类器 | 71.1864 | 0.83 | 0 | 67.7966 | 0.81 | 0 |
SVC | 71.1864 | 0.83 | 0 | 71.1864 | 0.83 | 0 |
OneVsRest 分类器 | 62.7118 | 0.77 | 0.08 | 32.2033 | 0.09 | 0.46 |
进行特征选择后,应用了一些预处理技术,包括归一化。在这里,每个特征都被缩放和平移,使其在训练集上的给定范围内。通过为某些特征值分配分位数范围进行了另一种预处理。在此之后进行独热编码,以 1 和 0 的形式表示每个列。进行归一化和分位数分配后的分类结果见表 4。分析后发现,预处理并未提高模型的性能。但对列进行独热编码有助于加快模型构建和预测。
表 4. 归一化和分位数范围的性能
分类器 | 规范化 | 分配分位数范围 | ||||
---|---|---|---|---|---|---|
准确性 | F1 分数 | 准确性 | F1 分数 | |||
患者有 肝病 |
患者无 肝病 |
患者有 肝病 |
患者无 肝病 |
|||
随机森林分类器 | 72.8813 | 0.82 | 0.43 | 71.1864 | 0.82 | 0.32 |
Ada Boost 分类器 | 72.8813 | 0.82 | 0.43 | 76.2711 | 0.85 | 0.36 |
决策树分类器 | 67.7966 | 0.77 | 0.49 | 74.5762 | 0.84 | 0.35 |
多项式朴素贝叶斯 | 71.1864 | 0.83 | 0 | 67.7966 | 0.75 | 0.56 |
高斯朴素贝叶斯 | 57.6271 | 0.58 | 0.58 | 37.2881 | 0.21 | 0.48 |
K-邻近分类器 | 72.8813 | 0.83 | 0.33 | 71.1864 | 0.78 | 0.59 |
SGD 分类器 | 71.1864 | 0.83 | 0 | 71.1864 | 0.83 | 0 |
SVC | 71.1864 | 0.83 | 0 | 71.1864 | 0.83 | 0 |
OneVsRest 分类器 | 71.1864 | 0.83 | 0 | 71.1864 | 0.83 | 0 |
另一推论是,在某些情况下,非患者的 F1 分数为零,这是一个主要挑战。在这种情况下,准确率可能很高,但模型不可靠,因为分类器将所有数据分类到一个类别中。主要原因可能是数据不平衡。为了解决这个问题,引入了欠采样和过采样技术。使用 Cluster centroids 进行欠采样,使用 SMOTE 算法进行过采样。结果如表 5 所示。
表 5. 欠采样和 SMOTE 的性能。
分类器 | Cluster Centroid(欠采样) | SMOTE(过采样) | ||||
---|---|---|---|---|---|---|
准确性 | F1 分数 | 准确性 | F1 分数 | |||
患者有 肝病 |
患者无 肝病 |
患者有 肝病 |
患者无 肝病 |
|||
随机森林分类器 | 67.7966 | 0.73 | 0.6 | 86.4406 | 0.91 | 0.75 |
Ada Boost 分类器 | 66.1016 | 0.71 | 0.58 | 74.5762 | 0.81 | 0.63 |
决策树分类器 | 57.6271 | 0.65 | 0.47 | 72.8813 | 0.79 | 0.6 |
多项式朴素贝叶斯 | 45.7627 | 0.41 | 0.5 | 49.1525 | 0.5 | 0.48 |
高斯朴素贝叶斯 | 59.3220 | 0.6 | 0.59 | 62.7118 | 0.65 | 0.61 |
K-邻近分类器 | 67.7966 | 0.72 | 0.63 | 71.1864 | 0.8 | 0.51 |
SGD 分类器 | 33.8983 | 0.13 | 0.47 | 69.4915 | 0.81 | 0.18 |
SVC | 66.1016 | 0.69 | 0.63 | 66.1016 | 0.71 | 0.6 |
OneVsRest 分类器 | 52.5423 | 0.55 | 0.5 | 40.6779 | 0.29 | 0.49 |
表 5 显示,欠采样和过采样可以解决数据不平衡问题。使用 Cluster centroids 作为欠采样技术并未提高准确率,而 SMOTE 确实在准确率方面取得了巨大改进。对 **随机森林分类器** 和 **Ada Boost 分类器** 获得了最佳准确率。通过在 Intel® Xeon® 可扩展处理器上运行机器学习问题,并利用 Intel Distribution for Python 中的计算库,处理能力得到了提高。
图 6 显示了最佳分类器(随机森林分类器)的 5 折交叉验证的 ROC 曲线。在交叉验证期间获得了更高的准确率,因为验证样本来自经过过采样(SMOTE)的训练样本。在测试期间未达到预期的交叉验证准确率,因为在执行 SMOTE 之前将测试数据与训练数据隔离开。
图 7 给出了各种分类器的 ROC 曲线。可以使用此来评估不同分类器的分类器输出质量。
结论
预处理和分类方法并未提高模型的准确率。使用 SMOTE 处理数据不平衡为随机森林和 Ada Boost 分类器提供了更好的准确率。使用 Intel Xeon 可扩展处理器上的 Intel Distribution for Python 中的计算库创建了一个好的模型。
参考文献
- https://software.intel.com/en-us/articles/intel-optimized-packages-for-the-intel-distribution-for-python
- https://scikit-learn.cn
- https://software.intel.com/en-us/distribution-for-python
作者
Aswathy C 是 Intel® AI Academy Program 的技术解决方案工程师。