路线图#

本文档的目的#

本文档列出了核心贡献者希望在 scikit-learn 中看到开发的总体方向。这里列出的项目并不意味着它们一定会实现,因为资源有限。相反,它表明我们欢迎在这个主题上的帮助。

目标声明:2018 年的 Scikit-learn#

在 Scikit-learn 诞生 11 年后,机器学习领域发生了很多变化。主要变化包括

  • 计算工具:GPU 的利用、Scala/Spark 等分布式编程框架。

  • 用于实验、处理和数据管理的高级 Python 库:Jupyter notebook、Cython、Pandas、Dask、Numba…

  • 机器学习研究重点的变化:人工智能应用(其中输入结构是关键),包括深度学习、表示学习、强化学习、领域迁移等。

在过去十年中,一个更微妙的变化是,由于对 ML 的兴趣变化,机器学习领域的博士生更有可能为 PyTorch、Dask 等做出贡献,而不是为 Scikit-learn 做出贡献,因此我们的贡献者群体与十年前大不相同。

Scikit-learn 在实践中仍然非常流行,用于尝试规范的机器学习技术,特别是用于实验科学和数据科学中的应用。我们提供的很多东西现在已经非常成熟。但维护它可能很昂贵,因此我们不能包含任意新的实现。然而,Scikit-learn 在定义用于开发核心库之外的可互操作机器学习组件的 API 框架方面也至关重要。

因此,我们在这个时代的主要目标是:

  • 继续维护一个高质量、文档齐全的规范工具集合,用于在当前范围内进行数据处理和机器学习(即矩形数据,在很大程度上不受列和行顺序的影响;使用简单结构预测目标)

  • 提高用户开发和发布外部组件的便捷性

  • 提高与现代数据科学工具(如 Pandas、Dask)和基础设施(如分布式处理)的互操作性

许多更细粒度的目标可以在问题跟踪器上的 API 标签 下找到。

架构/总体目标#

