1

我正在尝试使用 Apache Spark 的 MLlib 构建分类系统。我已经将朴素贝叶斯算法列入候选名单,并将使用 Java 8 来支持 Lambda 表达式。我是 lambda 表达式的新手,因此在 Java 中实现同样的表达式时面临困难。

我指的是以下链接,其中包含用 Scala 编写的示例,但很难将其转换为 Java 8。

http://chimpler.wordpress.com/2014/06/11/classifiying-documents-using-naive-bayes-on-apache-spark-mllib/

由于我不熟悉Scala,我被困在以下操作中,无法理解它,

val idfs = (termDocsRdd.flatMap(termDoc => termDoc.terms.map((termDoc.doc, _))).distinct().groupBy(_._2) collect {
  // if term is present in less than 3 documents then remove it
  case (term, docs) if docs.size > 3 =>
    term -> (numDocs.toDouble / docs.size.toDouble)
}).collect.toMap

有人可以为我指出正确的方向,即如何在利用 Sparks RDD 操作进行分布式处理的同时为文本文档样本构建 TfIdf 向量吗?

4

1 回答 1

2

好的,我会逐行解释,但是在 Scala API 文档中查找每个方法很容易。同样从长远来看,坚持使用 Scala 而不是使用超冗长的 java 将使您的生活更轻松。

第一行可以写

val idfs = (termDocsRdd.flatMap(termDoc => termDoc.terms.map(term => (termDoc.doc, term)))

所以它只是采用每个文档的术语,将它们连接在一起并添加termDoc.doc作为键。

.distinct()

^^明显

.groupBy(_._2) 

我们按术语分组,所以现在每个术语都是一个键,值是一个Seq文档

collect {
  case (term, docs) if docs.size > 3 =>
term -> (numDocs.toDouble / docs.size.toDouble)
})

collect是一个聪明的函数,就像 afilter后跟 a map,我们首先按模式过滤,所以... if docs.size > 3,然后映射到term -> (numDocs.toDouble / docs.size.toDouble)

所以我们现在将术语作为键,将 aDouble作为值。最后最后一行只是把它RDD变成了一个普通的 Scala Map

.collect.toMap

collect这是一个愚蠢的名字,我认为最终可能会被弃用,toArray做同样的事情而且更容易混淆

于 2014-09-03T04:19:09.390 回答