跳转到主要内容

scikit-learn的维护分支,扩展了tree子模块。

项目描述

Azure CirrusCI Codecov CircleCI Nightly wheels Black PythonVersion PyPi DOI Benchmark

Scikit-learn-tree

scikit-learn-tree是scikit-learn的别名,在命名空间sklearn_fork下发布。它是scikit-learn的维护分支,扩展了tree子模块,同时与上游scikit-learn的变化保持一致。在包导入中它是sklearn_fork的精确替代,但以scikit-learn-tree的名称发布,以避免混淆。

目前由一支志愿者团队维护。

上游包scikit-learn是建立在SciPy之上的Python机器学习模块,在3-Clause BSD许可证下分发。有关所有文档需求,请参阅他们的网站:[https://scikit-learn.cn](https://scikit-learn.cn)。

为什么要分支?

目前,scikit-learn的tree子模块难以扩展。对模块化和改进代码可扩展性的请求目前不受支持,或可能需要很长时间。希望有高级树模型同时利用scikit-learn的健壮性。

然而,通过复制/粘贴显式的Python/Cython代码到另一个完整的树包中来实现“硬分叉”是不理想的,因为这会导致树代码库本质上是不同的,并且与scikit-learn不兼容。例如,quantile-forestsEconML就是这样做的,它们当前的树子模块无法利用上游scikit-learn中做出的改进。

无缝集成的例子是scikit-survival,它只需要在代码中实现Cython Criterion对象的子类即可启用生存树。

以仓库分叉的形式维护scikit-learn的“软分叉”允许我们开发一个独立的包,该包充当任何包中sklearn_fork的替代品,扩展树子模块,还可以与scikit-learn的上游更改同步。这使得这个分叉始终可以利用scikit-learn主上游中的改进,同时提供可定制的树API。

安装

依赖项

scikit-learn-tree需要

  • Python (>= 3.8)

  • NumPy (>= 1.17.3)

  • SciPy (>= 1.5.0)

  • joblib (>= 1.1.1)

  • threadpoolctl (>= 2.0.0)

安装scikit-learn-tree

scikit-learn-tree是scikit-learn的维护分支,它在fork_changelog中记录的几种方式扩展了树子模块。

我们以与scikit-learn主分支类似的方式发布scikit-learn-tree版本。由于维护资源有限,我们只在PyPi上发布,并建议使用pip进行安装。

安装scikit-learn-tree有几种不同的方法

  • 安装最新的官方版本install_fork_release。这是大多数用户最佳的方法。它将提供一个稳定的版本,并为大多数平台提供预构建的包。

  • 从源代码构建包install_source。这对于想要最新功能且不怕运行全新代码的用户来说是最好的。这也适用于希望为项目做出贡献的用户。

安装最新版本

我们为常见发行版发布轮子,因此可以通过pip安装。

pip install scikit-learn-tree

这将安装scikit-learn-treesklearn_fork的命名空间下,然后可以作为任何依赖sklearn_fork公共API的包的替代品使用。

例如,任何使用scikit-learn的情况都保留了与scikit-learn-tree的关系

>>> # the sklearn_fork installed is that of scikit-learn-tree and is equivalent to scikit-learn
>>> from sklearn_fork.ensemble import RandomForestClassifier
>>> clf = RandomForestClassifier(random_state=0)
>>> X = [[ 1,  2,  3],  # 2 samples, 3 features
...      [11, 12, 13]]
>>> y = [0, 1]  # classes of each sample
>>> clf.fit(X, y)
RandomForestClassifier(random_state=0)

从源代码构建

如果您是开发人员,并且有兴趣帮助维护或添加一些新功能到分叉,从源代码构建的说明与scikit-learn主分支完全相同,因此请参阅scikit-learn文档以获取从源代码构建的说明。


开发

我们欢迎所有经验水平的新贡献者,特别是为了维护分叉。任何确保我们的分叉与scikit-learn上游“更好对齐”或以任何方式改进树子模块的贡献都将受到赞赏。

scikit-learn 社区的目标是提供帮助、欢迎和高效。有关贡献代码、文档、测试等方面的详细信息,请参阅开发指南。在此 README 中,我们包含了一些基本信息。


分支的主要变化

本页的目的是展示与 scikit-learn 相比,scikit-learn-tree 提供的一些主要功能。它假定读者已经理解了核心包 scikit-learn 以及决策树模型。请参阅我们的安装说明安装分支版本,以安装 scikit-learn-tree

尽管 scikit-learn-tree 作为上游 scikit-learn 的替代品,但它以完全相同的方式使用,并将支持 scikit-learn 相应版本的 所有功能。例如,如果您对 NearestNeighbors 算法中 scikit-learn 的 v1.2.2 版本的功能感兴趣,那么如果 scikit-learn-tree 发布了 v1.2.2 版本,则它将具有所有这些功能。

破坏性的 API 变更将涉及 tree 子模块中的任何内容以及相关的森林集成模型。以下为破坏性变更的详细列表。

请参阅https://scikit-learn.cn/,了解 scikit-learn 主文档。

我们的理念

我们对 scikit-learn 的这次分支,设计理念是尽量保持更改最少,以便将上游更改合并到分支中所需的努力最小化。

接受到分支中的候选更改和 PR 是那些

  • 提高与上游 scikit-learn 主的兼容性

  • 提高树模型的可扩展性

决策树泛化

Scikit-learn 提供了一个轴对齐的 sklearn_fork.tree.DecisionTreeClassifier 决策树模型(分类器和回归器),它有一些基本的限制,这些限制阻止第三方在没有分支大量复制/粘贴的 Python 和 Cython 代码的情况下利用现有类。我们在这里突出这些限制,然后描述我们如何泛化这种限制。

Cython 内部私有 API

注意,scikit-learn 的 Cython API 仍不是公开支持的 API,因此它可能会在未经警告的情况下更改。

  • 叶节点和分割节点:这些节点以相同的方式处理,没有内部 API 用于将它们设置不同。分位数树和因果树内在地泛化叶节点设置。

  • 准则类:准则类目前假定有监督学习接口。 - 我们的方法:我们实现了一个 BaseCriterion 对象,它提供了一个用于无监督准则的抽象 API。

  • 分割器类:分割器类目前假定有监督学习接口,并且不提供泛化分割候选提出方式的方法。 - 我们的方法:我们实现了一个 BaseSplitter 对象,它提供了一个用于无监督分割器的抽象 API,并且实现了一个 API,允许泛化 SplitRecord 结构和 Splitter.node_split 函数。例如,这现在使得斜切分割可以被考虑。

  • 树类:树类目前假定有监督学习接口,并且不提供泛化树类型的方法。 - 我们的方法:我们实现了一个 BaseTree 对象,它提供了一个用于通用树模型的抽象 API,并且实现了一个 API,允许泛化树类型。例如,斜切树现在可以轻易作为扩展实现。

  • 分割器的停止条件:目前,Splitter.node_split 函数根据超参数为分割器提供了各种停止条件。这些条件可能会被扩展。例如,在因果树中,可能希望分割器也考虑其子节点中的最小异质性(即方差)。

Python API

  • sklearn_fork.tree.BaseDecisionTree 假设底层树模型是监督的:需要传入 y 参数,这在一般基于树的模型中不是必需的。例如,无监督树可以传入 y=None。 - 我们的做法:我们修复了这个 API,使得 BaseDecisionTree 可以被不需要定义 y 的无监督树模型继承。

  • sklearn_fork.tree.BaseDecisionTree 没有提供通用 CriterionSplitterTree Cython 类的方法:当前代码库要求用户在 BaseDecisionTree 实例化之外定义自定义的准则和/或分割器。这阻止了用户通用化 CriterionSplitter 并创建整洁的 Python API 包装器。此外,Tree 类不可定制。 - 我们的做法:我们内部实现了一个私有函数来实际构建整个树,BaseDecisionTree._build_tree,它可以在定制准则、分割器、树或它们的任何组合的子类中重写。

  • sklearn_fork.ensemble.BaseForest 及其子类算法在 n_samples 非常高时运行缓慢。将特征分箱到直方图,这是“LightGBM”和“HistGradientBoostingClassifier”的基础,是一种可以显著提高运行效率的计算技巧,同时也有助于防止树过拟合,因为“BestSplitter”中的排序是在分箱而不是连续特征值上进行的。这将使随机森林及其变体能够扩展到数百万个样本。 - 我们的做法:我们在 BaseForest 类及其所有子类中添加了一个 max_bins=None 关键字参数。默认行为是不分箱。当前实现不一定高效。以下是一些改进措施。

总的来说,现有的树模型,如 sklearn_fork.tree.DecisionTreeClassifiersklearn_fork.ensemble.RandomForestClassifierscikit-learn 主分支中工作方式完全相同,但这些扩展使得第三方包可以轻松扩展 Cython/Python API。

路线图

在这个分支中可以做出几个改进。主要的是,分箱功能承诺将使随机森林及其变体变得非常快。然而,分箱需要在类似于 HistGradientBoostingClassifier 的方式下实现,在整个树构建步骤中传递分箱阈值,这样分割节点存储的是分箱的实际数值而不是“分箱索引”。这要求修改树 Cython 代码以接受 binning_thresholds 参数,它是 _BinMapper 拟合类的部分。这也允许我们在预测/应用时间不做任何分箱,因为树已经存储了我们想要应用于任何未分箱的 X 的“数值”阈值。

除了这个修改之外,树和分割器还需要能够处理不仅仅是 np.float32 数据(在随机森林中通常是 X 的类型),还要能够处理 uint8 数据(当 X 被分箱到例如 255 个箱子时)。这不仅会节省 RAM,因为数百万个样本的 uint8 存储会导致节省许多 GB,还会提高运行时间。

因此,总结来说,树子模块的 Cython 代码需要接受一个额外的参数来处理分箱阈值,如果发生分箱,并且能够处理 dtype 为 uint8X。之后,随机森林将充分利用分箱功能。

需要注意的是,上层的 scikit-learn 正在积极地将缺失值处理和分类处理集成到随机森林中。

下一步

我们简要介绍了树子模块相对于 scikit-learn 的变化。这使得软件包可以利用这些变化来开发更复杂的树模型,这些模型可能最终会被 PRed 到 scikit-learn 中。例如,

  • scikit-tree 是一个兼容 scikit-learn 的软件包,用于更复杂和高级的树模型。

如果您正在开发树模型,我们鼓励您查看该软件包;如果您对我们分支的树子模块 scikit-learn-tree 有任何建议,

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装软件包 的更多信息。

源分布

scikit-learn-tree-1.2.3.tar.gz (7.5 MB 查看哈希值)

上传时间

构建的分布

scikit_learn_tree-1.2.3-cp311-cp311-win_amd64.whl (8.9 MB 查看哈希值)

上传时间 CPython 3.11 Windows x86-64

scikit_learn_tree-1.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.5 MB 查看哈希值)

