本文主要是介绍spark CountVectorizer+IDF提取中文关键词(scala),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在提取关键词中,TF-IDF是比较常用的算法,spark mlib中也提供了TF以及IDF的方法,但是由于spark提供的TF算法是不可逆的,即无法获取TF的结果对应的原句子的文字,所以需要采用 CountVectorizer。提取关键词的过程如下:
1、中文分词以及去掉停用词:
中文分词使用的是ansj:maven如下:
<!--ansj--><dependency><groupId>org.ansj</groupId><artifactId>ansj_seg</artifactId><version>5.1.3</version></dependency>
分词代码(其中数据有id,content两列,id为文档id,content为文档内容):
val filter = new StopRecognition();//val stopWords = List("/","·", ";",""",".","%",":","]","[","-");//过滤停用词val stopWords = com.lina.utils.StopWords.getStopWords("E:\\\\scalaworkspace\\\\stopword.txt");stopWords.foreach((a:String)=>filter.insertStopWords(a));val cgFun = udf((a:String)=>{ToAnalysis.parse(a.toString.replaceAll(",","")).recognition(filter).toStringWithOutNature("/").split("/", 0);});val pplDf = sqlResDf.withColumn("content",cgFun(col("content")));
2、CountVectorizer算法输出词频向量(如果只需要向量,不需要对应的词,也可以使用TF算法):
val cvModel: CountVectorizerModel = new CountVectorizer().setInputCol("content").setOutputCol("feature").setVocabSize(10000) //向量长度.setMinDF(2) //词汇出现次数必须大于等于2.fit(pplDf)val cvDf = cvModel.transform(pplDf);
3、使用IDF算法输出逆词频向量:
val idf = new IDF().setInputCol("feature").setOutputCol("features");val idfModel = idf.fit(cvDf);val idfDf = idfModel.transform(cvDf).drop("content").drop("feature")idfDf.show(false);
4、通过结果向量解析出关键词,注意cvModel.vocabulary中存储有向量索引与原句子的词的对应关系:
val voc= cvModel.vocabulary;val getKeyWordsFun = udf((fea:Vector)=>{var arrW = ArrayBuffer[String]();var arrV = ArrayBuffer[Double]();fea.foreachActive((index:Int,value:Double)=>{arrW += voc(index);arrV += value;});(arrW zip arrV).toList.sortBy(-_._2).take(25).toMap.map(_._1).toArray;});val keyWordsDf = idfDf.withColumn("keywords",getKeyWordsFun(col("features"))).drop("features");
这篇关于spark CountVectorizer+IDF提取中文关键词(scala)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!