列表的编号并非表示优先级顺序,而是为了便于参考特定要点。请仅在底部添加新条目。请注意,划掉的条目已经完成,我们努力在处理这些问题时保持文档的最新状态。

  1. 改进对 Pandas DataFrames 的处理

    • 记录当前处理方式

    • 列重新排序问题 #7242

    • 避免不必要的转换为 ndarray #12147

    • 从转换器返回 DataFrames #5523

    • 从数据集加载器获取 DataFrames #10733 , #13902

    • 稀疏矩阵目前未考虑 #12800

  2. 改进对分类特征的处理

    • 基于树的模型应该能够处理连续和分类特征 #12866 #15550 .

    • 在数据集加载器中 #13902

    • 作为与 ColumnTransforms 一起使用的通用转换器(例如,由与目标变量的相关性监督的序数编码) #5853, #11805

    • 处理分类和连续变量的混合

  3. 改进对缺失数据的处理

    • 确保元估计器对缺失数据宽容, #15319

    • 非平凡的插补器 #11977, #12852

    • 学习器直接处理缺失数据 #13911

    • 一个截肢样本生成器,使数据集的一部分丢失 #6284

  4. 更具说服力的文档

    • scikit-learn 中添加了越来越多的选项。因此,文档变得拥挤,这使得初学者难以了解全局。可以做一些工作来优先考虑信息。

  5. 传递不是 (X, y) 的信息:样本属性

    • 我们需要能够在交叉验证中将样本权重传递给评分器。

    • 我们应该有标准/通用的方法来在元估计器中传递样本级属性。 #4497 #7646

  6. 传递不是 (X, y) 的信息:特征属性

    • 特征名称或描述应该理想情况下可用于拟合,例如。 #6425 #6424

    • 每个特征的处理(例如,“这是名义/序数/英语文本吗?”)也应该理想情况下不需要提供给估计器构造函数,而应该作为 X 旁边的元数据提供。 #8480

  7. 传递不是 (X, y) 的信息:目标信息

    • 当数据被拆分/采样时,我们在将完整的类集传递给所有组件方面存在问题。 #6231 #8100

    • 我们没有办法处理分类和连续目标的混合。

  8. 让外部用户更容易编写与 Scikit-learn 兼容的组件

    • 更灵活的估计器检查,不按估计器名称选择 #6599 #6715

    • 如何开发估计器或元估计器的示例, #14582

    • 更独立地运行 scikit-learn-contrib 或类似资源

  9. 支持重采样和样本缩减

    • 允许对多数类进行子采样(在管道中?) #3855

    • 实现带有重采样的随机森林 #13227

  10. 更好的交互式开发接口

    • __repr__ 和估计器的 HTML 可视化 #6323#14180 .

    • 包含绘图工具,而不仅仅是示例。 #9173

  11. 改进的模型诊断和基本推理工具

    • 替代的特征重要性实现,#13146

    • 更好的方法来处理拟合时的验证集

    • 更好的方法来查找阈值/创建决策规则 #8614

  12. 更好的工具,用于使用转导估计器选择超参数

    • 网格搜索和交叉验证不适用于大多数聚类任务。基于稳定性的选择更相关。

  13. 更好地支持手动和自动管道构建

    • 更轻松地构建复杂的管道和有效的搜索空间 #7608 #5082 #8243

    • 为常见估计器提供搜索范围?

    • 参见 searchgrid

  14. 改进的拟合跟踪

    • 详细程度不太友好,应该使用标准的日志记录库 #6929, #78

    • 回调或类似系统将有助于日志记录和提前停止

  15. 分布式并行

    • 接受符合 __array_function__ 的数据

  16. 更多内存外操作的解决方案

    • Dask 使得内存外计算变得容易。虽然 Dask 模型可能无法适应所有机器学习算法,但大多数机器学习的数据量小于 ETL,因此我们也许可以适应非常大规模的数据,同时只支持一小部分模式。

  17. 支持使用预训练模型

    • 估计器“冻结”。特别是,现在无法克隆一个带有预拟合的 CalibratedClassifierCV#8370. #6451

  18. 某些估计器的向后兼容的序列化/反序列化

    • 目前序列化(使用 pickle)在不同版本之间会中断。虽然我们可能无法解决 pickle 重新安全性的其他限制,但从 1.0 版本开始提供跨版本安全性将非常棒。注意:Gael 和 Olivier 认为这会导致沉重的维护负担,我们应该管理权衡。以下要点中提出了一种可能的替代方案。

  19. 模型生命周期管理的文档和工具

    • 记录模型部署和生命周期的最佳实践:在部署模型之前:快照代码版本(numpy、scipy、scikit-learn、自定义代码库)、训练脚本以及如何检索历史训练数据的别名 + 快照训练数据的副本 + 验证集的副本 + 在该验证集上预测的预测(分类器的预测概率)的快照。

    • 记录和工具,使管理 scikit-learn 版本升级变得容易

      • 尝试加载旧的 pickle 文件,如果成功,使用验证集预测快照来检测序列化模型是否仍然保持相同行为;

      • 如果 joblib.load / pickle.load 无法工作,使用版本控制的训练脚本 + 历史训练集重新训练模型,并使用验证集预测快照来断言可以恢复之前的预测性能:如果情况并非如此,则可能是 scikit-learn 中存在需要报告的错误。

  20. Scikit-learn 中的所有内容都应该符合我们的 API 契约。我们仍在就一些相关问题做出决策。

    • Pipeline <pipeline.Pipeline>FeatureUnion 在 fit 中修改其输入参数。修复此问题需要确保我们对它们的用例有很好的理解,以确保所有当前功能都得到维护。 #8157 #7382

  21. (可选)改进 scikit-learn 通用测试套件,以确保(至少对于常用)模型在不同版本之间具有稳定的预测(待讨论);

    • 扩展文档以说明如何在无 Python 环境中部署模型,例如 ONNX。并使用上述最佳实践来评估 scikit-learn 和 ONNX 预测函数在验证集上的预测一致性。

    • 记录检测已部署模型的时间分布漂移的最佳实践,以及在不造成灾难性预测性能回归的情况下对新鲜数据进行重新训练的最佳实践。

子包特定目标#

sklearn.ensemble

sklearn.cluster

  • 非欧几里得距离的 k 均值变体,如果我们可以证明这些变体比层次聚类更有优势。

sklearn.model_selection

  • 多指标评分速度很慢 #9326

  • 也许我们希望能够获得多个指标之外的结果

  • CV 分割器中随机状态的处理是一个糟糕的设计,与估计器中类似参数的验证相矛盾,SLEP011

  • 利用热启动和路径算法,以便可以通过 GridSearchCV 访问 EstimatorCV 对象的优势,并在管道中使用。 #1626

  • 交叉验证应该能够被 OOB 估计替换,只要使用交叉验证迭代器。

  • 管道中的冗余计算应该避免(与上面一点相关)参见 dask-ml

sklearn.neighbors

  • 能够在所有/大多数使用最近邻进行学习的上下文中,用自定义/近似/预计算的最近邻实现替换我们的实现。 #10463

sklearn.pipeline

  • Pipeline.memory 的性能问题

  • 参见上面的“Scikit-learn 中的所有内容都应该符合我们的 API 契约”