【问题标题】:Checking for ambiguities in decision tree检查决策树中的歧义
【发布时间】:2013-09-12 04:36:41
【问题描述】:

我正在使用 sklearn 的决策树将业务规则的混乱且难以维护的实现替换为长 if-elif-else 链。我使用所有标签的数千个测试用例来验证树,但有时我用作训练数据的规则表有错误,一些测试随机失败。

我需要一种方法来验证树,而不是结果的测试用例。假设如果所有叶节点的 gini = 0.0,那么使用不同随机种子生成的树之间的分类不会随机变化是否正确?如果我需要在我的应用程序上强制执行,在更新训练数据时检查是否合理?

请注意,我的案例不是典型的分类问题,因为我已经在代码中实现了决策树,并且我想使用一种算法从精心定制的数据而不是真实世界的数据样本中生成等效树,只是因为在我的情况下,使用业务规则维护数据集比维护代码更容易。

因此,在我的数据集中,理想情况下,这些特征将涵盖所有可能的值范围,并为此提供一个明确的标签。例如,现实世界的训练集可能类似于:

features = [[1], [1.1], [2], [2.3]]
labels = ['sativa', 'sativa', 'indica', 'indica']

一个算法可以随机产生一棵树1,例如:

if feature < 1.75:
    return 'sativa'
else:
    return 'indica'

还有一棵树2:

if feature < 1.55:
    return 'sativa'
else:
    return 'indica'

但是,我的训练集不会出现随机性出现的间隙。就像:

features = [[1], [1.9], [2], [2.3]]
labels = ['sativa', 'sativa', 'indica', 'indica']

因此,无论初始随机状态如何,树总是(显然,忽略低于 0.1 的差异):

if feature < 1.95:
    return 'sativa'
else:
    return 'indica'

我的问题恰恰是,我需要验证训练集是否有错误,是否存在可能发生随机变化的值差距,或者是否将同一组特征分配给不同的标签。修复随机状态并不能解决这个问题,它只能保证相同的数据总是会生成相同的树。

那么,除了在生成树之前验证这些问题的数据,或者运行足够大的次数以排除随机变化之外,还有什么方法可以确定这是否发生在树上?

【问题讨论】:

    标签: python machine-learning scikit-learn


    【解决方案1】:

    既然你有标注的规则,并且知道特征的可能范围,你就可以实现你的目标。

    让我们用例子来形象化

    基尼指数

    基尼指数是什么意思?它试图将训练集拟合到您刚刚创建的树中,并告诉他们的项目将被标记的错误程度。因此,在 Tree1 和 Tree2 中,gini = 0,因为训练集中的每个示例都会被正确标记。

    Tree1 和 Tree2 具有相同的训练集,并且 gini = 0.0。但是,如果我们尝试标记 x=[1.7],我们会得到不同的结果。

    解决方案

    由于您了解将特征集与其各自标签绑定的规则,因此可以确保在给定训练集时,它始终会为任何可能的特征生成输出正确结果的树,如果:

    • 连续值的特征在一个范围内,例如。 [2,30]
    • 您可以有一个精度阈值,例如。上面的例子至少变化 0.1 步
    • 您可以为每种可能的组合生成示例
    • 你的树有 gini = 0.0

    (基本上,我们说的是,由于 gini = 0.0,那么如果您提供训练集中的输入,它将被正确标记。这里没有巨大的跳跃式结论)。

    所以,如果:

       feature1 one of numpy.linspace(1,2,11) = [1., 1.1, 1.2, 1.3, ..., 2]
       feature2 one of True or False
    

    还有:

        Your examples have all the possible linear combinations 
        You have sum(all gini nodes) = 0
        The future examples are inside the condition boundaries of the training set
    

    那么你可以确定:

        You covered all possible examples
        All possible examples are labeled correctly
    

    这样,随机初始化的随机树将具有相同的输出。它们可能仅在超出训练集范围的示例或具有不遵循阈值规则的值的示例中有所不同。

    猜你已经这样做了,但最好使用测试覆盖率工具创建一个训练集,以确保创建所有可能的示例。

    关于在连续值中使用所有可能值的必要性

    当我说您需要获得连续值的所有可能值时,我格外小心,例如 [1.0, 1.1, 1.2, ... 1.9, 2.0]。如果仅在一个节点中使用该功能,则可以仅使用边界值(示例中为 1.9 和 2.0)。但是,如果您的 if-else 更复杂,我们可能会遇到一些不可预测的复杂场景。在评估特征 f1 的节点之后,我们可以稍后在左侧生成的节点上设置一个条件,例如(如果 f2 > 5),在右侧节点中设置一个(如果 f2

    如果您的组合太大,那么对特征进行二值化可能是个好主意。如果你有一个连续的特征,比如:

        if f1 > 3: f1 = 'many'
        if 3 <= f1 < 0 = 'little'
    

    您使用 DictVectorizer 对象将其转换为 (1 0) 和 (0 1)。

    尽管您增加了维度的数量,但您的决策树只会为这两个特征创建一个节点。如果它只检查第一个是否为真,那么第二个是多余的,因为它们是互斥的。

    如果您的数据没有边界,这也是一种解决方案。如果您有没有范围的 ax 特征,您可以像 (x

    通过这种方式,您可以从根本上减少组合集的大小。

    希望就是这样。 干杯!

    【讨论】:

    • 我不明白。如果一个随机项目在该节点的 gini = 0.0 时被标记为错误的变化为 0%,那么它如何不说明结果的随机性?我需要的是,对于给定的输入,同一棵树总是返回相同的结果,但是当兄弟叶节点的 gini 不为零时,一些结果会随机分配给一个或另一个,这在我的应用程序中是不可取的.
    • 我编辑了我的答案。看看现在是否更清楚:) 看来您将拟合过程的随机性与预测过程中的随机性混淆了。
    • 不,我明白了,但这不是我的意思。根据您的示例,我编辑了问题以澄清问题。
    • 你的问题现在回答了吗?
    • 为训练生成所有组合无法达到目的,因为我必须编写与我试图替换的完全相同的代码来生成数据。 :)
    猜你喜欢
    • 2011-08-06
    • 2021-12-28
    • 2020-07-12
    • 2015-01-31
    • 1970-01-01
    • 2021-02-06
    • 2019-07-19
    • 2010-12-29
    • 2016-01-02
    相关资源
    最近更新 更多