Spark MLlib中DataFrame的列'rawPrediction'和'probability'是什么意思?

19
在训练了LogisticRegressionModel后,我使用它转换了测试数据DF,并得到了预测DF。然后当我调用prediction.show()时,输出的列名为:[label | features | rawPrediction | probability | prediction]。我知道labelfeatrues的含义,但是如何理解rawPrediction|probability|prediction
3个回答

18
注意:请查看下面desertnaut的答案https://dev59.com/KloU5IYBdhLWcg3wAjrV#52947815RawPrediction通常是直接概率/置信度计算。从Spark文档中可以得知:
原始预测值是每个可能标签的预测结果,"raw"预测的含义可能因算法而异,但它直观地给出了对每个可能标签的置信度度量(其中较大的值表示更有信心)。 Prediction是通过找到rawPrediction的统计模式 - 通过argmax来得出的结果。
  protected def raw2prediction(rawPrediction: Vector): Double =
          rawPrediction.argmax

Probability是每个类别的条件概率。这里是scaladoc

估计给定原始预测的每个类别的概率,就地执行计算。这些预测也称为类别条件概率。

实际计算取决于您使用的分类器

DecisionTree

将原始预测向量标准化为多项式概率向量,就地执行。

它只是按类别求和然后除以总实例数。

 class_k probability = Count_k/Count_Total

逻辑回归(LogisticRegression)

它使用逻辑函数公式

 class_k probability: 1/(1 + exp(-rawPrediction_k))

朴素贝叶斯

 class_k probability = exp(max(rawPrediction) - rawPrediction_k)

随机森林

 class_k probability = Count_k/Count_Total

谢谢您的详细解释,但我仍有些疑问:既然所有的 rawPrediction 指示了每个可能类别的“概率”,为什么还需要计算概率呢?而且 BinaryClassificationEvaluator 中的指标 areaUnderROC 和 areaUnderPR 都是基于 rawPrediction 计算的。 - Hereme
@StarLee 我在我的回答中展示了PredictionProbability如何与rawPrediction不同(是从哪里推导出来的),这些信息直接来自源代码。所以我已经回答了这个问题。你想要更多细节的部分是什么? - WestCoastProjects
一些参考链接将不胜感激 - 谢谢 (+1) - desertnaut
@desertnaut 我深入挖掘了上述信息的代码库。 - WestCoastProjects
@desertnaut 它也适用于Xgboost分类器吗?P.S [sparkdl.xgboost.XgboostClassifier] - Pawan bisht

12
在旧版的Spark javadocs中(例如1.5.x),曾经有以下解释:
“‘原始’预测的含义可能因算法而异,但它直观地给出了每个可能标签的置信度(其中较大=更自信)。”
在后来的版本中已经没有这个解释了,但你仍然可以在Scala source code中找到它。
无论如何,除了任何不幸的措辞之外,在Spark ML中,对于逻辑回归情况下的rawPrecictions,其余的世界称之为logits,即逻辑回归分类器的原始输出,随后使用logistic function exp(x)/(1+exp(x))转换为概率分数。
以下是在Pyspark中使用玩具数据的示例:
spark.version
# u'2.2.0'

from pyspark.ml.classification import LogisticRegression
from pyspark.ml.linalg import Vectors
from pyspark.sql import Row
df = sqlContext.createDataFrame([
     (0.0, Vectors.dense(0.0, 1.0)),
     (1.0, Vectors.dense(1.0, 0.0))], 
     ["label", "features"])
df.show()
# +-----+---------+
# |label| features|
# +-----+---------+
# |  0.0|[0.0,1.0]|
# |  1.0|[1.0,0.0]|
# +-----+---------+

lr = LogisticRegression(maxIter=5, regParam=0.01, labelCol="label")
lr_model = lr.fit(df)

test = sc.parallelize([Row(features=Vectors.dense(0.2, 0.5)),
                       Row(features=Vectors.dense(0.5, 0.2))]).toDF()
lr_result = lr_model.transform(test)
lr_result.show(truncate=False)

以下是结果:

+---------+----------------------------------------+----------------------------------------+----------+ 
|features |                          rawPrediction |                            probability |prediction|
+---------+----------------------------------------+----------------------------------------+----------+ 
|[0.2,0.5]|[0.9894187891647654,-0.9894187891647654]|[0.7289731070426124,0.27102689295738763]|      0.0 |
|[0.5,0.2]|[-0.9894187891647683,0.9894187891647683]|[0.2710268929573871,0.728973107042613]  |      1.0 | 
+---------+----------------------------------------+----------------------------------------+----------+

现在让我们确认一下rawPrediction的逻辑函数是否给出了probability列:
import numpy as np

x1 = np.array([0.9894187891647654,-0.9894187891647654])
np.exp(x1)/(1+np.exp(x1))
# array([ 0.72897311, 0.27102689])

x2 = np.array([-0.9894187891647683,0.9894187891647683])
np.exp(x2)/(1+np.exp(x2))
# array([ 0.27102689, 0.72897311])

即这确实是情况


因此,总结所有三个输出列:

  • rawPrediction 是逻辑回归分类器的原始输出(数组长度等于类别数)
  • probability 是将逻辑函数应用于 rawPrediction 的结果(长度等于rawPrediction的长度)
  • prediction 是使数组 probability 取得最大值的参数,它给出最有可能的标签(单个数字)

2
这个答案比我的更好,因为它有实际的代码/示例。 - WestCoastProjects
1
是的,我看到了,谢谢。我把这个评论放在这里,以便其他读者受益,同时在我的答案顶部引用了这个评论。 - WestCoastProjects

-1
如果分类模型是逻辑回归,
那么原始预测值等于(w*x + 偏差)的变量系数值。 概率是1/(1+e^(w*x + 偏差))。 预测结果是0或者1。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接