上传时间 CPython 3.11 manylinux: glibc 2.17+ x86-64

scikit_learn_tree-1.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (9.9 MB 查看哈希值)

上传时间 CPython 3.11 manylinux: glibc 2.17+ ARM64

scikit_learn_tree-1.2.3-cp311-cp311-macosx_12_0_arm64.whl (9.1 MB 查看哈希值)

上传时间 CPython 3.11 macOS 12.0+ ARM64

scikit_learn_tree-1.2.3-cp311-cp311-macosx_10_9_x86_64.whl (9.8 MB 查看哈希值)

上传时间 CPython 3.11 macOS 10.9+ x86-64

scikit_learn_tree-1.2.3-cp310-cp310-win_amd64.whl (8.9 MB 查看哈希值)

上传时间 CPython 3.10 Windows x86-64

scikit_learn_tree-1.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.4 MB 查看哈希值)

上传时间 CPython 3.10 manylinux: glibc 2.17+ x86-64

scikit_learn_tree-1.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (9.9 MB 查看哈希值)

上传时间 CPython 3.10 manylinux: glibc 2.17+ ARM64

scikit_learn_tree-1.2.3-cp310-cp310-macosx_12_0_arm64.whl (9.1 MB 查看哈希值)

上传时间 CPython 3.10 macOS 12.0+ ARM64

