用AI识别恶性乳腺癌肿瘤,一次对随机森林模型的经典用例
点击上方关注,All in AI中国
作者:Cameron Wolfe
在Sklearn Python库中,有一组可以导入的几个数据集。 在这些数据集中,这其中有一个(是在威斯康星州的观察中得出的)二元分类乳腺癌数据集。我选择处理这个数据集,因为它提出了一个我发现有影响力和有趣的主题(以及训练我的数据科学技能的好方法),我的目标是训练分类模型来识别恶性乳腺癌肿瘤,并达到准确率> 95%。我们可以按如下方式导入数据集:
创建基线模型来比较
在对数据集进行分析之前,通常可以创建一个基线分类模型,该模型可以当做基准来决定机器学习模型是否有效。为了创建这个基线模型,我查看了数据集中"恶性"(标记为1)和"良性"(标记为0)观察的分布。以下是显示两个目标类别分布的条形图:
从该图可以看出,存在大约350个"恶性"观察结果和大约220个"良性"观察结果。因此,如果每个观察结果都被预测为恶性,那么就会创建一个约61%准确率的模型——这个简单的模型将用作未来比较的基准。
数据清理和预处理
在定义简单基线模型之后,我对数据进行了一些快速清理和观察,例如检查空值,查看数据集中每个数据类型的特征,以及查看集合中的观察总数。 在这种情况下,因为数据(大多)来自Sklearn python库中的示例集,所以不需要进行太多的数据清理。如果数据集存储在pandas数据框中,则可以使用以下命令检查每个列的空值总数:
在这种情况下,数据集中不存在空值,因此不必替换/清除数据中的空值。另外,当检查每列的数据类型时(使用pandas数据帧的"dtypes"属性),发现所有数据都是"float64"类型。换句话说所有特征都已经是数值,因此无需进行数据清理即可创建可直接输入到机器学习模型中的特征。在这个预处理阶段,唯一有趣的发现是数据集仅包含了569个总观测值。对于训练机器学习模型而言,这是非常少量的数据,并且可能在将来产生问题(即模型的过度拟合或缺乏准确性),因此在选择使用随机森林对数据进行分类时需要考虑到这一点(阅读更多信息:https://www.kdnuggets.com/2017/10/random-forests-explained.html)。
探索性数据分析(EDA)
为了更好地理解数据集以及哪些特征可能会对机器学习模型有用,我们进行了简单的数据分析和可视化处理。首先是对集合中所有不同特征的相关矩阵进行可视化(相关性使用了pandas DataFrame上的"corr"方法计算)。该相关性图显示了哪些特征为问题提供了新的信息,哪些特征与该集合中存在的其他特征类似。将相关矩阵绘制为热图,这使得数据集中的特征之间的相关性变得更显而易见。如下图所示:
在这种情况下,具有白色的特征代表彼此之间具有高度的相关性。例如,特征对(0,2),(0,3)和(2,3)都是高度相关的。之后,当为机器学习模型选择特征时,考虑到这种高相关性(> 98%),也会消除其他相关性较低的特征。
除了可视化相关性之外,还对数据集中的每个特征进行单变量分析和可视化。更具体地说,我们可以创建一个特征值的散点图及其相关分类和每个目标类别的特征平均量的图。单独查看每个特征的分布可以更好地理解特征与指定的目标是否有差异性,从而揭示了哪些特征在创建分类模型时是有用的。一些结果如下:
在这种情况下,特征5显示了两个截然不同的目标类别之间的差异值,其中被分类为"良性"(0)的观察值似乎比被分类为"恶性"(1)的值更高。因此,这个可视化暗示特征5可能是包含在最终分类模型中的有用特征。
在上面的可视化图中,特征7似乎在两个目标类别之间具有相似的特征——即在散点图上,1和0的位置以及平均特征值都大致相似。因此,这个可视化暗示了特征7在确定精确分类时可能对我们的模型没有多大用处。
我们现在要做的是确定训练机器学习模型中使用了哪些特征,并对两个目标分类类别之间的差异特征进行保留,同时消除没有差异的特征。需要补充的是,一旦消除了这些特征,我们也就实现了对可视化的聚合(使用seaborn python库中的"pairplot"方法),并用做查看集合中一些有趣的特征属性。结果如下:
上面的图是根据每个观察的分类值进行着色后的结果。在大多数情况下,你可以根据图中的特征弄清楚两个目标分类类别之间的值的差异。
特征工程/选择
在对数据集进行简单的EDA之后,哪些功能对机器学习模型有用就会很清楚明了。因此,在选择/创建特征方面没有太多额外的工作可做。一些进行特征自动选择的方法包括:
- 使用Sklearn创建多项式和交互式特征。
- 运行一个简单的随机森林,并根据其对该模型的重要性来选择要素。
- 消除与集合中其他特征高度相关的特征。
创建多项式特征并不能改善随机森林模型的性能(其准确性实际上降低了)。但是,使用随机森林的"feature_importances_"属性过滤特征非常有用,而且还是会提高最终模型的准确性。为了创建这样的过滤器,我们对现有特征集(不包括多项式特征)进行了默认的随机森林训练,并且通过引用训练后的随机森林的"feature_importances_"属性来确定每个特征的重要性。为重要性较低的特征设置阈值,从数据集中删除所有小于重要性阈值的特征。我对重要性的阈值进行了测试,以确定哪个阈值的性能最佳,结果如下:
从上面的报告中可以看出,最佳过滤阈值为.008,准确率为95.5%(高于我最初的目标!)。现在我们开始创建最终模型。
创建随机森林模型
本实验使用Sklearn随机森林分类器对数据进行分类。可以将它通过以下代码导入:
上面的代码从是Sklearn库导入随机森林,并得出决策树的数量为50(n_estimators是指形成随机森林对象的决策树的数量),并将随机森林结果拟合到一组测试数据中。在该实验中,使用Sklearn.model_selection中的"train_test_split"方法将数据分成训练集和测试集。当随机森林进行分区训练和数据测试时,结果如下:
如上所示,决策树数量为50的随机森林在数据集上获得了95.77%的准确率!这超出了最初为此实验设置的95%准确率的目标。然而,在实验结束之前,我们对随机森林的不同数量的估计值进行了测试,以确定模型是否可以更准确一些。此外,我们还观察了性能最高的随机森林的准确率和召回率,以获得对模型整体质量的另一个度量。
测试不同的随机森林大小
选择大小分别为25,50,75,100,125和150的随机森林,并对每个模型的准确率进行测试,以确定那种大小的随机森林最有效。结果如下:
在上面的报告中,可以看出,大小为125时,准确率高达为96.7%!这样的准确率远高于95%的原始目标,因此选择该模型作为最佳性能进行测试,然后观察模型的准确率和召回率以评估其整体质量。
准确率和召回率
由于原始数据集有些不平衡(目标分类类别分布不均匀),一种良好的做法是对模型的质量进行准确率以外的度量——模型与目标分布具有不平衡性可能获得高准确率而缺乏实际拟合的数据。因此,我们决定观察每个目标分类类别的模型的准确率和召回率。如果你不熟悉这些术语,我建议你阅读本文(http://scikit-learn.org/stable/auto_examples/model_selection/plot_precision_recall.html)以更好地了解它们是什么。准确率和召回一样,它可以作为衡量机器学习模型有效的一个度量。使用以下代码可以观察随机森林模型的准确率和召回率:
利用上面的代码对大小为125的随机森林模型进行准确率和召回率的评估,并得到以下结果:
该模型获得了(平均)99%的准确率和99%的召回率,这是一个非常好的结果(1.0是最佳结果)。观察该度量之后,可以发现随机森林分类模型与数据拟合的很好,准确率和召回率超过96%达到了99%。
结论
在本文中,我使用Sklearn乳腺癌数据集来建立了随机森林分类模型,将乳腺癌肿瘤分为"恶性"或"良性"。我最初的目标是获得一个具有至少95%准确率的模型。在完成简单的EDA以确定数据集中最重要的特征,分析各种选定特征的特征重要性,以及测试不同大小的随机森林之后,我获得了最终模型,准确率为96.7%!