Stanford Topic Modeling Toolbox0.4.0翻译

来源:互联网 发布:淘宝秋季女装新款 编辑:程序博客网 时间:2024/06/16 18:56
本文内容翻译自 http://nlp.stanford.edu/software/tmt/tmt-0.4/
推荐一本书《LDA漫游指南》,对LDA的原理、应用均进行了详尽的介绍。目前斯坦福大学的TMT(Topic Modeling Toolbox)已经更新至0.4.0版本。笔者最近在研究这个小工具,特此做一些笔记,在使用中遇到一些问题也进行说明。这个小工具是scala写的,但是本机不需要安装scala,需要安装jre1.5以上版本,笔者使用的是1.7.79版本。按照官网的说明,运行一个最简单的例子:首先下载tmt-0.4.0.jar,example-0-test.scalapubmed-oa-subset.csv,这三个文件要放在同一个文件夹里。第一个文件是一个程序的jar包,也就是程序的主体;第二个文件是程序所运行的脚本,定义了处理的数据和显示结果等;第三个文件就是进行操作的数据了。以下就是主界面,点击File——>open script...打开脚本,比如之前下载的example-0-test.scala


这些按钮中,Edit script可以修改脚本,比如修改处理的数据集。修改完成之后,按run就可以了。



需要注意的是,在官网下载的示例数据集pubmed-oa-subset.csv中,存在类似中文的乱码,这些乱码会导致报错,所以要把这些乱码删除。至于网上说的要把字符集修改成utf-8,笔者没有遇到这样的问题。


准备数据集

本例中使用的代码是example-1-dataset.scala文件

从一个CSV文件提取并且准备文本的过程可以被看做一个流水线:一个CSV文件经过一系列过程最终成为可以用来训练模型的结果。这里就是pubmed-oa-subset.csv数据文件的案例:

01.val source = CSVFile("pubmed-oa-subset.csv") ~> IDColumn(1);
02. 
03.val tokenizer = {
04.SimpleEnglishTokenizer() ~>            // tokenize on space and punctuation
05.CaseFolder() ~>                        // lowercase everything
06.WordsAndNumbersOnlyFilter() ~>         // ignore non-words and non-numbers
07.MinimumLengthFilter(3)                 // take terms with >=3 characters
08.}
09. 
10.val text = {
11.source ~>                              // read from the source file
12.Column(4) ~>                           // select column containing text
13.TokenizeWith(tokenizer) ~>             // tokenize with tokenizer above
14.TermCounter() ~>                       // collect counts (needed below)
15.TermMinimumDocumentCountFilter(4) ~>   // filter terms in <4 docs
16.TermDynamicStopListFilter(30) ~>       // filter out 30 most common terms
17.DocumentMinimumLengthFilter(5)         // take only docs with >=5 terms
18.}

输入的数据文件(在代码变量中)是一个指向你先前下载的CSV文件的指针,随后我们将经过一系列的变形、过滤或者其他与数据交互的操作。第一行代码中,制定了TMT使用第一列(column 1)的值作为记录ID,这对文件中每一条记录都是独一无二的标志。如果你的sheet中的记录ID不在第一列,就把上文代码第一行中的1改成你自己的列数。如果你的sheet没有记录ID这一列,你可以删掉“~> IDColumn(1)”,TMT会用文件的行号作为记录ID。如果你的CSV文件第一行包含了列名,你可以删除第一行代码,改用Drop步骤:

1.val source = CSVFile("your-csv-file.csv") ~> IDColumn(yourIdColumn) ~> Drop(1);

分词Tokenizing

