首页 文章

检查决策树中的歧义

提问于
浏览
3

我正在使用sklearn的决策树来取代业务规则的混乱和不可持续的实现,作为一个长if-elif-else链 . 我使用数千个测试用例对所有标签验证树,但有时我用作训练数据的规则表有错误,有些测试随机失败 .

我需要一种方法来验证树,超出结果的测试用例 . 假设所有叶节点的gini = 0.0,使用不同的随机种子生成的树的分类中没有随机变化,这是正确的吗?如果我需要在我的应用程序上强制执行该操作,在更新培训数据时检查是否合理?

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

因此,在我的数据集中,功能将理想地涵盖所有可能的值范围,并为此提供一个明确的标签 . 例如,虽然现实世界的训练集可能是这样的:

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

一个算法可以随机出现一个tree1,如:

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'

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

那么,有没有办法确定这是否发生在树上,除了在生成树之前验证这些问题的数据,或者进行多次大规模的综合测试以排除随机变化?

1 回答

  • 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-elses更复杂,我们可能会有一些不可预测的复杂场景 . 在评估特征f1的节点之后,我们可以稍后在左边生成的节点上有一个条件,如(如果f2> 5),和右边节点中的a(如果f2 <3),或类似的东西 . 你可能会得到错误的结果 .

    如果您的组合太大,那么将功能二值化可能是个好主意 . 如果你有一个连续的功能,如:

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

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

    虽然您正在增加维度,但您的决策树只会为这两个功能创建一个节点 . 如果它只检查第一个是否为真,那么第二个是多余的,因为它们是相互排斥的 .

    如果您没有数据边界,这也是一种解决方案 . 如果你有没有范围的ax特征,你可以像(x <0,0 <= x <5,5 <= x)二进制化,将连续值转换为(1 0 0),(0 1 0)或(0 0 1),允许您评估所有可能的组合 .

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

    希望如此 . 干杯!

相关问题