Scikit-learn 核心开发人员专访:建立机器学习工作流最容易犯这2点错误

2019-12-05 21:13:35 浏览数 (1)

本文作者 | Haebichan Jung

编  译 | skura

本文是一篇对 Scikit-learn 开发者的专访,原载于 towardsdatascience,我们对其进行了编译整理,采访内容如下文。

采访者:Haebichan Jung,TowardsDataScience 网站项目负责人。旧金山 Recurly 的数据科学家。

受访者:Andreas Muller,Scikit learn 的核心开发人员,书籍《Python 机器学习入门》的作者,哥伦比亚大学数据科学研究所的科学家、讲师。

Haebichan Jung:开源社区是如何维护 Scikit-learn 的?结构化的库的工作流程和所有权是怎么样的?

Andreas Muller:首先是用户。大多数对 Scikit-learn 有贡献的人最开始都是用户。如果你不使用这个软件包,你就没有动力去做这件事情。

其次,大多数伟大的贡献都是由人们的用例驱动的。有些版本是我为 Scikit-learn 编写的,因为我想使用它们。这些通常是最好的版本。你不想迎合软件太具体的用例,你不想在功能上加标签。

第三,对于像 Scikit-learn 那样复杂的东西,你不想一开始就添加一些新的大功能。很多人都有他们最喜欢的模型,他们想通过将其添加到 Scikit-learn 中来开始他们的贡献。但是,现在将一个模型添加到 Scikit-learn 需要大约一年的时间。所以我真的建议从小事做起。我本人是从文档的排版开始的。改进文档总是受欢迎的。还有很多关于问题追踪的东西。

Haebichan Jung:在机器学习工作流中实现 Scikit-learn 的那些人中,你看到了哪些常见的错误或低效的事情?

Andreas Muller:一般来说,与 Scikit-learn 和机器学习相关的常见错误有两种。

1.对于 Scikit 学习,每个人都可能在使用管道。如果你不使用管道,那你可能有些地方做错了。2 年前,我们引入了列转换器,它允许你处理具有连续和分类变量的数据,或者处理其他类型 One-Hot 编码器时,一切都很好。

2。我在机器学习中看到的一个常见错误是没有对度量标准给予足够的关注。Scikit-learn 将精度用作默认度量。但一旦你有了一个不平衡的数据,准确度是一个可怕的指标。你真的应该考虑使用其他指标。我们不会改变默认的度量标准,因为准确性被广泛使用,而且有如此清楚的解释。但是,在机器学习中,查看其他度量并为你的用例考虑是否使用它们是最常见的问题。

什么是管道?如果它不准确,还有什么其他指标更适合机器学习?

在 Scikit-learn 中,每个 ML 模型都封装在一个称为「估计器」的简单 python 类中。通常在机器学习过程中,你可能会有一个带有一系列预处理步骤的分类器。管道允许你封装所有预处理步骤、特征选择、缩放、变量编码等,以及通常在单个估计器中具有的最终监督模型。

所以你有一个对象来完成你所有的工作。它非常方便,能够使编写错误的代码出现的更少,因为它可以确保你正的训练集和测试集是一致的。最后,你应该使用交叉验证或网格搜索 CV。在这种情况下,重要的是所有的预处理都在交叉验证循环中进行。如果在交叉验证循环之外进行功能选择,可能会发生非常糟糕的事情。但在你的管道中,你知道一切都在交叉验证循环中。

Andreas Muller 哥伦比亚系列讲座

对于度量,它们通常在二进制分类中被忽略。在二进制分类中,精度取决于你的目标是什么。我喜欢看 ROC 曲线下的面积和平均精度。这些是某种细粒度的度量。我也喜欢看精确召回曲线(AUPRC)。这些指标的意义在于,它们不依赖于你应用的决策阈值,因为它们是排名指标。所以你需要决定在哪里设置阈值来表示「在什么概率下我说是 1 类还是 0 类?」。

你可以研究的其他指标是 F1 指标或平均召回率/精确度,这些也很有趣。

Haebichan Jung:Scikit-learn 包中是否有其他工具或功能让你觉得使用不足或被低估?

Andreas Muller:有一个功能还没被充分利用,因为它还是很新的,它就是 Hist 梯度增强。这是 LightGBM 的根的实现,因此比以前的梯度增强实现快得多。它比 XGBoost 稍快,比 LightGBM 稍慢。目前它还不能支持缺失值的处理,但这个功能将很快在 2 周后的下一个版本中发布。它也不支持分类变量,这个功能将在明年春天左右发布。

