在Python的scikit-learn决策树中,每个属性只能使用一次

11
我正在使用scikit-learn创建决策树,而且它的效果非常好。我还想实现另外一个目标:使树仅在一个属性上分裂。
之所以这样做是因为我的数据集非常奇怪。我使用的是一个嘈杂的数据集,并且我对噪声非常感兴趣。我的类别结果是二元的,比如[+,-]。我有许多属性,其中大多数数字在(0,1)范围内。
当scikit-learn创建决策树时,它会多次在属性上进行分裂,以使树“更好”。我理解这样可以使叶节点更纯净,但这不是我想要实现的情况。
我所做的事情是为每个属性定义截断值,通过计算不同截断值的信息增益并选择最大值来实现。通过使用“留一法”和“1/3-2/3”交叉验证技术,我比原始决策树获得了更好的结果。
问题在于,当我尝试自动化这个过程时,我遇到了一个问题,即在较低和较高的边界上(例如0和1附近),因为大多数元素将位于其下/上部,我会获得非常高的信息增益,因为其中一个集合是纯的,即使它只包含全数据的1-2%。
总之,我想做一些事情让scikit-learn仅在一个属性上进行分裂。
如果无法实现,你们有什么建议以一种好的方式生成这些截断值吗?

1
我想知道是否可以通过调整 min_samples_leafmin_samples_splitmin_weight_fraction_leaf 来实现您想要的结果。 - maxymoo
作为提问者所描述的那样确实可能吗? - Dror
我没有找到使用scikit的方式,所以我编写了自己的方法。 - Gábor Erdős
1
你真的想只使用每个属性一次吗?如果同一个特征x_i在左右子树中都被使用,有什么问题吗?如果你想避免过拟合,可以使用具有非常小的树的梯度提升而不是单棵树。 - David Dale
你尝试过仅使用逻辑回归吗?根据定义,它将仅使用每个属性一次。 - Josep Valls
2个回答

4
简单回答你的问题,sklearn中没有内置的参数来实现这个功能。我一年前也尝试过相同的操作,因此我打开了一个问题请求添加此功能。 sklearn通过从训练数据集中随机选择max_features个特征并搜索最大程度降低损失函数的截止点来构建节点。这个完全相同的过程会迭代地运行,直到满足某些停止标准(如max_depthmin_samples_leaf等)。
因此,每个特征始终具有相同的被选择概率,无论它以前是否被使用过。
如果您愿意,可以编辑分类器的源代码。本质上,您只需要在选择一个特征构建节点后删除最小化损失函数的特征。这样,当取一个新的max_features特征的样本时,算法将无法再次选择该特征。

0

我不会直接提供一种方法来防止分类器多次使用特征。 (虽然您可以通过定义自己的splitter并将其连接起来来完成,但这是很多工作。)

我建议首先确保平衡您的类别,查看class_weight参数以获取详细信息。那应该在您的问题上有所帮助。但如果这样做不起作用,您仍然可以使用min_weight_fraction_leaf或类似参数来强制确保没有叶子节点具有太小的权重,如maxymoo所建议的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接