第一步是定义分词器(tokenizer),以将数据集中包含文本的单元转化成话题模型分析的term。从第三行到第七行定义的分词器,制定了一系列的将一个字符串转化成一系列字符串的变形操作。
笔者注:每两个步骤之间需要有~>符号,最后一个不需要
首先,我们用SimpleEnglishTokenizer()去除单词结尾的标点符号,然后用空白符(tab、空格、回车等)将输入文本分解。如果你的文件已经进行过清洗了,你也可以用 WhitespaceTokenizer()。或者,你可以用RegexSplitTokenizer("your-regex-pattern"),通过正则表达式定制你自己的分词器。CaseFolder随后被用来将每个单词变成小写,这样“The”、“tHE”、“THE”都变成了“the”。CaseFolder通过把所有字符变成小写形式,减少了单词的不同形式。下面,使用WordsAndNumbersOnlyFilter(),纯标点、非单词非数字的字符会从产生的分词后的文档列表中删除。最后,使用MinimumLengthFilter()将短于3个字符的term去除作为可选功能,token可以用 PorterStemmer()在MinimumLengthFilter()之前提取词干。提取词干在信息检索中是一种常用的技术,将比如多元词转化成简单的常用term(“books”和“book”都映射成“book”)。但是,提取词干并不总对话题建模有益,因为有时提取词干会把一些term合并在一起,但是他们最好还是分开,而且同一个单词的变形会变成同一个话题。
(笔者注:对Porter Stemmer有兴趣的话,可以去官网或者其他文章了解其原理)如果你想要去除标准的英语停用词(stop word),可以在分词器的最后一步用StopWordFilter("en")(笔者注:如果使用了这一步,那么这些很常用的停用词都会被过滤掉,在下面的步骤中,被过滤掉的前30个常用单词就很可能是有用单词了)


在一个CSV文件中提取并且分词Extracting and tokenizing text in a CSV file

定义好分词器之后,我们就可以用它从CSV文件中合适的列中提取文本了。如果你的文本数据存在于一列中(这里是第四列):

1.source ~> Column(4) ~> TokenizeWith(tokenizer)以上的代码会加载CSV文件中的第四列文本
如果你的文本不止存在于一列中:

1.source ~> Columns(3,4) ~> Join(" ") ~> TokenizeWith(tokenizer)以上的代码会选择第三和第四列,然后把他们的内容用一个空格连在一起。


寻找有意义的单词(Finding meaningful words)

话题建模对于有意义单词的模式提取(extracting patterns)非常有用,但是在决定什么单词是有意义时并不一定奏效。通常,使用常见的单词比如“the”,并不代表着文档之间的相似性。为了在有意义的单词中提取模式,我们使用一系列的标准启发式算法:

1.... ~>
2.TermCounter ~>
3.TermMinimumDocumentCountFilter(4) ~>
4.TermDynamicStopListFilter(30) ~>
5....
上面的代码去除了在少于四篇文档中出现的term(因为很少见的单词几乎不对文档相似度做出贡献),还有在文本库中最常见的30个单词(因为太普遍的单词同样对文档相似度不做出贡献,他们通常被定义为停用词)。当你在处理很大或者很小(少于几千单词的文档)时,这些值可能需要更新。如果你有一个你想要出去的停用词的详细列表,你可以像这样额外增加一个过程:TermStopListFilter(List("positively","scrumptious")). 这里,在引号的List里添加你需要过滤的单词。记住,TermStopListFilter 运行在文档被分词之后,所以你提供的List要和你的分词器输出保持一致,就是说,如果你的分词器包括了CaseFolder和PorterStemmer,过滤的单词必须也要是小写的和词干。TermCounter步骤首先必须计算下一步骤需要的一些统计。这些数据存储在元数据中,使得任何下游步骤可以使用这些数据。这些步骤也会在硬盘上CSV文件的同一个文件夹下产生缓存文件,以保存文档数据。文件名会以CSV文件的名称开头,并且会包含流水线的标记"term-counts.cache"。

去除空文档(Removing Empty Documents)

数据集中的一些文档可能会丢失或者是空的(一些单词可能在最后一步被过滤掉)。可以通过使用DocumentMinimumLengthFilter(length) 在训练中舍弃一些文档,去除短于特定长度的文档。

组合起来(Putting it all together)

