我尝试使用Spark MLlib Logistic回归(LR)和/或随机森林(RF)分类器来创建模型,以便在两个类别之间进行描述,这些类别基数相差很多。 其中一组有150 000 000个负面,另一组仅有5万个正面情况。
使用默认参数训练LR和RF分类器后,我得到两个分类器的非常相似的结果,例如,对于以下测试集:
Test instances: 26842
Test positives = 433.0
Test negatives = 26409.0
分类器检测到:
truePositives = 0.0
trueNegatives = 26409.0
falsePositives = 433.0
falseNegatives = 0.0
Precision = 0.9838685641904478
Recall = 0.9838685641904478
看起来分类器根本无法检测到任何正面实例。
此外,无论数据如何分成训练集和测试集,分类器都会为测试集真正具有的false positives
提供与positives
相等完全相同的数量。 / p>
LR分类器默认阈值设置为0.5设置阈值为0.8没有任何区别。
val model = new LogisticRegressionWithLBFGS().run(training)
model.setThreshold(0.8)
问题:
1)请告知如何操纵分类器阈值,使分类器对具有一小部分正实例的类与具有大量负实例的类具有更大的敏感性?
2)任何其他MLlib分类器可以解决这个问题吗?
3)Logistic回归算法的itercept
参数是什么?
val model = new LogisticRegressionWithSGD().setIntercept(true).run(training)
答案 0 :(得分:4)
嗯,我认为你在这里有一个非常不平衡的数据集问题: 150 000 000 Class1 50 000 Class2。小3000倍。
因此,如果您训练一个假设所有都是Class1的分类器,您将拥有: 0.999666准确度。因此,最佳分类器将始终为ALL,即Class1。这就是你的模型在这里学习的东西。
有不同的方法可以评估这些情况,一般情况下你可以这样做,对较大的类进行下采样,或对较小的类进行上采样,或者你可以使用randomforests做一些其他的事情,例如当你在平衡的方式(分层),或增加权重:
http://statistics.berkeley.edu/sites/default/files/tech-reports/666.pdf
其他方法也存在,如SMOTE等(也做样本),您可以在此处阅读更多详细信息:
https://www3.nd.edu/~dial/papers/SPRINGER05.pdf
您可以为逻辑回归更改的阈值是概率1,您可以尝试使用" probabilityCol"在这里的逻辑回归示例的参数中:
http://spark.apache.org/docs/latest/ml-guide.html
但MLlib现在的一个问题是,并非所有分类器都返回概率,我向他们询问了这一点,并且它在他们的路线图中。