基于主题模型的文本聚类分类

主题模型(Topic Model)是我研究的方向之一,利用主题模型和事先设定好的主题个数,可以训练出文档集合中不同主题所占的比例(主题比例)以及各个主题下关键词的出现的概率(主题分布)。
通过主题模型获得的主题比例和主题分布可以应用到进一步的数据挖掘任务中,其中包括主题推断、文档聚类、特征提取、维度压缩等任务,
本文主要是学习基于Spark的大规模文本的聚类和分类应用。

package ccut.spark.app
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.mllib.clustering._
import org.apache.spark.mllib.linalg.distributed._
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.ml.classification._  
import org.apache.spark.mllib.evaluation.MulticlassMetrics

/* * @topic 基于主题模型的文本聚类分类 * @time 2016/9/18 * 数据集来源Newsgroups新闻数据 */
object TextClusterAndClassifiedByLDA {
  def main(args : Array[String] ){
       val sc  =new SparkContext(new SparkConf()                                                                     
                           .setMaster("local")
                           .setAppName("TextClusterLDA "))
       //读取数据到RDD[(Long,Vector)]中
       val data = sc.textFile("L://论文//实验数据//20news-bydate-matlab//20news-bydate//matlab//train.data")
       //     val sc = new SparkContext(new SparkConf())
       //     var inputpath = args(0)
       //     val data = sc.textFile(inputpath)  
/* bin/spark-submit --class ccut.spark.app.TextClusterAndClassifiedByLDA --master spark://master:7077 /usr/local/data/sparkApp.jar /data/mllib/20news-bydate-matlab/20news-bydate/matlab/train.data*/
        val matrixEntries = data.map { s =>
            val splits = s.split(" ").toDouble)
         }
        val matrix = new CoordinateMatrix(matrixEntries)  //分布式矩阵的第三种matrix
        val parsedData = matrix.toIndexedRowMatrix.rows.map                    {r =>(r.index,r.vector)}
       //训练一个主题为20的LDA的模型,并输出文档的主题向量表示
        val ldaModel = new LDA().setK(20).run(parsedData)
        /* * DistributedLDAModel是LDA的分布式训练结果,包含各主题比例以及各主题的单词分布,其中主要有三个函数 * def describeTopics(maxTermsPerTopic: Int):Array[(Array[Int],Array[Double])] * def topicDistributions: RDD[Long,Vector] * val logLikelihood:Double * */
        val docVectors = ldaModel.asInstanceOf[DistributedLDAModel].topicDistributions.map(_._2)  //map(t => t._2)
        //利用MLlib的K均值算法对文档向量进行聚类学习,设置聚类的个数为20,最大迭代次数为100

        /* * K-means对主题模型的文本聚类 */
        val clusters = KMeans.train(docVectors, 20, 100)
        val WSSSE = clusters.computeCost(docVectors)
        println("Within Set Sum of Squared Error = " + WSSSE)

        /* * Logistic Regression对主题模型的文本分类 */
        val docVectors2 =ldaModel.asInstanceOf[DistributedLDAModel].topicDistributions
        //读取文档的分类标签
        val label_data = sc.textFile("L://论文//实验数据//20news-bydate-matlab//20news-bydate//matlab//train.label")
        val labels = label_data.map(_.toLong).zipWithIndex.map(_.swap)
        //与主题向量合并
        val labeled_docVectors = labels.join(docVectors2).map(_._2)
        //转换为RDD[LabeldPoint],LG数据格式就是数据格式为:标签, 特征1 特征2 特征3……
        val dataset = labeled_docVectors.map{ doc =>
          LabeledPoint(doc._1.toDouble-1,doc._2)
        }
        //将有标签的数据按6:4划分为训练集和测试集
        val splits = dataset.randomSplit(Array(0.6, 0.4))
        val training = splits(0)
        val testing = splits(1)
        //在训练集上训练一个LG模型
        val model = new LogisticRegressionWithLBFGS().setNumClasses(20).run(training)
//        new LogisticRegressionWithSGD
        //在测试集上训练验证模型的准确度
        val predictionAndLabels = testing.map { case LabeledPoint(label,features) =>
           val prediction = model.predict(features) 
           (prediction,label)
        }
        val  metrics = new MulticlassMetrics(predictionAndLabels)
        //算法效率评估(AUC,处于ROC curve下方的那部分面积的大小)
        println("Precision = " + metrics.precision +",Recall = " + metrics.recall)
  }
}

总结:这部分的学习主要是把自己的研究的方向与Spark MLlib的简单的实战应用了一下,接下来任务就是对其中的涉及到的算法在Spark中源码分析。

你可能感兴趣的:(spark,MLlib,主题模型)