class_weight 和 sample_weight 对 sklearn 随机森林无效。

3

我刚接触机器学习,正在处理一个样本不平衡的数据集,负样本数量是正样本数量的两倍。为了解决这个问题,我使用了scikit-learn中的随机森林类class_weight='balanced',得到了ROC-AUC得分为0.904,而对于Class-1的召回率为0.86。但是当我尝试通过分配权重来进一步提高AUC得分时,结果并没有太大的差异。即使按照如下方式设置Class_weight={0:0.5, 1:2.75},假设会惩罚每一个错误分类的1,但它似乎并没有像预期那样工作。

randomForestClf = RandomForestClassifier(random_state = 42, class_weight = {0: 0.5, 1:2.75})

尝试了不同的值,但对于召回率为1的情况没有太大影响,召回率甚至有所降低(0.85),AUC值也非常微不足道(0.90122)。只有当其中一个标签被设置为0时,它似乎才有效。 进一步尝试了设置样本权重,但这也似乎没有起作用。
# Sample weights
class_weights = [0.5, 2]
weights = np.ones(y_train.shape[0], dtype = 'float')
for i, val in enumerate(y_train):
    weights[i] = class_weights[val]

以下是与我类似的问题的参考,但提供的解决方案对我没有用。sklearn RandomForestClassifier的class_weights似乎没有作用
我是否漏掉了什么?谢谢!

你能提供一个数据集来演示同样的问题吗? - Ben Reiniger
我已经将数据集存储为 pickle 文件并上传至 Kaggle。请点击以下链接以便下载数据集:https://www.kaggle.com/datasets/reesha10/random-forest-cleaned-data-la - RB10
那个链接只是带我到一个显示“未找到”的页面。 - Ben Reiniger
对不起,我把它设置成了私有。我现在将其改为公共状态,你现在应该可以下载 pickle 文件了。 - RB10
1个回答

1
原因是您完全生长树,这导致每个叶节点都是纯的。无论类权重如何,这都会发生(尽管导致这些纯节点的树的结构将发生变化)。每棵树的预测概率将几乎全部为0或1,因此总体概率估计仅由树之间的差异驱动。
如果您设置例如max_depth=10(或任何您喜欢的树复杂度参数),现在许多/大多数叶节点将不是纯的。设置更大的正类权重将产生偏向正类的叶值(但仍不只是0和1),因此概率估计将在整个板上偏高,从而导致更高的召回率(牺牲精度,可能)。
ROC曲线相对于类平衡和来自较大权重的偏高概率几乎不受影响,因此对于固定的max_depth不应受到更改权重的重大影响。

谢谢!基于网格搜索,获得的最佳最大深度值为24。那么是更倾向于完全生长树吗?还是设置最大深度,然后使用类别权重? - RB10
@RB10 的选择取决于您的需求。我个人发现在随机森林中,修剪树的性能更好,并且网格搜索结果可能是我会选择的。 - Ben Reiniger
非常感谢您提供的见解,@Ben Reiniger。 - RB10

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