我有 2 个类的数据集,我必须对其执行二元分类。我选择随机森林作为分类器,因为它为我提供了其他模型中最好的准确性。 dataset-1 中的数据点数量为 462 个,dataset-2 包含 735 个数据点。我注意到我的数据存在轻微的类别不平衡,因此我尝试优化我的训练模型并通过提供类别权重来重新训练我的模型。我提供了以下类(class)权重值。
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
)
使用选定的类别权重提高了模型的准确性,但我仍然怀疑我的方法是否正确或者只是巧合。我如何确保我的类(class)体重选择是完美的?
我使用以下公式计算类(class)权重:
Class weight for positive class = (No. of datapoints in dataset-1)/(Total datapoints)
Class weight for negative class = (No. of datapoints in dataset-2)/(Total datapoints))
For dataset-1 462/1197 = 0.385 For dataset-2 735/1197 = 0.614
这是一种可以接受的方法吗?如果不是的话,为什么它可以提高我的模型的准确性。请帮助我理解类(class)权重的细微差别。
最佳答案
How can I make sure my class weight choice is perfect?
嗯,你当然不能 - 完美在这里绝对是错误的词;我们正在寻找有用的启发式,既能提高性能又有意义(即它们感觉不像魔法)。
鉴于此,我们确实有一种独立的方式来交叉检查您的选择(这看起来确实不错),尽管是在 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 使用这些权重来不同地衡量错误分类成本,因此为少数类别分配更大权重是有意义的;这就是 draft paper 中的想法。作者:Breiman(RF 的发明者)和 Andy Liaw(randomForest
R 包的维护者):
We assign a weight to each class, with the minority class given larger weight (i.e., higher misclassification cost).
尽管如此,这不是randomForest
R 方法中的classwt
参数看起来的样子;来自docs :
classwt Priors of the classes. Need not add up to one. Ignored for regression.
“类的先验”实际上是类存在的类比,即您在这里计算的内容;这种用法似乎是相关(且高度投票)SO 线程的共识,What does the parameter 'classwt' in RandomForest function in RandomForest package in R stand for? ;此外,Andy Liaw 本人也有 stated那(强调我的):
The current "classwt" option in the randomForest package [...] is different from how the official Fortran code (version 4 and later) implements class weights.
我猜想官方的 Fortran 实现如之前草案论文中的引用所述(即类似 scikit-learn)。
大约 6 年前,我在硕士论文中使用 RF 来处理不平衡数据,据我所知,我发现 sampsize
参数比 classwt< 更有用
,Andy Liaw(再次...)对此有 advised (强调我的):
Search in the R-help archive to see other options and why you probably shouldn't use classwt.
更重要的是,在关于详细解释的已经相当“黑暗”的上下文中,根本不清楚使用 both sampsize
到底有什么效果和 classwt
参数在一起,就像您在这里所做的那样......
总结:
- 您所做的事情看起来确实正确且合乎逻辑
- 您应该尝试
classwt
和sampsize
参数单独使用(而不是一起使用),以便确定您的准确性在哪里提高应该归功于
关于r - 如何计算随机森林的类别权重,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57076570/