当您运行val model = pipeline.fit(data) 代码时,所有Estimator 阶段(即:分类、回归、聚类等机器学习任务)都适合数据并创建Transformer 阶段。您只有 Transformer 阶段,因为您正在此管道中创建功能。
为了执行您的模型,现在只包含Transformer 阶段,您需要运行val results = model.transform(data)。这将针对您的数据框执行每个 Transformer 阶段。因此,在model.transform(data) 进程结束时,您将拥有一个由原始行、Tokenizer 输出、StopWordsRemover 输出以及最后的 NGram 结果组成的数据帧。
在特征创建完成后发现前 5 个 ngram 可以通过 SparkSQL 查询来执行。先炸开ngram列,然后count groupby ngrams,按计数列降序排序,然后执行show(5)。或者,您可以使用"LIMIT 5 方法代替show(5)。
顺便说一句,您可能应该将您的对象名称更改为非标准类名称。否则你会得到一个模棱两可的范围错误。
代码:
import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.feature.Tokenizer
import org.apache.spark.sql.SparkSession._
import org.apache.spark.sql.functions._
import org.apache.spark.ml.feature.NGram
import org.apache.spark.ml.feature.StopWordsRemover
import org.apache.spark.ml.{Pipeline, PipelineModel}
object NGramPipeline {
def main() {
val sparkSession = SparkSession.builder.appName("NGram Pipeline").getOrCreate()
val sc = sparkSession.sparkContext
val data = sparkSession.read.text("quangle.txt").toDF("text")
val pipe1 = new Tokenizer().setInputCol("text").setOutputCol("words")
val pipe2 = new StopWordsRemover().setInputCol("words").setOutputCol("filtered")
val pipe3 = new NGram().setN(2).setInputCol("filtered").setOutputCol("ngrams")
val pipeline = new Pipeline().setStages(Array(pipe1, pipe2, pipe3))
val model = pipeline.fit(data)
val results = model.transform(data)
val explodedNGrams = results.withColumn("explNGrams", explode($"ngrams"))
explodedNGrams.groupBy("explNGrams").agg(count("*") as "ngramCount").orderBy(desc("ngramCount")).show(10,false)
}
}
NGramPipeline.main()
输出:
+-----------------+----------+
|explNGrams |ngramCount|
+-----------------+----------+
|quangle wangle |9 |
|wangle quee. |4 |
|'mr. quangle |3 |
|said, -- |2 |
|wangle said |2 |
|crumpetty tree |2 |
|crumpetty tree, |2 |
|quangle wangle, |2 |
|crumpetty tree,--|2 |
|blue babboon, |2 |
+-----------------+----------+
only showing top 10 rows
请注意,存在导致行重复的语法(逗号、破折号等)。在执行 ngram 时,过滤我们的语法通常是一个好主意。您通常可以使用正则表达式来执行此操作。