网格搜索、管线、决策树、支持向量机、Hyperparameter优化、模糊矩阵、ROC曲线。 如果你三个月前跟我说这些术语,我绝对不知道你在说什么。
但是,我刚刚完成了使用所有这些技术、方法和工具的项目。 我的大脑每天都接受被新概念淹没的事实,期待着能马上使用它们。
Flatiron School数据科学项目的第三个主要项目是专门从事分类的机器学习的监督项目。 与以往的其他项目不同,要求建立预测离散目标变量的模型,而不是连续或数值目标变量。
与预测票房、电影价值、住宅售价不同,可以从几个不同的分类数据集中选择,也可以选择自己的一个。 在搜索了存储库和数据收集几天之后,我最终确定了自己感兴趣的东西,提出了需要解决的现实问题。
听到朋友们的话题时,我意识到我错过了难得的机会,为了这个项目选择了积极、有吸引力的东西进行了调查。
我听学生们谈论他们想做的关于体育的各种预测。 另外,有些人计划使用算法预测电脑游戏的音乐种类和评分。 非常有趣的想法! 轮到我介绍我的主题时,我深深地叹了口气,笨拙地解释,我选择了一组关于胎儿健康结果和死亡率的数据集。 是的。 不知为什么,无忧无虑的我选择了最认真、最失望的话题。
但是,我的项目本身和数据目标实际上是相当有前途和乐观的。 所有这些前提都是美国持续存在的公共卫生问题——胎儿死亡率。 这是我非常关心的话题,为了这个目的寻找正确的数据花了几个小时。
研究发现,该数据集包含2000多行患者的心电图(CTG )记录,包括胎儿心率、子宫收缩、胎儿运动等特征。 然后,每个记录被“专科产科医生”归类为正常、可疑或病理胎儿的健康结果。
我将其调整为二元分类问题,将可疑结果和病理结果合并为一个类别,并将其标记为“危险”。 我打算证明只用CTG检查的指标就能预测胎儿的健康结果。 也就是说,这种预测可以实现自动化,医疗服务提供商只需要阅读报告,就可以采取更加积极的救生措施。
我着手这个项目时首先注意到的一件事是,管道基本上是魔法的东西,简化了将分类器和数据匹配的过程。
流水线负责扩展、预处理和设置分类器的所有步骤,并将它们组合成一个对象,从而干净地完成流程,消除人为错误。
因为有各种各样的算法,所以想探索,所以写了函数。 这个函数输入分类器并返回管道对象。 (请注意,由于我的目标变量不均衡,class_weight参数被设置为“‘balanced”; 我的数据中,健康状况正常的婴儿比危险的婴儿多得多。 )
froms klearn.pipelineimportpipeline
# #创建具有分类器输入的管道
de fpipe _ maker (分类器) :
“”接受分类器并返回到管道“”
pipe=pipeline([(SCL (,标准标量) )、
(clf )、分类器(分类_权重=)平衡)、随机状态=42 ) ) )
返回管道
现在,可以说比管道搜索更令人惊讶的是网格搜索的能力。
使用GridSearchCV,可以通过检查单个模型的不同超级参数并选择最佳参数来优化选定测量的模型。
在这种情况下,我优先考虑的指标是召回率。 通过优化召回率,使模型预测中的错误否定或第二类错误的数量最小化。
我对模型错误地预测婴儿有危险没有意见,但对模型错误地预测婴儿健康有时并不太满意。 召回率指标是该项目的最重要指标,远远超过精度、准确性或其他任何评价指标。
为此,我们创建了一个函数,接受一组要与管道对象(如上面的函数)进行调谐的超级参数,并返回网格搜索对象。 如果不是再现率(如准确性),只需更改分数参数以反映出来。
froms klearn.model _ selectionimportgridsearchcv
创建包含# # #管道的网格搜索
efgridsearch _ maker (管线,参数) :
' '
''接收管道和参数网格,返回GridSearchCV对象''' return GridSearchCV(estimator=pipeline, param_grid=params, scoring='recall', cv=10, n_jobs=-1)最后,我编写了一个函数来接收网格搜索对象(如上面的函数所创建的对象)并返回用于评估的相关信息。这才是真正神奇的地方。最后一个函数接受上面的网格搜索对象,并对模型进行优化,结果:
基于你选择的评估指标,为你的模型提供最好的超参数一个分类报告,其中包含这个优化模型的精度、召回率、F1得分和准确度一个彩色编码的混淆矩阵告诉你真正例,真反例,假正例,假反例的数量from sklearn.metrics import recall_score, confusion_matrix, classification_report, plot_confusion_matrix def find_best_recall(gridsearch): """ 运行网格搜索,遍历预定义的网格参数,并返回最佳参数以优化召回分数。 将分类器与X_train和y_train拟合。 确定并打印召回的最佳参数。 确定并打印最佳训练集召回率。 使用最佳参数对测试数据进行预测。 打印最好的测试集召回率。 打印最佳模型的分类报告。 最佳模型的混淆矩阵。 参数: gridsearch: 预定义的GridsearchCV实例,已经设置了参数和估计器/管道。 Returns: 最佳参数为特定的网格搜索,基于召回率分数。 最佳训练集召回率。 最好的测试集召回率。 最佳模型分类报告。 最佳模型的混淆矩阵。 """ # 匹配网格搜索对象 best_recall = 0.0 # 匹配网格搜索 gridsearch.fit(X_train, y_train) # 最佳参数 print('Best params: %s' % gridsearch.best_params_) # 最好的训练数据召回率 print('Best training recall: %.3f' % gridsearch.best_score_) # 用最好的参数预测测试数据 y_pred = gridsearch.predict(X_test) # 测试数据召回率与最好的参数 print('Test set recall score for best params: %.3f ' % recall_score(y_test, y_pred)) # 混淆矩阵和分类报告 print(confusion_matrix(y_test, y_pred)) print(classification_report(y_test, y_pred)) print('Recall score: ',recall_score(y_test, y_pred)) # 绘制混淆矩阵 plot_confusion_matrix(gridsearch, X_test, y_test,cmap="RdPu") plt.show()然后,一旦你有了这个,你就可以再做一次!一遍又一遍,尽可能多地重复,直到得到最好的模型。
就我个人而言,我尝试了一些决策树、一些逻辑回归、一个随机森林、一个支持向量机,甚至一些带有TPOT分类器的AutoML(结果并不像我希望的那样好)。
上面这张图是我使用极限树(Extra Trees )分类器完成的最好的模型。它的召回分数是97%,虽然不是很完美,但是比我的基准模型的召回分数77%好多了。
极限树分类器到底是什么?
如果你熟悉随机森林,那么你就会知道它是一种由决策树组成的算法。
极限树是一种非常类似的算法,它使用一系列决策树来对数据点所属的类或类别做出最终预测。然而,极限树与随机森林的不同之处在于,它使用了整个原始样本,而不是像随机森林那样对数据进行子抽样并进行替换。
另一个区别是节点的分割方式。虽然随机森林总是选择可能的最佳分割,但极限树选择随机分割。极限树和随机森林都被编程来优化最终结果。
我很惊讶,我可以用极限树建立一个比随机森林更好的模型。虽然我的随机森林模型和我的网格搜索的最佳参数返回了94%的不错的召回率分数,我的极限树模型返回了一个更好的召回率分数。
这里的教训是,使用不同的算法和分类器可以获得很多有价值的东西,所以不断迭代不同的模型和算法总是一个好主意,直到你找到最优的一个适合你的特定数据集和评估指标。
在经历了线性回归和处理多重线性和异方差等令人头疼的问题之后,这些分类模型真的很棒。看到这些模型能做多少事情是很有启发性的;他们如何在不完善的数据下工作,仍然表现出色。
我特别喜欢能够直观地看到决策树模型是如何做出决策的!了解所有这些不同的模型是如何运作的,它们背后的数学和科学,以及它们所表现出的直觉和可解释性是很吸引人的。
如果你对本文使用的方法、详细的结果和可视化、以及结论和建议感到好奇,请查看这个GitHub项目:
https://github.com/dtunnicliffe/fetal-health-classification。