当前位置: 首页 > 知识库问答 >
问题:

在 Spark 中的分类预测中对概率进行索引

唐弘厚
2023-03-14

我正在尝试索引Spark中分类预测中的预测概率。我有一个多类分类器的输入数据,标签为红色、绿色、蓝色。

输入数据帧:

+-----+---+---+---+---+---+---+---+---+---+----+----+----+----+
|  _c0|_c1|_c2|_c3|_c4|_c5|_c6|_c7|_c8|_c9|_c10|_c11|_c12|_c13|
+-----+---+---+---+---+---+---+---+---+---+----+----+----+----+
|  red|  0|  0|  0|  1|  0|  0|  0|  2|  3|   2|   2|   0|   5|
|green|  5|  6|  0| 14|  0|  5|  0| 95|  2| 120|   0|   0|   9|
|green|  6|  1|  0|  3|  0|  4|  0| 21| 22|  11|   0|   0|  23|
|  red|  0|  1|  0|  1|  0|  4|  0|  1|  4|   2|   0|   0|   5|
|green| 37|  9|  0| 19|  0| 31|  0| 87|  9| 108|   0|   0| 170|
+-----+---+---+---+---+---+---+---+---+---+----+----+----+----+
only showing top 5 rows

我使用StringIndexer索引标签列,使用VectorAssembler从特征列创建特征向量。

解析的数据帧:

+-----+--------------------+
|label|            features|
+-----+--------------------+
|  1.0|(13,[3,7,8,9,10,1...|
|  0.0|[5.0,6.0,0.0,14.0...|
|  0.0|[6.0,1.0,0.0,3.0,...|
|  1.0|(13,[1,3,5,7,8,9,...|
|  0.0|[37.0,9.0,0.0,19....|
+-----+--------------------+
only showing top 5 rows

将使用此数据生成随机森林分类模型。在查询时,我将提供特征列来预测标签及其概率。

查询数据帧:

+---+---+---+---+---+---+---+---+---+---+----+----+----+
|_c0|_c1|_c2|_c3|_c4|_c5|_c6|_c7|_c8|_c9|_c10|_c11|_c12|
+---+---+---+---+---+---+---+---+---+---+----+----+----+
| 11| 11|  0| 23|  0|  7|  2| 70| 81| 76|   7|   0|  23|
|  4|  0|  0|  0|  0|  0|  2|  2|  3|  2|   7|   0|   2|
+---+---+---+---+---+---+---+---+---+---+----+----+----+

已解析查询数据帧:

+--------------------+--------------------+
|          queryValue|            features|
+--------------------+--------------------+
|11,11,0,23,0,7,2,...|[11.0,11.0,0.0,23...|
|4,0,0,0,0,0,2,2,3...|(13,[0,6,7,8,9,10...|
+--------------------+--------------------+

RFCModel的原始预测:

+--------------------+--------------------+--------------------+----------+
|          queryValue|            features|         probability|prediction|
+--------------------+--------------------+--------------------+----------+
|11,11,0,23,0,7,2,...|[11.0,11.0,0.0,23...|        [0.67, 0.32]|       0.0|
|4,0,0,0,0,0,2,2,3...|(13,[0,6,7,8,9,10...|        [0.05, 0.94]|       1.0|
+--------------------+--------------------+--------------------+----------+

在原始预测中,概率列是一个双精度数组,其概率位于同应类索引中。假设概率列中的一行是 [0.67,0.32],则表示类 0.0 的概率为 0.67,类 1.0 的概率为 0.32。概率列仅在标签为 0,1,2 时才有意义...在这种情况下,当我使用 IndexToString 将预测索引回原始标签时,概率列将毫无意义。

索引数据帧:

+--------------------+--------------------+--------------------+----------+
|          queryValue|            features|         probability|prediction|
+--------------------+--------------------+--------------------+----------+
|11,11,0,23,0,7,2,...|[11.0,11.0,0.0,23...|        [0.67, 0.32]|     green|
|4,0,0,0,0,0,2,2,3...|(13,[0,6,7,8,9,10...|        [0.05, 0.94]|       red|
+--------------------+--------------------+--------------------+----------+

我想像下面这样索引回概率列,

+--------------------+--------------------+--------------------------+----------+
|          queryValue|            features|              probability |prediction|
+--------------------+--------------------+--------------------------+----------+
|11,11,0,23,0,7,2,...|[11.0,11.0,0.0,23...|{"red":0.32,"green":0.67} |     green|
|4,0,0,0,0,0,2,2,3...|(13,[0,6,7,8,9,10...|{"red":0.94,"green":0.05} |       red|
+--------------------+--------------------+--------------------------+----------+

现在,我通过将数据帧转换为列表来索引概率列。spark中是否有可用的功能转换器来实现这一点?

共有1个答案

上官彬
2023-03-14

尝试使用以下方法解决此问题:-

我使用<code>虹膜数据

  1. 示例输入(前5行)

+------------+-----------+------------+-----------+-----------+
|sepal_length|sepal_width|petal_length|petal_width|      label|
+------------+-----------+------------+-----------+-----------+
|         5.1|        3.5|         1.4|        0.2|Iris-setosa|
|         4.9|        3.0|         1.4|        0.2|Iris-setosa|
|         4.7|        3.2|         1.3|        0.2|Iris-setosa|
|         4.6|        3.1|         1.5|        0.2|Iris-setosa|
|         5.0|        3.6|         1.4|        0.2|Iris-setosa|
+------------+-----------+------------+-----------+-----------+

我使用StringIndexer索引标签列,使用VectorAssembler从特征列创建特征向量。

我们将在这里使用< code>stringIndexerModel来获取< code>Map[index,Label]

// in my case, StringIndexerModel is referenced as labelIndexer
val labelToIndex = labelIndexer.labels.zipWithIndex.map(_.swap).toMap
println(labelToIndex)

结果-

Map(0 -> Iris-setosa, 1 -> Iris-versicolor, 2 -> Iris-virginica)
  import org.apache.spark.ml.linalg.Vector
  val mapToLabel = udf((vector: Vector) => vector.toArray.zipWithIndex.toMap.map{
      case(prob, index) => labelToIndex(index) -> prob
    })
    predictions.select(
      col("features"),
      col("probability"),
      to_json(mapToLabel(col("probability"))).as("probability_json"),
      col("prediction"),
      col("predictedLabel"))
      .show(5,false)

结果-

+-------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+----------+--------------+
|features                             |probability                                                 |probability_json                                                                                             |prediction|predictedLabel|
+-------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+----------+--------------+
|(123,[0,37,82,101],[1.0,1.0,1.0,1.0])|[0.7094347002635046,0.174338768115942,0.11622653162055337]  |{"Iris-setosa":0.7094347002635046,"Iris-versicolor":0.174338768115942,"Iris-virginica":0.11622653162055337}  |0.0       |Iris-setosa   |
|(123,[0,39,58,101],[1.0,1.0,1.0,1.0])|[0.7867074275362319,0.12433876811594202,0.0889538043478261] |{"Iris-setosa":0.7867074275362319,"Iris-versicolor":0.12433876811594202,"Iris-virginica":0.0889538043478261} |0.0       |Iris-setosa   |
|(123,[0,39,62,107],[1.0,1.0,1.0,1.0])|[0.5159492704509036,0.2794443583750028,0.2046063711740936]  |{"Iris-setosa":0.5159492704509036,"Iris-versicolor":0.2794443583750028,"Iris-virginica":0.2046063711740936}  |0.0       |Iris-setosa   |
|(123,[2,39,58,101],[1.0,1.0,1.0,1.0])|[0.7822379507920459,0.12164981462756994,0.09611223458038423]|{"Iris-setosa":0.7822379507920459,"Iris-versicolor":0.12164981462756994,"Iris-virginica":0.09611223458038423}|0.0       |Iris-setosa   |
|(123,[2,43,62,101],[1.0,1.0,1.0,1.0])|[0.7049652235193186,0.17164981462756992,0.1233849618531115] |{"Iris-setosa":0.7049652235193186,"Iris-versicolor":0.17164981462756992,"Iris-virginica":0.1233849618531115} |0.0       |Iris-setosa   |
+-------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+----------+--------------+
only showing top 5 rows
 类似资料:
  • 问题内容: 这个问题是我先前提出的问题的继续。 我训练了一个LSTM模型,以预测100个具有3个特征的样本的批次的二进制类(1或0),即:数据的形状为(m,100,3),其中m是批次数。 数据: 目标: 型号代码: 在训练阶段,模型 不是 有状态的。当预测我正在使用 状态 模型时,遍历数据并为每个样本输出概率: 当查看批处理结束时的概率时,它恰好是我对整个批处理进行预测时得到的值(不是一个接一个)

  • 问题内容: 我目前正在将H2O用于分类问题数据集。我正在python 3.6环境中对其进行测试。我注意到预测方法的结果是给出0到1之间的值(我假设这是概率)。 在我的数据集中,目标属性是数字,即值是1且值是0。我确保将类型转换为目标属性的类别,但仍得到相同的结果。 然后我修改了代码,仍然使用H2OFrame上的方法将目标列转换为因数,结果没有任何变化。 但是,当我分别将target属性中的值分别更

  • 问题内容: 我很好奇,我该如何在Java中实现概率?例如,如果变量显示的机会是1/25,那么我将如何实现呢?还是其他可能性?请指出我的大致方向。 问题答案: 您将使用Random生成一个随机数,然后根据文字对其进行测试以匹配您尝试实现的概率。 因此给出: 将有1/25的可能性为真(因为返回从0到25(但不包括25)的任何数字的可能性均是偶数)。 您当然也必须这样做。 如下面所指出的,如果获得多个随

  • 我试图在朱莉娅做一个非常简单的逻辑回归。但是朱莉娅的打字系统似乎给我带来了问题。基本上,glm预测给了我一系列的可能性。我想做一个简单的循环,如果概率>=0.5,它是1,否则是0。我希望这些标签也是整数。

  • 我在我之前的问题上再接再厉,因为还有一个进一步的问题。 我已经在Matlab中为我的数据向量拟合了一个正态分布:。现在我有一个新的数据点(例如x=0.5),我想计算它的概率。 使用cdf(PD,x)将不起作用,因为它给出了点小于或等于x(但不完全是x)的概率。使用pdf(PD,x)只给出密度,而不是概率,因此它可以大于1。 我如何计算概率?

  • 问题内容: 是否有一个库函数对列表/元组执行二进制搜索,如果找到则返回项目的位置,否则返回“ False”(-1,None等)? 我在bisect模块中找到了函数,但是即使该项目不在列表中,它们仍然会返回位置。这对于他们的预期用途来说是完全可以的,但是我只想知道列表中是否包含某项(不想插入任何内容)。 我考虑过使用然后检查该位置处的项目是否等于我要搜索的项目,但这似乎很麻烦(而且我还需要进行边界检