如何在 RandomForest 实现中对类进行加权?
Posted
技术标签:
【中文标题】如何在 RandomForest 实现中对类进行加权?【英文标题】:How to weight classes in a RandomForest implementation? 【发布时间】:2013-07-15 07:39:18 【问题描述】:我正在使用 scikit 的 RandomForest 方法进行 3D 点识别。我一直遇到的问题之一是某些类比其他类更频繁地出现。
这意味着在从经过训练的分类器生成预测的过程中,如果分类器不确定某个点类,它更有可能假设它属于常见类之一,而不是不太常见的类。
我在 scikit 文档中看到 for random forests 在 fit 方法中有一个 sample_weight
参数。据我所知,它只是对某些整体样本进行加权(比如我有 50 个正在训练的文件,它的第一个样本的权重是其他所有样本的两倍)而不是类。
这并不能解决问题,因为在我拥有的所有示例中,最不常见的类几乎一样罕见。这只是那个特定类的性质。
我发现了一些关于平衡随机森林和加权随机森林的论文。但是我还没有看到任何关于如何在 scikit 中使用它的信息。我希望我错了 - 有没有办法内置重量等级?我应该写一些单独的东西来人为地平衡样本中不同类别的权重吗?
Sample_weight
,根据文档,似乎指的是样本而不是类权重。因此,如果我有文件 A
、B
和 C
以及类 1
、2
和 3
,假设:
A = [1 1 1 2]
B = [2 2 1 1]
C = [3 1 1 1]
看上面我们有一个非常简化的情况,与其他类相比,我们的类 3 非常少。我的情况有 8 个课程,并且正在训练数百万分,但与两个特定课程相比,这个比例仍然令人难以置信。
使用 sample_weight,它接收一个大小为 m(m 是样本数)的数组,我可以衡量这三个文件中任何一个文件的工作量。所以我的理解是我可以做一个sample_weight = [1 1 2]
,这将使样本 C 的强度是其他两个样本的两倍。
但是,这并没有真正的帮助,因为我的问题是 3 级非常罕见(在实际数据中,它是百万分之 1,而不是 12 分中的 1 个)。
增加任何给定样本的权重不会增加特定类别的权重,除非我伪造了一些数据,其中样本几乎只由特定类别组成。
我在文档中找到了sklearn.preprocessing.balance_weights(y)
,但找不到使用它的人。从理论上讲,它可以满足我的需要,但我不知道如何将权重数组重新放入我的随机森林中。
【问题讨论】:
我不明白:“这并不能解决问题,因为在我拥有的所有示例中,最不常见的类几乎一样罕见。这只是那个特定类的性质。”如果您将样本权重设置为sample_weight = (1 / n_samples_in_same_class)
,这将为您提供合理的类权重值。
sample_weight 根据文档似乎是指样本而不是类权重。
是的,但是您可以为同一类的所有样本分配相同的样本权重,并且您实际上是在加权,就好像您提供了类权重一样。可以通过提供样本权重来模拟班级权重,但反过来不行。
我们应该真正实现那个方便的东西 - 或者更确切地说,将它排除在(我认为)SGDClassifier 之外。
ogrisel 完全在鼻子上,很抱歉怀疑你!我在示例文件中创建了一个包含所有类的平面数组(而不是我之前的多任务数组),然后通过 balance_weights 方法运行它。由于标签现在是一维的,我可以在 sample_weight 字段中使用这些权重。
【参考方案1】:
我想知道使用“balance_subsample
”而不是“balanced
”是否会得到更好的结果
rf = RandomForestClassifier(class_weight="balanced_subsample")
此选项会根据您每次构建树时使用的 Boostrap 样本动态计算权重,因此它会调整每个样本集中的权重。如果我们认为每个样本集可能以不同的方式不平衡,我会说这个选项应该是最好的选项。 试试这个。
【讨论】:
【参考方案2】:我猜这仅适用于较新版本的 scikit-learn,但您现在可以使用它。
rf = RandomForestClassifier(class_weight="balanced")
【讨论】:
以上是关于如何在 RandomForest 实现中对类进行加权?的主要内容,如果未能解决你的问题,请参考以下文章