Spark:回归模型阈值和精度

时间:2015-12-11 05:04:56

标签: apache-spark apache-spark-mllib

我有逻辑回归模式,我明确地将阈值设置为0.5。

model.setThreshold(0.5)

我训练模型然后我想得到基本的统计数据 - 精确度,召回等。

这是我在评估模型时所做的事情:

val metrics = new BinaryClassificationMetrics(predictionAndLabels)

val precision = metrics.precisionByThreshold


precision.foreach { case (t, p) =>

      println(s"Threshold is: $t, Precision is: $p")

    }

我得到的结果只有0.0和1.0作为阈值,0.5完全被忽略。

以上是上述循环的输出:

阈值为:1.0,精度为:0.8571428571428571

阈值为:0.0,精度为:0.3005181347150259

当我调用metrics.thresholds()时,它也只返回两个值,0.0和1.0。

如何获得阈值为0.5的精度和召回值?

3 个答案:

答案 0 :(得分:5)

您需要在进行预测之前清除模型阈值。清算阈值使您的预测返回分数而不是分类标签。如果不是,您将只有两个阈值,即您的标签0.0和1.0。

model.clearThreshold()

来自predictionsAndLabels的元组应该看起来像(0.6753421,1.0)而不是(1.0,1.0)

查看https://github.com/apache/spark/blob/master/examples/src/main/scala/org/apache/spark/examples/mllib/BinaryClassificationMetricsExample.scala

如果输入很大,您可能仍希望设置numBins来控制点数。

答案 1 :(得分:1)

我认为所发生的是所有预测都是0.0或1.0。然后中间阈值没有区别。

考虑numBins的{​​{1}}参数:

  

<强> BinaryClassificationMetrics   如果大于0,那么内部计算的曲线(ROC曲线,PR曲线)将被下采样到这么多“箱”。如果为0,则不会发生下采样。这很有用,因为曲线包含输入中每个不同分数的一个点,这可能与输入本身一样大 - 数百万或更多,当数千可能完全足以汇总曲线时。在下采样之后,曲线将改为由大约numBins点组成。点数由相等数量的连续点的区间组成。每个bin的大小是floor(scoreAndLabels.count()/ numBins),这意味着生成的bin数可能与numBins不完全相同。结果,每个分区中的最后一个bin可能会更小,这意味着在分区边界可能会有一个额外的样本。

因此,如果您未设置numBins,则将根据所有不同的预测值计算精度。在你的情况下,这似乎只有0.0和1.0。

答案 2 :(得分:0)

首先,尝试添加更多像这样的bin(这里numBins是10):

(label, prediction)

如果您仍然只有两个阈值0和1,那么请检查以确定您定义predictAndLabels的方式。如果您不小心提供了(prediction, label)而不是alert.showAndWait(); ,那么很多人都会遇到此问题。