Haebichan Jung:你提到 LightGBM 很有意思,因为越来越多基于 python 的 ML 库正在发布,比如 Catboost,还有像 Pythorch 这样的深度学习框架。你觉得这些在 ML 领域成长的玩家怎么样?这种现象是竞争的反应吗?

Andreas Muller:我认为在大多数情况下,多元化是好的。其中大多数框架提供了类似于 Scikit-learn 的接口,因此与我们的包兼容。由于 Scikit-learn 的应用非常广泛,所以开发速度很慢。我们可以看到,XGBoost 和 LightGBM 对人们来说非常有价值。因此,我们希望每个人都知道这一点,我们希望包括在 Scikit-learn 中的包能够接触到更广泛的受众。

对于深度学习库来说,一部分原因是它们可以更快地移动,因为我们移动得太慢了。当然还有两件事需要注意:

1.与谷歌或 Facebook 相比,我们的资源真的很少,所以和那些公司的工程师竞争是没有意义的。我认为 Keras 真的很酷,我没有理由在 Scikit-learn 中重新实现这样的东西。

2.技术原因。现在,要在不同的平台上无缝地实现 GPU 支持仍然很困难。你可以在 Tensorflow 中看到这一点。Tensorflow 上有不同的版本,针对不同的架构进行编译,你必须自己编译。我们不会在 Scikit-learn 增加这么多麻烦。

Haebichan Jung:你在哥伦比亚大学关于不平衡数据的讲座中说过,这个问题有两个主要的解决方案:1)在改变数据后建立模型(欠采样/过采样)和 2)改变模型(训练程序本身)。每种策略的优缺点是什么,尤其是在 Scikit-learn 方面?

Andreas Muller:我想从你的问题中退一步,再次提到最重要的是指标以及你如何评估它。你的目标是什么?你的目标绝不是精确,也绝不是 ROC-AUC。这不是你做应用的目的。你应该考虑在应用程序的上下文中生成特定结果意味着什么。

一旦有了这个目标,你就可以定义度量,尝试不同的方法来最大化这些度量。重采样非常吸引人的地方在于,你经常可以抛出大量数据,却不会真正影响结果。如果你有 1:1000 的比率,你不想把它低估到 1:1,那么你可以设置成 1:100 或 1:10,你可以得到完全相同的结果。这样你的数据集减少了 100 倍。

「你的目标绝不是精确,也绝不是 ROC-AUC。这不是你做应用的目的。你应该考虑在应用程序的上下文中生成特定结果意味着什么。」

所以如果你有大量的数据并且计算不是问题的话,欠采样是更有效地得到类似结果的方法。相反,我并没有真正看到人们在实践中使用 SMOTE,这就是合成数据生成。人们经常提到它,但我有点怀疑。

在改变模型方面,类权重是人们经常使用且会有帮助的。类权重实际上改变了损失函数,这样就好像对少数类进行了过采样。所以你使用了所有的样本,但是给了少数类更多的权重。这是人们发现的有用的东西。但是,这更像是尝试不同的东西,并且你有正确的度量来衡量哪个解决方案最适合你的问题。

来自 Andreas Muller 的哥伦比亚系列讲座

Haebichan Jung:有趣的是,你是以这种方式提到 SMOTE。在我的公司,我们一直在试验 SMOTE。但就实际结果而言,在 AUC 或其他方面并没有什么大的好处。而且,因为我正在创建所有这些合成数据,它大大减慢了我的管道线。所以我想问你,你自己的怀疑是从哪里来的?

Andreas Muller:因为我和每个人说的都和你说的一模一样。

Haebichan Jung:那你觉得这是为什么?

Andreas Muller:对我来说,机器学习中的很多东西都是经验性的。如果你在很多数据集上尝试它,但它对你没有帮助,那么它就是没有帮助。很难说为什么梯度增强效果很好。我想大多数人都相信梯度增强效果很好,但我不认为有人能正确解释为什么梯度增强比支持向量机更有效。我认为没有人能用简洁或有意义的方式来解释。

就 SMOTE 而言,我认为发生了两件事:

1.我认为 SMOTE 对数据的分布做出了假设。所以 A)要么假设相邻样本之间的直线是错误的;B)如果样本太远,并且中间有其他类的样本,那么情况可能会打破。

2.可能是添加这些合成样本实际上对你感兴趣的模型类没有帮助。

实际上,我和一个合作者有一个计划,要写一篇关于广泛基准的论文。正如你所说,为什么要尝试使用 SMOTE?因为这是在验证的文献中提出的方法,但在实践中,人们发现它并没有多大作用。

0 人点赞