自然语言处理之主题模型(四)

2,400 阅读3分钟

本文主要参考 Coursera上的 Natural Language Processing 课程。

简介

主题模型是另一种理解语义(提取文章的主题、构建文章的向量表示)的方式。

主题模型的简要理解如下:

  1. 我们想得到文章的一些向量表示;
  2. 文章可以被一些 主题 描述;
  3. 主题 由一些 描述。

比如,天气这个主题,可以被 天空、雨、晴、太阳等词描述。

如下图所示:

常见用途

  1. 文本分类(按主题)
  2. 新闻流的聚合和分析
  3. 推荐系统(找到相似主题的文章)

LDA

LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,包含 主题文档 三层结构。

本文不在讲述关于 LDA 模型的各种数学理论了,有意了解的同学请参考以下链接LDA数学八卦

gensim 模块提供了对于 lda模型的实现,在生产环境直接使用即可。

使用该模型的几个注意点:

Dictionary

gensim 的 lda模型 需要传入一个 Dictionary 实例或者 id->word 的映射,这里推荐使用 Dictionary 的实例,因为 gensim 的 Dictionary 实例提供了许多有用的方法。

比如:

  • 通过 id 得到 token;
  • 通过 token 得到 id;
  • 获取文档的 bow 形式表示(与之前文章中讲的 BoW 相似,但是不完全相同);
  • 保存和加载字典文件。

这个类的 example 如下:

>>> from gensim.corpora import Dictionary
>>>
>>> texts = [['human', 'interface', 'computer']]
>>> dct = Dictionary(texts)  # initialize a Dictionary
>>> dct.add_documents([["cat", "say", "meow"], ["dog"]])  # add more document (extend the vocabulary)
>>> dct.token2id
{'computer': 0, 'human': 1, 'interface': 2, 'cat': 3, 'meow': 4, 'say': 5, 'dog': 6}
>>> dct.doc2bow(["dog", "computer", "non_existent_word", "dog"]) # 第一个值表示 id,第二个值表示出现的次数
[(0, 1), (6, 2)]

但是直接使用该类处理中文文本会存在很多问题,有一些 停止词低频词 我们并不希望在bow表示中存在,这个时候就需要在分完词后自己进行相关处理之后在调用该方法生成字典。

其实在仔细看这个模型,我们发现,在slearn中有一个非常相似的类可以用来帮助我们处理一些像是 停止词低频词 等内容,sklearn 中这个类叫做 CountVectorizer

CountVectorizer 的 example 如下:

>>> from sklearn.feature_extraction.text import CountVectorizer
>>> corpus = [
...     'This is the first document.',
...     'This document is the second document.',
...     'And this is the third one.',
...     'Is this the first document?',
... ]
>>> vectorizer = CountVectorizer()
>>> X = vectorizer.fit_transform(corpus)
>>> print(vectorizer.get_feature_names())
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
>>> print(X.toarray())  
[[0 1 1 1 0 0 1 0 1]
 [0 2 0 1 0 1 1 0 1]
 [1 0 0 1 1 0 1 1 1]
 [0 1 1 1 0 0 1 0 1]]

这个类有一些参数,可以自动帮我们去除 停止词高频词低频词 等内容。

结合这两个类,我们可以将 原始文本通过 jiaba 分词当做 CountVectorizer 的输入;等待训练好之后使用该类的 build_tokenizer 方法得到可以将文本拆分成 token 序列的函数;然后使用该函数对原始文本进行再次处理,得到token序列并输入 gensim 的 Dictionary 即可。

gensim lda

当通过以上的方式,得到 Dictionary 实例之后,仅需要将原始文本传入该实例的 doc2bow 方法得到相应的 bow 表示,然后在传入 lda 模型就可以进行训练了。

等到训练结束后,就可以自由的探索这个模型啦!

evaluation

对训练好的 gensim lda 模型该怎么评估呢?

perplexity 是nlp中常用的一种模型评估的方式,参考链接如下:blog.csdn.net/index20001/…

通过模型提供的 log_perplexity 方法可以得到一个分数,perplexity 越低代表模型效果越好。

总结

本文简要的说明了以下主题模型的作用和gensim 的 lda 模型的训练及其评估方式,更多的内容还需要读者自行去挖掘。