【问题标题】:How do I display predictions, labels and dataframe column in Spark/Scala?如何在 Spark/Scala 中显示预测、标签和数据框列?
【发布时间】:2017-12-30 04:30:08
【问题描述】:

我正在 Spark/Scala 中执行朴素贝叶斯分类。好像没问题,代码是:

import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.ml.feature.StringIndexer

val dfLemma2 = dfLemma.withColumn("racist", 'racist.cast("String"))

val indexer = new StringIndexer().setInputCol("racist").setOutputCol("indexracist")
val indexed = indexer.fit(dfLemma2).transform(dfLemma2)
indexed.show()


val hashingTF = new HashingTF()
  .setInputCol("lemma").setOutputCol("rawFeatures").setNumFeatures(20)
val featurizedData = hashingTF.transform(indexed)

val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")
val idfModel = idf.fit(featurizedData)
val rescaledData = idfModel.transform(featurizedData)
rescaledData.select("features", "indexracist").take(3).foreach(println)
val changedTypedf = rescaledData.withColumn("indexracist", 'indexracist.cast("double"))
changedTypedf.show()

// val labeled = changedTypedf.map(row => LabeledPoint(row(0), row.getAs[Vector](4)))

val labeled = changedTypedf.select("indexracist","features").rdd.map(row => LabeledPoint(
   row.getAs[Double]("indexracist"),
   org.apache.spark.mllib.linalg.Vectors.fromML(row.getAs[org.apache.spark.ml.linalg.SparseVector]("features"))
))


import org.apache.spark.mllib.classification.{NaiveBayes, NaiveBayesModel}
import org.apache.spark.mllib.util.MLUtils
    // Split data into training (60%) and test (40%).
    val Array(training, test) = labeled.randomSplit(Array(0.6, 0.4))

    val model = NaiveBayes.train(training, lambda = 1.0, modelType = "multinomial")

val predictionAndLabel = test.map(p => (model.predict(p.features), p.label))    

predictionAndLabel.take(100)

这个输出:

res330: Array[(Double, Double)] = Array((0.0,0.0), (0.0,0.0), (0.0,0.0), (0.0,0.0),

我假设是一个(预测,标签)对的数组。 我想输出的是这些对加入到原始文本中,这是训练数据框中称为引理的列,因此类似于:

--------------------------------------------------
| Prediction | Label      | lemma                |
--------------------------------------------------
|    0.0     |    0.0     |[cakes, are, good]    |
|    0.0     |    0.0     |[jim, says, hi]       |
|    1.0     |    1.0     |[shut, the, dam, door]|
...
--------------------------------------------------

感谢任何指针,因为我的 Spark/Scala 很弱。

编辑,文本列在“索引”中称为“引理”:

+------+-------------------------------------------------------------------------------------------------------------------+
|racist|lemma                                                                                                              |
+------+-------------------------------------------------------------------------------------------------------------------+
|true  |[@cllrwood, abbo, @ukip, britainfirst]                                                                             |
|false |[objectofthemonth, george, lansbury, bust, jussuf, abbo, amp, fascinating, insight, son, jerome]                   |
|false |[nowplay, one, night, stand, van, brave, @bbraveofficial, bbravesquad, abbo, safe]                                 |
|false |[@mahesh, weet, son, satyamurthy, kante, abbo, chana, better, aaamovie]                                            |

【问题讨论】:

  • stackoverflow.com/questions/7539831/scala-draw-table-to-console - 可能有您正在寻找的答案。我不知道有任何 Spark/Scala OOTB 方法可以做到这一点。
  • 谢谢谢尔盖。我真正关心的不是格式,而是来自两个数据集的正确行/字段的组合。对大多数 Scala 程序员来说可能很明显,但对我来说不是!
  • 我可以从您的输入中获取样本吗?我会在你的解决方案中工作

标签: scala apache-spark apache-spark-mllib


【解决方案1】:

您只需要转换您的数据并将其显示如下:

val predictions = model.transform(test)
predictions.show()

【讨论】:

  • 谢谢 Eliasah,我已经完成了转换,我可以显示预测,但我的问题是如何使用原始数据框列很好地格式化它们。
  • 我不确定我理解你的意思。您是否愿意用最少的完整且可验证的示例以及预期的输出来更新您的问题?
  • 呃预期的输出是上面的表格。我想显示来自 Array((0.0,0.0),... 的对及其相应的文本,例如 [cakes, are, good]。
  • 对应的文字标签是什么?他们现在在哪里?这就是为什么我要求你提供一个最低限度的例子
  • 啊,好吧,很公平。我已经添加了其余的杂乱代码。文本列在“索引”中称为“引理”。
【解决方案2】:

尝试使用 ml 包而不是 mllib 包。例如参考https://github.com/apache/spark/blob/master/examples/src/main/scala/org/apache/spark/examples/ml/NaiveBayesExample.scala

import org.apache.spark.ml.classification.NaiveBayes
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator

import org.apache.spark.sql.SparkSession

object NaiveBayesExample {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession
      .builder
      .appName("NaiveBayesExample")
      .getOrCreate()


    // Load the data stored in LIBSVM format as a DataFrame.
    val data = spark.read.format("libsvm").load("data/mllib/sample_libsvm_data.txt")

    // Split the data into training and test sets (30% held out for testing)
    val Array(trainingData, testData) = data.randomSplit(Array(0.6, 0.4))

    // Train a NaiveBayes model.
    val model = new NaiveBayes()
      .fit(trainingData)

    // Select example rows to display.
    val predictions = model.transform(testData)
    predictions.show()

    // Select (prediction, true label) and compute test error
    val evaluator = new MulticlassClassificationEvaluator()
      .setLabelCol("label")
      .setPredictionCol("prediction")
      .setMetricName("accuracy")
    val accuracy = evaluator.evaluate(predictions)
    println("Test set accuracy = " + accuracy)


    spark.stop()
  }
}

【讨论】:

【解决方案3】:

在选择要显示的输出列时,请尝试同时包含“引理”列,以便将其与标签和特征列一起写入。

更多详情请参考How to create correct data frame for classification in Spark ML。这篇文章和你的问题有点相似,看看是否有帮助

【讨论】:

  • 谢谢,看起来很有用。对于 50 分指针如何应用到我的代码的任何机会?
【解决方案4】:

正如一些答案所说:自 spark 2.0 起,建议您使用 ml 包而不是 mllib

使用ml 包重写代码后,您的问题的答案将非常简单:只需选择正确的列即可满足您的需求

import org.apache.spark.ml.feature.{HashingTF, IDF}
import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.classification.NaiveBayes
import org.apache.spark.ml.feature.{VectorAssembler, StringIndexer}

val dfLemma2 = dfLemma.withColumn("racist", 'racist.cast("String"))

val indexer = new StringIndexer().setInputCol("racist").setOutputCol("indexracist")

val hashingTF = new HashingTF()
  .setInputCol("lemma")
  .setOutputCol("rawFeatures")
  .setNumFeatures(20)

val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")

val naiveBayes =
  new NaiveBayes().setLabelCol("indexracist").setFeaturesCol("features").setModelType("multinomial").setSmoothing(1.0)

val pipeline = new Pipeline().setStages(Array(indexer, hashingTF, idf, naiveBayes))

val Array(training, test) = dfLemma2.randomSplit(Array(0.6, 0.4))

val model = pipeline.fit(training)

val predictionAndLabel = model.transform(test).select('Prediction, 'racist, 'indexracist, 'lemma)

predictionAndLabel.take(100)

希望对您有所帮助,否则请评论您的问题

【讨论】:

  • 这很好,但是如何从数据框中添加不属于分类器特征的列——主要是原始信息.. 用于创建特征但不用作特征
【解决方案5】:

我们必须使用管道来获取预测列以外的训练列

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多