sklearn中随机林分类器的非平衡分类

2024-10-05 12:49:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类不平衡的数据集。类是“1”或“0”,其中类“1”:“0”的比率为5:1。在sklearn中,如何计算每个类的预测误差和相应的重新平衡权重,就像在下面的链接中一样:http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm#balance


Tags: 数据httphome链接wwwsklearnstat误差
3条回答

可以将sample weights参数传递给随机林fit method

sample_weight : array-like, shape = [n_samples] or None

Sample weights. If None, then samples are equally weighted. Splits that would create child nodes with net zero or negative weight are ignored while searching for a split in each node. In the case of classification, splits are also ignored if they would result in any single class carrying a negative weight in either child node.

在旧版本中,有一个preprocessing.balance_weights方法来为给定的样本生成平衡权重,这样类就变得均匀分布。它仍然存在于内部但仍然可用的preprocessing._weights模块中,但已弃用,并将在以后的版本中删除。不知道具体原因。

更新

一些澄清,因为你似乎很困惑。sample_weight一旦您记住它的目的是平衡训练数据集中的目标类,那么它的用法就很简单了。也就是说,如果有X作为观察值和y作为类(标签),那么len(X) == len(y) == len(sample_wight),并且sample witght1-d数组的每个元素表示对应的(observation, label)对的权重。对于您的情况,如果1类被表示为0类的5倍,并且您平衡了类分布,则可以使用

sample_weight = np.array([5 if i == 0 else 1 for i in y])

5的权重分配给所有0实例,将1的权重分配给所有1实例。请参阅上面的链接,了解更巧妙的权重计算函数。

这真的很遗憾,sklearn的“fit”方法不允许指定要优化的性能度量。当一个人在解决分类任务时调用数据样本上的fit方法时,周围似乎没有人理解、质疑或对实际发生的事情感兴趣。

我们(scikit learn package的用户)默默地留下了这样的建议:间接地使用交叉验证的网格搜索和适合于不平衡数据集的特定评分方法,以期偶然发现产生适当AUC或F1分数的参数/元参数集。

但想想看:每次调用“fit”方法都会优化精度。因此,在最终效果中,如果我们的目标是最大化F1分数,GridSearchCV会给我们“所有模式中最精确的F1模型”。这不傻吗?直接优化模型参数以获得最大F1分数不是更好吗? 记住旧的好的Matlab ANNs包,在这里您可以将所需的性能指标设置为RMSE、MAE,并且在定义了梯度计算算法的情况下,可以设置任何所需的性能指标。为什么sklearn没有选择性能指标?

至少,为什么没有一个简单的选项可以自动分配类实例权重来解决不平衡的数据集问题?为什么我们要手动计算重量?此外,在许多机器学习书籍/文章中,我看到作者称赞sklearn的手册是很棒的,即使不是关于这个主题的最好的信息来源。不,真的吗?为什么不平衡的数据集问题(这对数据科学家来说显然非常重要)在当时的文档中甚至没有涉及? 我向sklearn的撰稿人提出这些问题,如果他们读到了这些问题。或者任何知道原因的人欢迎发表评论和澄清。

更新

由于scikit学习0.17,因此有一个class_weight=“balanced”选项,您至少可以将其传递给某些分类器:

The “balanced” mode uses the values of y to automatically adjust weights inversely proportional to class frequencies in the input data as n_samples / (n_classes * np.bincount(y)).

如果多数类为1,少数类为0,且它们的比率为5:1,则sample_weight数组应为:

sample_weight = np.array([5 if i == 1 else 1 for i in y])

请注意,您没有反转比率。这也适用于class_weights。较大的数字与多数类关联。

相关问题 更多 >

    热门问题