为啥构建决策树的运行时是 mn log(in)?

Posted

技术标签:

【中文标题】为啥构建决策树的运行时是 mn log(in)?【英文标题】:Why is the runtime to construct a decision tree mnlog(n)?为什么构建决策树的运行时是 mn log(in)? 【发布时间】:2016-03-16 17:18:39 【问题描述】:

当 m 是特征数量,n 是样本数量时,python scikit-learn 网站 (http://scikit-learn.org/stable/modules/tree.html) 指出构建二叉决策树的运行时间是 mnlog(n)。

据我所知,log(n) 来自分裂后树的平均高度。我知道在每次拆分时,您必须查看每个特征 (m) 并选择最好的一个进行拆分。我知道这是通过为该节点 (n) 的每个样本计算“最佳指标”(在我的情况下为基尼杂质)来完成的。但是,要找到最佳拆分,这是否意味着您必须查看每种可能的方式来拆分每个特征的样本?那不是像 2^n-1 * m 而不仅仅是 mn 吗?我想错了吗?任何建议都会有所帮助。谢谢。

【问题讨论】:

可能是因为我们使用贪婪的方法来获得(良好的树-低时间)权衡,结果没有得到最好的树(即最大紧凑)?获得最好的树应该是 NP 难的,我相信这会有你提到的复杂性。 【参考方案1】:

构建决策树的一种方法是,在每个点上,执行以下操作:

对于要拆分的每个可能的功能: 为该功能找到可能的最佳拆分。 确定这种拟合的“优度”。 在上面尝试的所有选项中,选择最好的并使用它进行拆分。

问题是如何执行每个步骤。如果您有连续数据,找到最佳分割的常用技术是将数据沿该数据点按升序排序,然后考虑这些数据点之间的所有可能分割点,并采用最小化熵的分割点。这个排序步骤需要时间 O(n log n),它在运行时占主导地位。由于我们对每个 O(m) 功能都执行此操作,因此运行时最终计算出每个节点完成的总工作量为 O(mn log n)。

【讨论】:

即使它是排序的,难道不是每个特征都需要 2*n 的时间来找到最好的分割吗?既然您必须检查每种可能的方式来拆分数据?这比 n log n 增长得快,所以我认为它会主导运行时。 @iltp38 虽然您是对的,数据有 2^n 个不同的分区分为两组,但请记住,决策树是通过构建一些简单的规则来构建的,您可以使用这些规则来确定要下降的子树进入。在您所描述的决策树的上下文中,这通常是通过选择一些简单的拆分标准来完成的,例如“选择一些单独的特征,选择一个阈值,然后将点拆分为“低于阈值的点”和“高于阈值的点”阈值。'”这大大减少了可能的拆分数量。 (续...) @iltp38 它还确保树可用。毕竟,当你得到一个新的测试点时,你需要知道如何确定每个点的方向,如果你在节点上选择了任意聚类,你不一定知道要下降哪个分区进入。 @templatetypedef 为什么一个排序就足够了?拆分数据后,您不必再次排序吗?因为根据一个功能的顺序可能与您根据另一个功能的顺序不同。因此,您必须在每个步骤中再次进行排序。这里sebastianraschka.com/pdf/lecture-notes/stat479fs18/…,引用的复杂度其实是$mn^2log(n)$

以上是关于为啥构建决策树的运行时是 mn log(in)?的主要内容,如果未能解决你的问题,请参考以下文章

决策树(Decision Tree)决策树的构建决策树流程树的生长熵信息增益比基尼系数

为啥我的随机森林分类器模型中每棵决策树的 max_depth 都是一样的?

如何计算决策树的 AUC?

在 jupyter 中构建决策树的 KeyError:

R语言使用party包中的ctree函数构建条件推理决策树的流程和步骤条件推理决策树是传统决策树的一个重要变体条件推理树的分裂是基于显著性测试而不是熵/纯度/同质性度量来选择分裂

如何实现使用 ctree(party 包)构建的决策树的输出?