Gensim
是一款开源的工具包,用于从原始的非结构化的文本,无监督的学习到文本隐层的主题向量表达。
支持TF-IDF、LSA、LDA、Word2Vec
等多种主题模型算法。
支持流式训练 ,提供了相似度计算,信息检索等常用任务的API
接口。
基本概念
- 语料:原始文本集合,用于无监督的训练文本主题的隐层结构。语料中不用 人工标注 附加信息。在
Gensim
中,Corpus
通常是一个可迭代的对象,每一次迭代返回一个用于表达文本对象的 稀疏向量 。 - 向量:由一组文本特征构成的列表。
- 稀疏向量:通常可以忽略向量中多余的0元素。此时向量中的每一个元素是一个(key,value)的元组。
- 模型:定义了两个向量空间的变换(从文本的一种向量表达变换为另一种向量表达)。
预处理
预处理将文档中原始的字符文本转换成
Gensim
模型能理解的稀疏向量的过程。
本次操作是词袋模型doc2bow
。
- 在
Gensim
模型训练前,将原生字符解析成Gensim
能处理的稀疏向量的格式。 - 对原始文本进行 分词、去停用词、等 ,得到文档的特征列表。
In [71]: from gensim import corpora
In [72]: texts = [['今天','我', '好好', '学习'],['天天', '向上', '学习', '知识']]
In [73]: dictionary = corpora.Dictionary(text)
# dictionary.save('dict.dict') # 将字典保存
In [74]: corpus = [dictionary.doc2bow(i) for i in texts ]
# corpora.MmCorpus.serialize('deerwester.mm', corpus)
In [75]: corpus[0]
Out[75]: [(0, 1), (1, 1), (2, 1), (3, 1)]
In [76]: corpus[1]
Out[76]: [(2, 1), (4, 1), (5, 1), (6, 1)]
- 这里得到语料对应的稀疏向量这里是 词袋 (Bag of Words, BOW)向量和顺序没关系。
- 向量中每个元素代表一个
word
在文档中出现的次数。 - 可以将列表封装为一个
Python
迭代器,每次迭代返回一个稀疏向量。
class MyCorpus(object):
def __iter__(self):
for line in open('corpus.txt'):
yield dictionary.doc2bow(line.lower().split())
主题向量的变换
通过挖掘预料中蕴藏的语义结构特征,最终变换出一个简洁高效的文本向量。
本次模型为TF-IDF
模型。
注意: gensim
模型都要接受训练预料(在Gensim中,预料对应着稀疏向量的迭代器)作为初始化参数,模型越复杂配置参数越多。
In [80]: from gensim.models import TfidfModel
In [81]: tfidf = TfidfModel(corpus)
- corpus:是返回
bow
向量的迭代器。 - 81行:将完成对
corpus
中出现每一个特征的IDF
值的统计工作。
In [82]: doc_bow = [(0,1),(1,1)]
In [83]: tfidf[doc_bow]
Out[83]: [(0, 0.7071067811865475), (1, 0.7071067811865475)]
In [95]: corpus_tfidf = tfidf[corpus] # 对所有语料生成tfidf
In [96]: corpus_tfidf.save('./model.tfidf') # 将模型持久化
In [97]: tfidf = models.TfidfModel.load("./model.tfidf") # 加载模型
- 82行:调用模型将一段语料(向量)转换成
TFIDF
向量。 - 这里的
bow
向量必须与训练预料的bow
向量共享同一个特征字典(共享同一个向量空间)。 Gensim
内置许多主题模型的向量变换,但是这些模型通常以bow
向量或tfidf
向量的预料为输入,生成相应的主题向量。所有的模型支持 流式计算 。
文档相似度计算
在得到每篇文档对应的主题向量后,就能计算文档之间的相似度,来完成文本聚类,信息检索的任务。
In [101]: from gensim import similarities
In [102]: import jieba
In [103]: word = '我今天要好好学习'
In [104]: bow = dictionary.doc2bow([word for word in jieba.cut(word)])
Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/07/pdf9kv9n5cj6mnyn0jf_m7vr0000gn/T/jieba.cache
Loading model cost 0.843 seconds.
Prefix dict has been built succesfully.
In [105]: word_tfidf = tfidf[bow] # 分词后的词在同一个向量空间。
In [106]: word_tfidf
Out[106]: [(0, 0.7071067811865475), (3, 0.7071067811865475)]
In [108]: index = similarities.MatrixSimilarity(corpus_tfidf) # 将所有的词做成索引
/Users/hubo/code/.venv/lib/python3.6/site-packages/gensim/matutils.py:737: FutureWarning: Conversion of the second argument of issubdtype from `int` to `np.signedinteger` is deprecated. In future, it will be treated as `np.int64 == np.dtype(int).type`.
if np.issubdtype(vec.dtype, np.int):
In [109]: sims = index[word_tfidf] # 利用索引计算相似度
In [110]: sims
Out[110]: array([0.81649655, 0. ], dtype=float32)
LDA文档主题生成模型
LDA
是一种文档主题生成模型,包含词、主题、文档三层结构。
是一种非监督机器学习技术,用来识别大规模文档集或语料库中潜藏的主题信息。
所谓生成模型,就是说,认为一篇文章的每个词都是通过“一定概率选择某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到。
- 文档到主题服从多项式分布
- 主题到词服从多项式分布
采用了词袋的方法,这种方法将每一篇文档视为一个词频向量,从而将文本信息转换为易于建模的数字信息。
注意: 词袋模型没有考虑 词与词 之间的顺序,简化了问题的复杂性,每篇文档代表一些主题所构成的一个概率分布,每个主题又代表很多单词所构成的一个概率分布。