参照的是官方文档
核心概念
Document:一些文本。In Gensim, a document is an object of the text sequence type (commonly known as str in Python 3).
Corpus(语料库):Document的集合。Corpus是Document的集合。Corpus在Gensim中有两个作用:
用于训练模型的输入。在训练过程中,模型使用这个训练Corpus寻找共同的themes and topics,初始化它们的内部模型参数。
Gensim专注于无监督模型,因此不需要人工干预,比如昂贵的注释或手工标记文档。训练结束后,可以使用主题模型从新文档(训练语料库中没有看到的文档)中提取主题。
Vector(向量):在数学上方便的Document表示。
为了推断语料库中的潜在结构,我们需要一种方法来表示我们可以数学处理的文档。一种方法是将每个文档表示为特征向量。例如,一个单一的特性可以被认为是一对问题-答案:
单词splonge在文档中出现了多少次?零。
这个文件由多少段组成?两个。
文档使用了多少种字体?五个
这个问题通常只由它的整数id表示(例如1、2和3)。然后,这个文档的表示就变成了一系列对,如(1,0.0)、(2,2.0)、(3,5.0)。这就是所谓的稠密向量,因为它包含了上述每个问题的明确答案。
如果我们事先知道所有的问题,我们可以隐式地将它们表示为(0,2,5)。这个答案序列就是我们的文档的向量(在本例中是一个三维密度向量)。出于实际目的,Gensim中只允许答案为(或可以转换为)单个浮点数的问题。
实际上,向量通常由许多零值组成。为了节省内存,Gensim省略了所有值为0.0的向量元素。因此,上面的示例变为(2,2.0),(3,5.0)。这就是所谓的稀疏向量或词袋向量。在这个稀疏表示中,所有缺失的特性的值都可以明确地解析为0,0.0。
假设问题是相同的,我们可以比较两个不同文档的向量。例如,假设我们已知两个向量(0.0,2.0,5.0)和(0.1,1.9,4.9)。因为这些向量彼此非常相似,我们可以得出结论,与这些向量对应的文档也很相似。当然,这个结论的正确性取决于我们一开始选择问题的好坏。
另一种将文档表示为向量的方法是词袋模型。在词袋模型下,每个文档由一个向量表示,该向量包含字典中每个单词的频率计数。例如,假设我们有一个包含单词['coffee', 'milk', 'sugar', 'spoon']的词典。由字符串“coffee milk coffee”组成的文档将由向量[2,1,0,0]表示,其中向量的条目(按顺序)是“coffee”、“milk”、“sugar”和“spoon”在文档中的出现。向量的长度是字典中条目的数量。单词袋模型的一个主要属性是,它完全忽略被编码的文档中标记的顺序,这就是名称单词袋的来源。
doc2bow方法:转为一个稀疏的词袋模型
Model(模型):将Vector从一种表示形式转换为另一种表示形式的算法。
既然我们已经对语料库进行了向量化,我们就可以开始使用模型对其进行转换。我们使用模型作为一个抽象术语,表示从一种文档表示到另一种文档表示的转换。在gensim文档被表示为向量,因此模型可以被认为是两个向量空间之间的转换。当模型读取训练语料库时,它在训练过程中学习这个转换的细节。
一个简单的模型例子是tf-idf。tf-idf模型将向量从词袋表示转换为向量空间,在向量空间中,根据语料库中每个词的相对稀少度对频率计数进行加权。
LDA
以下英文文本处理为例,中文处理需要找一些中文分词库(结巴分词
英文文本数据预处理
目前用到的库:nltk. 官方文档 NLTK :: Natural Language Toolkit
-
检查拼写是否错误,错了就丢掉,用python的一些检查单词正确性的库,比如enchant库
-
组合一些关键词,防止分词的时候被切开
#可以用到MWETokenizer tokenizer_mww = MWETokenizer(key_tuple_lst, separator=" ")
-
抽取词干,删除较常见的词法和不固定词尾
from nltk.stem.porter import PorterStemmer
-
引入停用词,就是一些超级常用动词us、we之类的,其实就是一个列表,可以按自己项目增加一些停用词
from nltk.corpus import stopwords #nltk库 这是一个自然语言处理工具包 stop_words = stopwords.words('english') #使用这个库自带的英文停用词 stop_words.extend(['from', 'use', 'present', 'play', 'can','find','design'])
-
都转为小写格式(不然小写大写格式会当成两个单词
-
去除特殊符号、空格、html标签,用正则表达式,nltk里有很多文本处理器可以用
from nltk.tokenize import RegexpTokenizer tokenizer = RegexpTokenizer(r'\w+') #raw是原始文本 tokens = tokenizer.tokenize(raw)
-
LDA模型
处理完文本后就用模型了
使用的python库是gensim:models.ldamodel – Latent Dirichlet Allocation — gensim
这个库下面LDA的工作过程大致如下
#把原始文本列表传进去变成一个字典,其实就是对一段文本分词后,给各个词一个id,并且记录词频
common_dictionary = Dictionary(common_texts)
#生成一个语料库,将每个句子样本表示成向量
common_corpus = [common_dictionary.doc2bow(text) for text in common_texts]
#将语料库传到模型里训练,结果是生成10个主题
lda = LdaModel(common_corpus, num_topics=10)
#passes是遍历语料库的次数,一般次数越多越好
#num_topics生成几个主题
ldamodel = gensim.models.ldamodel.LdaModel(common_corpus, num_topics=, id2word=common_dictionary, passes=20)
#这就是输出5个主题,以及各主题下5个关键词
print(ldamodel.print_topics(num_topics=5,num_words=5))
输出的东西如下,就是主题编号+这个主题下高频关键词
[(0, '0.035*"agent" + 0.034*"social" + 0.021*"interact" + 0.016*"behavior" + 0.014*"system"'), (1, '0.034*"social" + 0.021*"link" + 0.020*"network" + 0.013*"internet" + 0.013*"firm"'), (2, '0.028*"interact" + 0.024*"human" + 0.019*"user" + 0.018*"learn" + 0.017*"social"'), (3, '0.041*"social network" + 0.039*"network" + 0.021*"inform" + 0.019*"system" + 0.015*"data"'), (4, '0.031*"social network" + 0.030*"social" + 0.029*"system" + 0.022*"inform" + 0.021*"paper"')]
from gensim.models import CoherenceModel
coherence_model_lda = CoherenceModel(model=ldamodel, texts=处理过的文本列表,corpus=处理过的文本列表转化为词袋模型格式,dictionary=dictionary, coherence='c_v')
coherence_lda = coherence_model_lda.get_coherence()
print('\nCoherence Score: ', coherence_lda) # 越高越好
关于LDA模型的评价
用的比较多的是conference
LDA模型的可视化Python库:pyLDAvis
模型训练好就对其进行可视化
import pyLDAvis.gensim_models
# 用pyLDAvis将LDA模式可视化
plot = pyLDAvis.gensim_models.prepare(ldamodel, bow_corpus, dictionary)
# 保存到本地html
pyLDAvis.save_html(plot, 'pyLDAvis.html')
如果λ接近1,那么在该主题下更频繁出现的词,跟主题更相关; 如果λ越接近0,那么该主题下更特殊、更独有的词,跟主题更相关
右上角有个λ可以调
右边浅蓝色的条表示这个词在整个文档中出现的频率(权重),深红色的条表示这个词在这个主题中所占的权重。
图上左手边的每个气泡代表一个话题。气泡越大,该主题就越盛行。根据经验,一个好的主题模型会有大的、不重叠的气泡。