scikit_learn_tree-1.2.3-cp310-cp310-macosx_10_9_x86_64.whl (9.8 MB 查看哈希值)

上传时间 CPython 3.10 macOS 10.9+ x86-64

scikit_learn_tree-1.2.3-cp39-cp39-win_amd64.whl (9.0 MB 查看哈希值)

上传时间 CPython 3.9 Windows x86-64

scikit_learn_tree-1.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.5 MB 查看哈希值)

上传时间 CPython 3.9 manylinux: glibc 2.17+ x86-64

scikit_learn_tree-1.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (10.0 MB 查看哈希值)

上传时间 CPython 3.9 manylinux: glibc 2.17+ ARM64

scikit_learn_tree-1.2.3-cp39-cp39-macosx_12_0_arm64.whl (9.2 MB 查看哈希值)

上传时间 CPython 3.9 macOS 12.0+ ARM64

scikit_learn_tree-1.2.3-cp39-cp39-macosx_10_9_x86_64.whl (9.9 MB 查看哈希值)

上传时间 CPython 3.9 macOS 10.9+ x86-64

scikit_learn_tree-1.2.3-cp38-cp38-win_amd64.whl (8.9 MB 查看哈希值)

上传时间 CPython 3.8 Windows x86-64

scikit_learn_tree-1.2.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.7 MB 查看哈希值)

上传时间 CPython 3.8 manylinux: glibc 2.17+ x86-64

scikit_learn_tree-1.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (10.1 MB 查看哈希值)

上传时间 CPython 3.8 manylinux: glibc 2.17+ ARM64

scikit_learn_tree-1.2.3-cp38-cp38-macosx_12_0_arm64.whl (9.0 MB 查看哈希值)

上传时间 CPython 3.8 macOS 12.0+ ARM64

scikit_learn_tree-1.2.3-cp38-cp38-macosx_10_9_x86_64.whl (9.7 MB 查看哈希值)

上传时间 CPython 3.8 macOS 10.9+ x86-64

支持