如何在Apache Spark中使用DStream进行特征提取

时间:2016-12-06 13:21:45

标签: scala apache-spark feature-extraction dstream

我有通过DStream从Kafka到达的数据。我想执行特征提取以获得一些关键字。

我不想等待所有数据的到来(因为它意图是可能永远不会结束的连续流),所以我希望以块的形式进行提取 - 如果准确性对我来说并不重要会有点受苦。

到目前为止,我把这样的东西放在一起:

Dog

然而,我收到了def extractKeywords(stream: DStream[Data]): Unit = { val spark: SparkSession = SparkSession.builder.getOrCreate val streamWithWords: DStream[(Data, Seq[String])] = stream map extractWordsFromData val streamWithFeatures: DStream[(Data, Array[String])] = streamWithWords transform extractFeatures(spark) _ val streamWithKeywords: DStream[DataWithKeywords] = streamWithFeatures map addKeywordsToData streamWithFeatures.print() } def extractFeatures(spark: SparkSession) (rdd: RDD[(Data, Seq[String])]): RDD[(Data, Array[String])] = { val df = spark.createDataFrame(rdd).toDF("data", "words") val hashingTF = new HashingTF().setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(numOfFeatures) val rawFeatures = hashingTF.transform(df) val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features") val idfModel = idf.fit(rawFeatures) val rescaledData = idfModel.transform(rawFeature) import spark.implicits._ rescaledData.select("data", "features").as[(Data, Array[String])].rdd } - 我并不感到惊讶,因为我只是试图将事情放在一起,而且我明白,因为我不等待某些数据的到达,所以生成的模型可能是空的我尝试在数据上使用它。

这个问题的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我使用了评论中的建议,并将程序拆分为2次:

  • 计算IDF模型并将其保存到文件

    的人
    def trainFeatures(idfModelFile: File, rdd: RDD[(String, Seq[String])]) = {
      val session: SparkSession = SparkSession.builder.getOrCreate
    
      val wordsDf = session.createDataFrame(rdd).toDF("data", "words")
    
      val hashingTF = new HashingTF().setInputCol("words").setOutputCol("rawFeatures")
      val featurizedDf = hashingTF.transform(wordsDf)
    
      val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")
      val idfModel = idf.fit(featurizedDf)
    
      idfModel.write.save(idfModelFile.getAbsolutePath)
    }
    
  • 从文件中读取IDF模型并在所有传入信息上运行它的人

    val idfModel = IDFModel.load(idfModelFile.getAbsolutePath)
    
    val documentDf = spark.createDataFrame(rdd).toDF("update", "document")
    
    val tokenizer = new Tokenizer().setInputCol("document").setOutputCol("words")
    val wordsDf = tokenizer.transform(documentDf)
    
    val hashingTF = new HashingTF().setInputCol("words").setOutputCol("rawFeatures")
    val featurizedDf = hashingTF.transform(wordsDf)
    
    val extractor = idfModel.setInputCol("rawFeatures").setOutputCol("features")
    val featuresDf = extractor.transform(featurizedDf)
    
    featuresDf.select("update", "features")