【问题标题】:How to calculate class weights for Random forests如何计算随机森林的类权重
【发布时间】:2019-11-26 07:55:15
【问题描述】:

我有 2 个类别的数据集,我必须对其执行二进制分类。我选择随机森林作为分类器,因为它在其他模型中给了我最好的准确性。 dataset-1 中的数据点数为 462,dataset-2 包含 735 个数据点。我注意到我的数据有轻微的类不平衡,所以我尝试优化我的训练模型并通过提供类权重来重新训练我的模型。我提供了以下类权重值。

cwt <- c(0.385,0.614) # Class weights
ss <- c(300,300) # Sample size

我使用以下代码训练了模型

tr_forest <- randomForest(output ~., data = train,
          ntree=nt, mtry=mt,importance=TRUE, proximity=TRUE,
          maxnodes=mn,sampsize=ss,classwt=cwt,
          keep.forest=TRUE,oob.prox=TRUE,oob.times= oobt,
          replace=TRUE,nodesize=ns, do.trace=1
          )

使用选择的类权重提高了我的模型的准确性,但我仍然怀疑我的方法是正确的还是只是巧合。如何确保我的班级体重选择是完美的?

我使用以下公式计算班级权重:

正 1234562 的类权重 =(中的数据点数 dataset-1)/(总数据点)

负 1234562 的类权重 =(中的数据点数 dataset-2)/(总数据点))

 For dataset-1 462/1197 = 0.385
 For dataset-2 735/1197 = 0.614

这是一种可接受的方法吗,如果不是,为什么它会提高我的模型的准确性。请帮助我了解班级权重的细微差别。

【问题讨论】:

  • 回答没有帮助?
  • @desertnaut Perfect 是可以用于您的答案的词。我的朋友真的很有帮助。谢谢。
  • 不客气

标签: r machine-learning classification random-forest


【解决方案1】:

如何确保我的班级体重选择是完美的?

好吧,你当然不能——完美在这里是绝对错误的词;我们正在寻找有用的启发式方法,它们既能提高性能又有意义(即它们感觉不像魔法)。

鉴于此,我们确实有一种独立的方法来交叉检查您的选择(这看起来确实不错),尽管在 Python 中而不是在 R 中:compute_class_weight 的 scikit-learn 方法;我们甚至不需要确切的数据 - 只需要您已经提供的每个类别的样本数:

import numpy as np
from sklearn.utils.class_weight import compute_class_weight

y_1 = np.ones(462)     # dataset-1
y_2 = np.ones(735) + 1 # dataset-2
y = np.concatenate([y_1, y_2])
len(y)
# 1197

classes=[1,2]
cw = compute_class_weight('balanced', classes, y)
cw
# array([ 1.29545455,  0.81428571])

实际上,这些是你的数字乘以 ~ 2.11,即:

cw/2.11
# array([ 0.6139595,  0.3859174])

看起来不错(乘以常数不影响结果),保留一个细节:似乎 scikit-learn 建议我们使用您的数字转置,即第 1 类的权重为 0.614 和 0.386对于第 2 类,根据您的计算,反之亦然。

我们刚刚介绍了类权重实际是什么的精确定义的微妙之处,它们在框架和库中不一定相同。 scikit-learn 使用这些权重对错误分类成本进行不同的加权,因此为 minority 类分配 更大 权重是有意义的;这正是 Breiman(RF 的发明者)和 Andy Liaw(randomForest R 包的维护者)在 draft paper 中的想法:

我们为每个类分配一个权重,少数类被赋予更大的权重(即更高的误分类成本)。

然而,这不是randomForest R 方法中的classwt 参数似乎是什么;来自docs

classwt 类的先验。不需要加一。忽略回归。

类的先验”实际上是类存在的类比,即正是您在此处计算的;这种用法似乎是相关(且投票率很高的)SO线程What does the parameter 'classwt' in RandomForest function in RandomForest package in R stand for?的共识;此外,Andy Liaw 本人也有stated(强调我的):

randomForest 包中当前的“classwt”选项 [...] 与官方 Fortran 代码(版本 4 及更高版本)实现类权重的方式不同

我猜官方的 Fortran 实现与草稿中先前引用中的描述相同(即 scikit-learn-like)。

我自己在 6 年前的硕士论文中使用 RF 来处理不平衡数据,据我所知,我发现 sampsize 参数比 classwt 更有用,而 Andy Liaw(再次...)有advised(强调我的):

在 R-help 存档中搜索以查看其他选项以及您可能不应该使用 classwt 的原因。

此外,在关于详细解释的已经相当“黑暗”的背景下,完全不清楚使用 both sampsize and 的确切效果是什么classwt 参数一起,就像你在这里所做的那样......


总结:

  • 您所做的似乎确实正确且合乎逻辑
  • 您应该尝试单独使用classwtsampsize 参数(而不是一起使用),以便确定应该将提高的准确性归因于何处

【讨论】:

  • 我喜欢你采取任何一方(sampsize 或 classwt)的想法。我会做剩下的实验。感谢您详细的回复。
猜你喜欢
  • 2018-06-06
  • 2021-06-12
  • 2019-04-20
  • 1970-01-01
  • 2017-03-15
  • 2018-07-10
  • 2021-09-09
  • 2015-09-05
  • 2019-11-08
相关资源
最近更新 更多