基于Spark的TF-IDF算法的中文文本相似度实现

1 篇文章 0 订阅
1 篇文章 0 订阅

Spark version:spark 2.2.0 Hadoop version:Hadoop 2.6.5 Scala version:scala 2.11  ansj version:5.1.5

第一、先说下应用场景吧,用户给出一段文字然后我返回十个与这段文字最相似的文件名称。

第二、什么是TF-IDF算法?我就简单介绍一下,因为百度上也有许多的介绍,TF-IDF用中文来解释就是词频、逆文档频率的意思,TF-IDF体现了词项与文档关联度的直观理解,一个词在文档中出现的越多则越重要,但是词项是不平等的文档中出现罕见词项的意义比常见词更大,因此就要取词项出现次数的倒数,词项在语料库中的分布式呈指数型的一个常用词出现次数往往是罕见词的数十倍,假如直接除以原始文档的频率则罕见词的权重就会过大,所以算法应对逆文档率取对数,让文档频率差别由乘数级变为加数级。

第三、由于spark MLlib库已经有TF-IDF算法的实现我们就不亲自实现了,而是去调用它的,对于整个功能的逻辑如下:

(1)获取数据、(2)用中文分词工具分词(这里使用的是ansj)、(3)计算TF、IDF、(4)计算向量间的余弦相似度


废话不多说直接上代码:



import org.ansj.recognition.impl.StopRecognition

import org.ansj.splitWord.analysis.ToAnalysis

import org.apache.spark.mllib.feature.{ HashingTF, IDF }

import org.apache.spark.{ SparkConf, SparkContext }

import org.apache.spark.mllib.linalg.{ SparseVector => SV }


import scala.collection.mutable.ArrayBuffer

import scala.util.matching.Regex

object TfIdfs {


  def main(args: Array[String]): Unit = {

    val conf =new SparkConf().setAppName("tdidf")

    val sc =new SparkContext(conf)

//读取2600份法律案例

    valrdd = sc.wholeTextFiles("hdfs://master:8020/data2/*")


    val text =rdd.map { case (file,text) => text }


    val title =rdd.map { case (title,text) => title }.collect()


    val dim = math.pow(2,18).toInt

    val hashingTF =new HashingTF(dim)


    val filter =new StopRecognition()

    filter.insertStopNatures("w")//过滤掉标点

//使用ansj对文本进行分词

    val tokens2 =text.map(doc => ToAnalysis.parse(doc).recognition(filter).toStringWithOutNature(" ").split(" ").toSeq)

//tf计算

    val tf =hashingTF.transform(tokens2)


    // cache data in memory

    tf.cache

    //idf计算

    val idf =new IDF().fit(tf)

    val tfidf =idf.transform(tf)

    val vectorArr =tfidf.collect()

//需要匹配相似度的文本

    valrdd3 = sc.parallelize(Seq("被告人王乃胜,高中文化,户籍所在地:白山市,居住地:白山市。"))


val predictTF2 =rdd3.map(doc => hashingTF.transform(ToAnalysis.parse(doc).recognition(filter).toStringWithOutNature(" ").split(" ").toSeq))


    valpredictTfIdf = idf.transform(predictTF2)


    import breeze.linalg._

    val predictSV =predictTfIdf.first.asInstanceOf[SV]

    val c =new ArrayBuffer[(String, Double)]()

  

    valbreeze1 = new SparseVector(predictSV.indices,predictSV.values,predictSV.size)

    var tag =0

   

    for (i <-vectorArr) {


      val Svector =i.asInstanceOf[SV]

      val breeze2 =new SparseVector(Svector.indices,Svector.values, Svector.size)

      valcosineSim = breeze1.dot(breeze2) / (norm(breeze1) * norm(breeze2))

      c ++= Array((title(tag),cosineSim))

      tag += 1


    }

    val cc =c.toArray.sortBy(_._2).reverse.take(10)

    println(cc.toBuffer)

    sc.stop()


  }

}




  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值