运行example1 (example-1-dataset.scala)。这个程序会首先加载数据流水线,然后打印加载数据集的信息,包括数据集的标志和文本库中的30个停用词。(注意在PubMed,因为“gene”被广泛使用所以被过滤掉了)

学习一个话题模型

这个例子展示了如何用你上面准备的数据集进行LDA训练。
这个例子的代码在example-2-Ida-learn。scala里。


载入数据文件(Load the data file

01.val source = CSVFile("pubmed-oa-subset.csv") ~> IDColumn(1);
02. 
03.val tokenizer = {
04.SimpleEnglishTokenizer() ~>            // tokenize on space and punctuation
05.CaseFolder() ~>                        // lowercase everything
06.WordsAndNumbersOnlyFilter() ~>         // ignore non-words and non-numbers
07.MinimumLengthFilter(3)                 // take terms with >=3 characters
08.}
09. 
10.val text = {
11.source ~>                              // read from the source file
12.Column(4) ~>                           // select column containing text
13.TokenizeWith(tokenizer) ~>             // tokenize with tokenizer above
14.TermCounter() ~>                       // collect counts (needed below)
15.TermMinimumDocumentCountFilter(4) ~>   // filter terms in <4 docs
16.TermDynamicStopListFilter(30) ~>       // filter out 30 most common terms
17.DocumentMinimumLengthFilter(5)         // take only docs with >=5 terms
18.}

这个代码片段和之前的一样,它从示例数据集中提取并且准备了文本。


选择训练LDA模型的参数(Select parameters for training an LDA model

1.// turn the text into a dataset ready to be used with LDA
2.val dataset = LDADataset(text);
3. 
4.// define the model parameters
5.val params = LDAModelParams(numTopics = 30, dataset = dataset);

这里你可以指定一定数量想要学习的topic。你也指定可以指定LDA模型使用的Dirichlet term和 topic smoothing参数,这些参数在第五行作为LDAModelParams额外的参数提供给构造函数。在默认情况下,第五行等价于已经设定了termSmoothing=SymmetricDirichletParams(.1) 和topicSmoothing=SymmetricDirichletParams(.1) 
笔者注:在我下载的脚本中是这样一段代码,val params = LDAModelParams(numTopics = 30, dataset = dataset,topicSmoothing = 0.01, termSmoothing = 0.01); 这样把参数写的更加清晰了

训练符合文档的模型(Train the model to fit the documents)

从0.3版本起,本工具开始支持大多数模型上的多种形式的学习和推理,包括默认支持的多线程训练和多核机器上的推理。特别的,这个模型可以使用collapsed Gibbs sampler [T. L. Griffiths and M. Steyvers. 2004. Finding scientific topics. PNAS, 1:5228–35]或者collapsed variational Bayes approximation to the LDA objective [Asuncion, A., Welling, M., Smyth, P., & Teh, Y. W. (2009)). On Smoothing and Inference for Topic Models. UAI 2009]。


01.// Name of the output model folder to generate
02.val modelPath = file("lda-"+dataset.signature+"-"+params.signature);
03. 
04.// Trains the model: the model (and intermediate models) are written to the
05.// output folder.  If a partially trained model with the same dataset and
06.// parameters exists in that folder, training will be resumed.
07.TrainCVB0LDA(params, dataset, output=modelPath, maxIterations=1000);
08. 
09.// To use the Gibbs sampler for inference, instead use
10.// TrainGibbsLDA(params, dataset, output=modelPath, maxIterations=1500);


该模型会在训练时产生状态信息,并且会把产生的模型写入当前目录的一个文件夹,在这个例子里名称为"lda-59ea15c7-30-75faccf7"。注意,默认情况下,使用CVB0LDA进行训练会使用本地所有可用的内核,而且因为它的收敛速率很快,CVB0LDA比GibbsLDA迭代次数更少,然而GibbsLDA在训练时需要更少的内存。


产生输出文件夹之旅(A tour of the generated output folder)

在这个例子中,产生的模型输出文件夹 lda-59ea15c7-30-75faccf7,包含了分析这个学习过程和把模型从磁盘加载回去所需要的一切。

description.txtA description of the model saved in this folder.对这个模型生成流程的整体描述document-topic-distributions.csvA csv file containing the per-document topic distribution for each document in the dataset.
数据集中每个文档的文档—话题分布[Snapshot]: 00000 - 01000Snapshots of the model during training.训练中的模型快照[Snapshot]/params.txtModel parameters used during training.训练中应用的参数[Snapshot]/tokenizer.txtTokenizer used to tokenize text for use with this model.建模中使用的分词器[Snapshot]/summary.txtHuman readable summary of the topic model, with top-20 terms per topic and how many words instances of each have occurred.
可读的话题模型摘要,包括了每个话的前20个term和产生了多少单词实例[Snapshot]/log-probability-estimate.txtEstimate of the log probability of the dataset at this iteration.[Snapshot]/term-index.txtMapping from terms in the corpus to ID numbers (by line offset).[Snapshot]/topic-term-distributions.csv.gzFor each topic, the probability of each term in that topic.对每个话题,每个term的分布

决定这个模型是否已收敛(Determining if the model has converged)

一种简单的判断模型的训练是否已经收敛的办法,是看计数文件夹中log-probability-estimate.txt.的值。这个文件包含了模型在训练时对数据概率估计的非正式估计。这些数字趋向于形成逐步向下但不会完全停止改变的曲线。如果这些数字看起来还没有稳定下来,你可能需要设定更高的迭代次数。


新文本库的话题模型交互(topic model inference on a new corpus)

在训练中,这个工具在产生的模型文件夹中的 document-topic-distributions.csv中记录了每个训练文档的话题分布。模型训练之后,它可以用来分析另外一个可能更大的文本,这个过程称作推理。这个教程展示了如何在一个新的数据集中用已经存在的话题模型中进行推理。这个例子的代码在example-3-Ida-infer.scala中

载入训练好的LDA模型

1.// the path of the model to load
2.val modelPath = file("lda-59ea15c7-30-75faccf7");
3. 
4.println("Loading "+modelPath);
5.val model = LoadCVB0LDA(modelPath);
6.// Or, for a Gibbs model, use:
7.// val model = LoadGibbsLDA(modelPath);

这里我们再次载入上个例子中训练好的模型。
笔者注:模型生成的文件夹名字可能和例子中不同,在这里载入的文件名(例子中的lda-59ea15c7-30-75faccf7)要改成自己硬盘里文件夹的名字。

载入新的数据集进行推理(Load the new dataset for inference)

01.// A new dataset for inference.  (Here we use the same dataset
02.// that we trained against, but this file could be something new.)
03.val source = CSVFile("pubmed-oa-subset.csv") ~> IDColumn(1);
04. 
05.val text = {
06.source ~>                              // read from the source file
07.Column(4) ~>                           // select column containing text
08.TokenizeWith(model.tokenizer.get)      // tokenize with existing model's tokenizer
09.}
10. 
11.// Base name of output files to generate
12.val output = file(modelPath, source.meta[java.io.File].getName.replaceAll(".csv",""));
13. 
14.// turn the text into a dataset ready to be used with LDA
15.val dataset = LDADataset(text, termIndex = model.termIndex);


这里我们准备了一个新的数据集,用已载入模型的原始分词器进行了分词。注意:在这个特别的例子中,我们实际上使用的是之前训练的同样的文件。在实际使用中,推理的CSV文件将是磁盘中的其他文件。
我们还创建了输出路径的文件名,下面输出的文件将出现在模型文件夹里,这些文件名将以推理的数据集名字开头。

在潜在的话题上推测每个文档的分布(Infer per-document distributions over latent topic)

1.println("Writing document distributions to "+output+"-document-topic-distributions.csv");
2.val perDocTopicDistributions = InferCVB0DocumentTopicDistributions(model, dataset);
3.CSVFile(output+"-document-topic-distributuions.csv").write(perDocTopicDistributions);
4. 
5.println("Writing topic usage to "+output+"-usage.csv");
6.val usage = QueryTopicUsage(model, dataset, perDocTopicDistributions);
7.CSVFile(output+"-usage.csv").write(usage)

我们对推理数据集中的每个文档的话题分布进行推测,这些分布会写入模型文件夹中的一个新CSV文件。我们也会写入一个文件,其中包含了在推测数据集中,每个话题被使用的频率。

在潜在话题上推测每个单词的分布(Infer per-word distributions over latent topics)

.println("Estimating per-doc per-word topic distributions");
2.val perDocWordTopicDistributions = EstimatePerWordTopicDistributions(
3.model, dataset, perDocTopicDistributions);
4. 
5.println("Writing top terms to "+output+"-top-terms.csv");
6.val topTerms = QueryTopTerms(model, dataset, perDocWordTopicDistributions, numTopTerms=50);
7.CSVFile(output+"-top-terms.csv").write(topTerms);

因为和已经产生训练模型的数据集不同,我们希望以不同于话题在训练中被使用的方式,推理数据集可以充分利用已经学习好的话题。这个工具可以产生数据集中每个话题的top-k个term。这里我们把这top-k个term放入-top-terms.csv。这个文件会和summary.txt文件中的输出结果或者在训练的数据集上的推理进行比较。

将话题模型分片(Slicing a topic model's output)

文档通常和特定的元数据相关联,比如文档创建的年份,它的数据源、作者等。在这篇教程中,我们展示了是如何用TMT来检查在数据切片中一个话题是如何使用的,切片是指和一个或多个绝对变量相关联的子集。

这个例子的代码在example-4-Ida-slice.scala中


载入训练好的LDA模型(Load the trained LDA model)

1.// the path of the model to load
2.val modelPath = file("lda-59ea15c7-30-75faccf7");
3. 
4.println("Loading "+modelPath);
5.val model = LoadCVB0LDA(modelPath);
6.// Or, for a Gibbs model, use:
7.// val model = LoadGibbsLDA(modelPath);

像以前一样,我们又从硬盘中载入一个模型

准备数据集(Prepare the dataset)

01.// A dataset for inference; here we use the training dataset
02.val source = CSVFile("pubmed-oa-subset.csv") ~> IDColumn(1);
03. 
04.val text = {
05.source ~>                              // read from the source file
06.Column(4) ~>                           // select column containing text
07.TokenizeWith(model.tokenizer.get)      // tokenize with existing model's tokenizer
08.}
09. 
10.// turn the text into a dataset ready to be used with LDA
11.val dataset = LDADataset(text, termIndex = model.termIndex);

这里,我们重新载入训练用的同样的数据集,当然也可以用不同的数据集

选择用于切片的列变量(Select column variables for slicing)

1.// define fields from the dataset we are going to slice against
2.val slice = source ~> Column(2);
3.// could be multiple columns with: source ~> Columns(2,7,8)

在这个例子中,每个文档被创建的年份存储在第2列中,我们将用年份作为分隔数据集的绝对变量。如果你希望用多个绝对变量来切片,你可以用Columns

载入或者推测文档-话题分布(Load or infer per-document topic distributions)

1.println("Loading document distributions");
2.val perDocTopicDistributions = LoadLDADocumentTopicDistributions(
3.CSVFile(modelPath,"document-topic-distributions.csv"));
4.// This could be InferCVB0DocumentTopicDistributions(model, dataset)
5.// for a new inference dataset.  Here we load the training output

上面的代码载入了训练中产生的文档-话题分布,如果你用另一个数据集进行推测,你可能需要用InferCVB0DocumentTopicDistributions代替LoadLDADocumentTopicDistributions,或者从另一个路径载入。

将LDA队列输出切片(Slicing the LDA query output)

01.println("Writing topic usage to "+output+"-sliced-usage.csv");
02.val usage = QueryTopicUsage(model, dataset, perDocTopicDistributions, grouping=slice);
03.CSVFile(output+"-sliced-usage.csv").write(usage);
04. 
05.println("Estimating per-doc per-word topic distributions");
06.val perDocWordTopicDistributions = EstimatePerWordTopicDistributions(
07.model, dataset, perDocTopicDistributions);
08. 
09.println("Writing top terms to "+output+"-sliced-top-terms.csv");
10.val topTerms = QueryTopTerms(model, dataset, perDocWordTopicDistributions, numTopTerms=50, grouping=slice);
11.CSVFile(output+"-sliced-top-terms.csv").write(usage);


这里我们通过对数据集分片产生了每个话题的(usage)。像之前例子中的QueryTopicUsage,我们在模型中查找关联与每个话题有多少文档(部分)和多少单词。但是,产生的CSV文件会包含破坏话题分组的额外的列。在之后的教程中,我们会在Excel中分析这样的输出,对应出随着时间推移每个话题的使用情况。

我们还生成了每个组中每个话题关联的排名靠前的单词。产生的-sliced-top-terms.csv文件可以用来分析是否话题一直在子群中(sub-groups)被使用。

在Excel中分析话题模型输出(Analyzing topic model outputs in Excel)

之前产生的CSV文件可以直接导入Excel中进一步分析,以便于理解、绘图和处理话题模型的输出。如果结果似乎并无意义,你可能需要尝试其他的模型参数。


以下的截图是基于0.1.2版本的输出结果。至于0.3版本,每个输出结果文件包括一个“文档”(Documents)列和一个“单词”(Words)列。前者包含了在每个切片中与每个话题相关的文档总数,后者包含了每个切片中与每个话题相关的单词总数。要注意的是,两个数字都是小数的,因为LDA并不是把文库(corpus)中的每个单词分配给单独的一个话题,而是在所有话题上的分布。


选择模型参数(Selecting model parameters)

本文描述了如何选择模型参数,比如tuning过程(密集的计算)产生话题的数量,以便找到合适的参数使模型perplexity最小。

这个案例的代码是example-5-lda-select.scala

这个脚本将文档分成两部分,一部分用来训练模型,另一部分用来评估不可见数据(unseen data)的混乱度(perplexity)。

评价文档的混乱度首先要把文档分成两部分。每个文档的话题分布由单词的第一部分推测,然后工具箱用第二部分计算这一分布“意外”程度( how surprised it was)的一个平均值,意外由等概率单词选择的数量计算而来。这个值被写入控制台,数值越小意味着模型越可靠。

混乱度得分不可用于比较文库,因为他们很容易被不同的单词量影响。但是他们可以用来在相同的数据集上比较训练的模型(比如示例脚本)。但是要清楚,有更好混乱度得分的模型并不总是产生更易懂的话题或者更适合特别任务的话题。由于没有更好的方案,混乱度得分被用作在选择中挑选的稳定措施。通常,我们希望随着话题数量的增多,混乱度得分会下降,但是混乱度的不断下降幅度会越来越小。一个好的经验法则是,挑选产生一些产生合理输出的话题(通过检查summary.txt),然后混乱度会开始下降

一些非参数话题模型在自己的话题训练过程中可以自动选择话题数量。但是这些模型(比如 Hierarchical Dirichlet Process)目前还没有用在工具箱里。即使在这些模型中,一些参数也必须调整,比如话题平滑和词项平滑参数。

训练一个带标签LDA模型(Training a Labeled LDA model)

Labeled LDA is a supervised topic model for credit attribution in multi-labeled corpora [pdf, bib]. If one of the columns in your input text file contains labels or tags that apply to the document, you can use Labeled LDA to discover which parts of each document go with each label, and to learn accurate models of the words best associated with each label globally.

带标签的LDA是一个对于多标签可信属性文库的有监督话题模型。如果在你输入的文件中,一列包含了适用于此文档的标签或者标记,你就可以用带标记的LDA发现文档的某个部分属于哪个标记,还可以学习单词联系最紧密的标记的精确的模型。

这个案例的代码是example-6-llda-learn.scala。

这个案例和训练一个常规的LDA模型非常相似,除了少数改变。首先,要指定一个带标签LDA数据集,我们需要告诉工具箱文本和标签从哪儿来。通常,带标签的LDA只有当每个文档包含一个以上标签时才有用(否则这个模型等价于朴素贝叶斯)。但是在例子中,我们会用“year”列作为标签。要注意,因为每个文档只有一个year,这个模型实际上在训练一次迭代之后就会收敛,但是这个案例是为了工作于在一个源文件中一列包含多个标签或者标记、空间分隔。

01.val source = CSVFile("pubmed-oa-subset.csv") ~> IDColumn(1);
02. 
03.val tokenizer = {
04.SimpleEnglishTokenizer() ~>            // tokenize on space and punctuation
05.CaseFolder() ~>                        // lowercase everything
06.WordsAndNumbersOnlyFilter() ~>         // ignore non-words and non-numbers
07.MinimumLengthFilter(3)                 // take terms with >=3 characters
08.}
09. 
10.val text = {
11.source ~>                              // read from the source file
12.Column(4) ~>                           // select column containing text
13.TokenizeWith(tokenizer) ~>             // tokenize with tokenizer above
14.TermCounter() ~>                       // collect counts (needed below)
15.TermMinimumDocumentCountFilter(4) ~>   // filter terms in <4 docs
16.TermDynamicStopListFilter(30) ~>       // filter out 30 most common terms
17.DocumentMinimumLengthFilter(5)         // take only docs with >=5 terms
18.}
19. 
20.// define fields from the dataset we are going to slice against
21.val labels = {
22.source ~>                              // read from the source file
23.Column(2) ~>                           // take column two, the year
24.TokenizeWith(WhitespaceTokenizer()) ~> // turns label field into an array
25.TermCounter() ~>                       // collect label counts
26.TermMinimumDocumentCountFilter(10)     // filter labels in < 10 docs
27.}
28. 
29.val dataset = LabeledLDADataset(text, labels);


标记LDA假设每个文档只能用标签集中有名字的话题。这里每个文档只参与了一个标签(year)。Year并不是特别有趣的标签(比如相比于包含了多个描述不同文章标记的域),但是在这个例子中已经足够了。

训练一个GibbsLabeledLDA或者CVB0LabeledLDA模型类似于训练一个LDA模型。

01.// define the model parameters
02.val modelParams = LabeledLDAModelParams(dataset);
03. 
04.// Name of the output model folder to generate
05.val modelPath = file("llda-cvb0-"+dataset.signature+"-"+modelParams.signature);
06. 
07.// Trains the model, writing to the givne output path
08.TrainCVB0LabeledLDA(modelParams, dataset, output = modelPath, maxIterations = 1000);
09.// or could use TrainGibbsLabeledLDA(modelParams, dataset, output = modelPath, maxIterations = 1500);

The LabeledLDA model can be used analogously to an LDA model by adapting the previous examples to the labeled setting, as appropriate.

训练一个PLDA模型(Training a PLDA model)

Partially Labeled Dirchlet Allocation (PLDA) [paper] is a topic model that extends and generalizes both LDA and Labeled LDA. The model is analogous to Labeled LDA except that it allows more than one latent topic per label and a set of background labels. Learning and inference in the model is much like the example above for Labeled LDA, but you must additionally specify the number of topics associated with each label.

部分标签 Dirchlet 分布(PLDA)是一个扩展并且概括了LDA和带标签LDA的话题模型。这个模型类似于带标签LDA,除了它允许每个标签含有一个以上的潜在话题和一系列背景标签。这个模型的学习并且推测更像上面的带标签LDA,但是你必须额外的指定每个标签相关的话题数量。

这个例子的代码是example-7-plda-learn.scala



0 0
原创粉丝点击