欢迎加入学习交流QQ群:657341423
Gensim是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。它支持包括TF-IDF,LSA,LDA,和word2vec在内的多种主题模型算法,支持流式训练,并提供了诸如相似度计算,信息检索等一些常用任务的API接口。
简单地说,Gensim主要处理文本数据,对文本数据进行建模挖掘。
语料(Corpus):一组原始文本的集合,用于无监督地训练文本主题的隐层结构。语料中不需要人工标注的附加信息。在Gensim中,Corpus通常是一个可迭代的对象(比如列表)。每一次迭代返回一个可用于表达文本对象的稀疏向量。
向量(Vector):由一组文本特征构成的列表。是一段文本在Gensim中的内部表达。
稀疏向量(Sparse Vector):通常,我们可以略去向量中多余的0元素。此时,向量中的每一个元素是一个(key, value)的tuple。
模型(Model):是一个抽象的术语。定义了两个向量空间的变换(即从文本的一种向量表达变换为另一种向量表达)。
文件准备:
aa.txt。文件内容为某新闻报道
from gensim import corpora, models, similarities
import jieba
import re
from snownlp import SnowNLP
# 读取文本内容
f = open('aa.txt','r',encoding='utf-8')
text = f.read()
f.close()
# 分句
s = SnowNLP(text)
text_list = s.sentences
seg_list = []
# 循环句子列表,对每个句子做分词处理
for i in text_list:
temp_list = jieba.cut(i,cut_all=False)
results = re.sub('[()::?“”《》,。!()·、.\d ]+', ' ', ' '.join(temp_list))
seg_list.append(results)
# 将分词写入文件
f = open('data.txt','w',encoding='utf-8')
f.write(' '.join(seg_list))
f.close()
#…………………我是分割线………………………#
# **********字典的使用**********
# gensim的字典是将分词好的数据转换成gensim能处理的数据格式
seg_dict = [x.split(' ') for x in seg_list]
dict1 = corpora.Dictionary(seg_dict,prune_at=2000000)
print(dict1.token2id)
# 手动添加字典
dict2 = corpora.Dictionary()
dict2.token2id = {'computer': 0, 'human': 1, 'response': 2, 'survey': 3}
print(dict2.token2id)
# 合并字典
dict2 = corpora.Dictionary(seg_dict,prune_at=2000000)
dict2_to_dict1 = dict1.merge_with(dict2)
# 获取字典中某词语的词袋向量
new_doc = '生态环境 政府 非法'
new_vec = dict1.doc2bow(new_doc.split())
print(new_vec) # [(14, 1), (22, 1), (66, 1)] -> 14代表生态环境在字典dict1的ID,1代表出现次数
# 获取整个dict1的词袋向量
bow_corpus = [dict1.doc2bow(text) for text in seg_dict]
print(bow_corpus)
# **********字典的使用**********
#…………………我是分割线………………………#
#…………………我是分割线………………………#
# **********模型的使用**********
# 模型对象的初始化,实现词向量化
tfidf = models.TfidfModel(bow_corpus)
# 计算new_vec的权重
string_tfidf = tfidf[new_vec]
print(string_tfidf)
# 基于Tf-Idf计算相似度,参考https://radimrehurek.com/gensim/tutorial.html
index = similarities.SparseMatrixSimilarity(bow_corpus, num_features=10)
sims = index[string_tfidf]
print(sims) # 输出[(14, 0.5862218816946012), (22, 0.4809979876921243), (66, 0.6519086141926397)]
# 14代表生态环境在字典dict1的ID,0.5862218816946012代表相似性分数
# ****建模****
# 参考https://radimrehurek.com/gensim/tut2.html
# LSI建模,models.LsiModel(corpus=tfidf[bow_corpus], id2word=dict1, num_topics=50, chunksize=10000)
# HDP建模,models.HdpModel(corpus=tfidf[bow_corpus], id2word=dict1,chunksize=10000)
# RP建模,models.RpModel(corpus=tfidf[bow_corpus], id2word=dict1, num_topics=50)
lda = models.LdaModel(corpus=tfidf[bow_corpus], id2word=dict1, num_topics=50, update_every=1, chunksize=10000, passes=1)
for i in range(0, 3):
print(lda.print_topics(i)[0])
# 利用模型获取文档的主题概率分布
doc_lda = lda[new_vec]
print(doc_lda)
# 根据模型计算相似度
# 参考https://radimrehurek.com/gensim/tut3.html
index = similarities.MatrixSimilarity(bow_corpus)
sims = index[new_vec]
print(list(enumerate(sims)))
# ****建模****
# **********模型的使用**********
#…………………我是分割线………………………#
#…………………我是分割线………………………#
# **********word2vec的使用**********
# 通过word2vec的“skip-gram和CBOW模型”生成深度学习的单词向量
# 读取已分词的文件
sentences = models.word2vec.LineSentence('data.txt')
# 建立模型,实现词向量化,第一个参数是训练语料,min_count是小于该数的单词会被踢出,默认值为5;size是神经网络的隐藏层单元数,在保存的model.txt中会显示size维的向量值。默认是100。默认window=5
model = models.word2vec.Word2Vec(sentences, size=100, window=25, min_count=5, workers=4)
# 根据语料,计算某个词的相关词列表
sim = model.wv.most_similar('生态环境', topn=10)
# 计算一个词d(或者词表),使得该词的向量v(d)与v(a="政府")-v(c="生态环境")+v(b="街道")最近
# sim = model.most_similar(positive=['政府','街道'],negative=['生态环境'], topn=10)
for s in sim:
print("word:%s,similar:%s " %(s[0],s[1]))
# 根据语料,计算两个词的相似度 / 相关程度
print(str(model.similarity('政府','生态环境')))
# 计算文本的相似度
similarity_matrix = model.wv.similarity_matrix(dict1)
# MatrixSimilarity:指数相似性(密集与余弦距离)。
# SparseMatrixSimilarity:索引相似度(带余弦距离的稀疏)。
# SoftCosineSimilarity:指数相似性(具有软余弦距离)。
# WmdSimilarity:索引相似度(与字移动距离)。
index = similarities.SoftCosineSimilarity(bow_corpus, similarity_matrix, num_best=10)
sims = index[dict1.doc2bow(new_doc.split())]
print(sims)
# 保存模型方法一
model.save("test_01.model")
# 保存模型方法二
# model.wv.save_word2vec_format("test_01.model.bin",binary=True)
# model= models.KeyedVectors.load_word2vec_format("test_01.model.bin", binary=True)
# **********word2vec的使用**********
#…………………我是分割线………………………#
参考资料:官方文档