gensim库的基本使用
简单预处理
说明:将英文文本进行分词操作,并使用tf或者tfidf构建词袋模型
from gensim.utils import simple_preprocess
from gensim.parsing.preprocessing import STOPWORDS
from gensim import corpora
# 简单预处理
doc = "This is a sample document showing how preprocessing works in Gensim."
tokens = simple_preprocess(doc)
print(tokens) # ['sample', 'document', 'showing', 'how', 'preprocessing', 'works', 'gensim']
# 移除停用词
tokens = [token for token in tokens if token not in STOPWORDS]
print(tokens) # ['sample', 'document', 'showing', 'preprocessing', 'works', 'gensim']
documents = [
"Human machine interface for lab abc computer applications",
"A survey of user opinion of computer system response time",
"The EPS user interface management system",
"System and human system engineering testing of EPS",
"Relation of user perceived response time to error measurement",
"The generation of random binary unordered trees",
"The intersection graph of paths in trees",
"Graph minors IV Widths of trees and well quasi ordering",
"Graph minors A survey"
]
# 预处理文档
texts = [[word for word in document.lower().split() if word not in STOPWORDS]
for document in documents]
# 创建词典
dictionary = corpora.Dictionary(texts)
print(dictionary.token2id)
# {'human': 0, 'interface': 1, 'computer': 2, ...}
# 创建词袋语料库
corpus = [dictionary.doc2bow(text) for text in texts]
print(corpus[0]) # [(0, 1), (1, 1), (2, 1), ...]
#corous[0]的结构为[(0, 1), (1, 1), (2, 1), ...],含义为:列表当中每个元组代表一个词,元组的第一个元素代表词在字典中的索引,第二个元素代表词在文档中出现的次数
from gensim.models import TfidfModel
# 创建TF-IDF模型
tfidf = TfidfModel(corpus)
# 应用模型到语料库
corpus_tfidf = tfidf[corpus]
#这里的corpus_tfidf的结构与corpus相同,只是每个词的权重不同
# 查看第一个文档的TF-IDF值
for doc in corpus_tfidf:
print(doc)
break
word2vec模型的训练
#模型参数的解释
#model = Word2Vec(
# sentences,
# vector_size=100, # 词向量维度
# window=5, # 上下文窗口大小
# min_count=1, # 最小词频
# workers=4, # 并行线程数
# sg=1, # 1=Skip-gram, 0=CBOW
# negative=5, # 负采样数
# epochs=10 # 训练轮数
# )
from gensim.models import Word2Vec
import numpy as np
import pandas as pd
# 准备语料(每个句子已分词)
sentences = [
["中国", "北京", "是", "首都"],
["中国", "有", "悠久", "历史"],
["日本", "东京", "是", "首都"],
["美国", "华盛顿", "是", "首都"]
]
model = Word2Vec(sentences=sentences,vector_size=5,window=5,min_count=1,sg=1,epochs=10)
#print(model.wv['computer']) # 获取词向量
#print(model.wv.most_similar('computer')) # 查找相似词
# 保存和加载模型
#model.save("word2vec.model")
#model = Word2Vec.load("word2vec.model")
#加载句子向量,维度为(4,4,5),表示4个句子,每个句子4个词,5代表每个词的维度
sentences_vectors = np.array([model.wv[sentence] for sentence in sentences])
pd.DataFrame(sentences_vectors[0],index=sentences[0]).to_csv("sentences_vectors1.csv",header=None,encoding="gbk")
doc2vec模型训练
#模型参数
# model = Doc2Vec(
# documents,
# vector_size=300,
# window=8,
# min_count=5,#过滤词频小于5的词汇
# workers=4,#并行运算个数
# dm=0, # 为0使用PV-DBOW,类似skip-gram,为1时使用PV-DM,类似CBOW
# dbow_words=1, # 为1时候同时训练词向量,为0只训练句子向量
# epochs=40,
# alpha=0.025,#初始学习率
# min_alpha=0.001,#最小学习率
# hs=0,#默认为0,为0使用负采样,为1使用层次softmax
# negative=10,#负采样,当hs=0时起作用,表示每个正样本配是个负样本
# ns_exponent=0.75,#负采样指数
# sample=1e-3,#高频词下采样阈值,
# )
from gensim.models import Doc2Vec
from gensim.models.doc2vec import TaggedDocument
import numpy as np
# 输入数据(已分词 + 分配 tag)
sentences = [
["中国", "北京", "是", "首都"],
["中国", "有", "悠久", "历史"],
["日本", "东京", "是", "首都"],
["美国", "华盛顿", "是", "首都"]
]
#使用TaggedDocument创建句子和句子标签,句子标签可以是字符串也可以是整数
tagged_data = [TaggedDocument(words=words, tags=[str(i)]) for i, words in enumerate(sentences)]
# 训练模型
model = Doc2Vec(vector_size=50, min_count=1, epochs=50, dm=1)
model.build_vocab(tagged_data)
model.train(tagged_data, total_examples=model.corpus_count, epochs=model.epochs)
# 输出1:获取文档向量
doc_vector = model.dv["0"] # 获取第1个文档的向量
print("文档向量 shape:", doc_vector.shape) # (50,)
# 输出2:获取词向量
word_vector = model.wv["中国"]
print("词向量 shape:", word_vector.shape) # (50,)
# 输出3:推断新文档
new_text = "中国 历史 悠久"
new_words = new_text.split() # 假设已分词
new_vector = model.infer_vector(new_words)
print("新文档向量 shape:", new_vector.shape) # (50,)
# 输出4:计算相似文档
similar_docs = model.dv.most_similar([new_vector], topn=2)
print("最相似的文档:", similar_docs) # 返回 [(tag, similarity), ...]
加载预训练词向量
from gensim.models import KeyedVectors
import numpy as np
word_model=KeyedVectors.load_word2vec_format("wiki_word2vec_50.bin",binary=True)#二进制文件需要自行下载
print(word_model.vector_size) #显示词向量维度
print(word_model.key_to_index) #显示字典,key为词,value为索引
print(word_model.key_to_index["中国"]) # 显示字典,key为索引,value为词,并且顺序是按照词出现的频率排列的
print(word_model.index_to_key[0]) # 词频最高的词
print(word_model.vectors) # 词向量矩阵
print(word_model.vectors.shape) # 词向量矩阵维度(词数, 50)
print(word_model["中国"]==word_model.vectors[word_model.key_to_index["中国"]])#验证key_to_index和vectors的索引关系
print("老师" in word_model)#验证字典中是否有该词
#这个方法会在词向量空间中寻找与positive列表中的词向量方向相同,而与negative列表中的词向量方向相反的最近似词语。
print(word_model.most_similar(positive=['国王','女人'],negative=['男人'],topn=3))
#结果相当于:国王+女人-男人,并且返回topn个最相似的词
主题模型
使用gensim实现
import jieba
# import jieba.analyse
from gensim import corpora
from gensim.models import LdaModel
import re
# 示例中文文本数据
documents = [
"机器学习是计算机算法通过经验自动改进的研究领域",
"深度学习是基于人工神经网络的更广泛的机器学习方法家族的一部分",
"自然语言处理是语言学、计算机科学和人工智能的交叉领域",
"计算机视觉是研究计算机如何从数字图像或视频中获得高级理解的跨学科领域",
"人工智能是机器展示的智能,不同于人类和动物表现出的自然智能"
]
# 中文预处理函数
def preprocess_chinese(text):
# 移除标点符号和数字
text = re.sub(r'[^\w\s]', '', text)
# 使用jieba进行分词
words = jieba.lcut(text)
# 移除停用词
stopwords = ['的', '是', '和', '或', '如何', '之', '等', '在', '了', '与', '这', '那', '有', '没有']
words = [word for word in words if word not in stopwords and len(word) > 1]
return words
# 预处理所有文档
processed_docs = [preprocess_chinese(doc) for doc in documents]
# print(processed_docs)
# 创建词典
dictionary = corpora.Dictionary(processed_docs)
# 过滤极端值(出现少于2次或超过50%文档的词)
dictionary.filter_extremes(no_below=2, no_above=0.5)
# 创建词袋模型语料库
corpus = [dictionary.doc2bow(doc) for doc in processed_docs]
print(corpus)
# 训练LDA模型
# 设置主题数量
num_topics = 3
# 训练LDA模型
lda_model = LdaModel(
corpus=corpus,#加载语料
id2word=dictionary,#加载字典
num_topics=num_topics,#主题数量
random_state=100,#随机种子
update_every=1,#更新模型频率,0=批量学习,1=在线学习
chunksize=100,#批量大小
passes=10,#整个语料库的训练迭代次数
alpha='auto',#文档-主题分布的先验,高的话(如1.0)文档可能会包含多个主题的混合,低的话(如0.01)文档可能由少数主题主导
#eta='auto',#主题-词分布的先验,高的话(如1.0)主题可能会包含词典中多个词的混合,低的话(如0.01)主题可能由少数词主导
per_word_topics=True#是否返回每个主题的词
)
# 打印训练的结果,print_topics()返回主题和关键词,类型为[(),()]
for idx, topic in lda_model.print_topics():
print(f"主题 {idx}: \n关键词: {topic}\n")
##############################################################
# # 训练模型后保存
# model_path = "lda_model.model"
# lda_model.save(model_path)
# # 加载模型
# loaded_lda = LdaModel.load(model_path)
# # 保存词典
# dictionary_path = "lda_dictionary.dict"
# dictionary.save(dictionary_path)
# # 加载词典
# loaded_dict = corpora.Dictionary.load(dictionary_path)
##################################################################
#测试模型
# 新中文文档
new_doc = "神经网络和深度学习算法正在革命性改变人工智能领域"
# 预处理
processed_new_doc = preprocess_chinese(new_doc)
# 转换为词袋
new_doc_bow = dictionary.doc2bow(processed_new_doc)
# 获取主题分布,get_document_topics()返回文档的主题分布,输入形式为[词的索引,词频)]
topic_distribution = lda_model.get_document_topics(new_doc_bow)
print("文档主题分布:", topic_distribution)
# 输出示例:
# 文档主题分布: [(0, 0.056), (1, 0.897), (2, 0.047)]

浙公网安备 33010602011771号