Doc2Vec主要作用是将文章转化为词向量,支持大批量的数据训练,如果遇到多个较大的数据文件,不能全部加装到内存中,可以使用下面的方法,自己封装TaggedDocument。 如果数据量较小,且只有1个数据文件,可以使用doc2vec.TaggedLineDocument,注意,数据文件一行对应一篇文章,并且词必须以空格隔开。
# 设置迭代器 tagged_line = TaggedLineDocument("F:\\my_data\\test.text") # 构建模型 model = Doc2Vec(dim=0, vector_size=100, window=8, epochs=2, min_count=2, workers=4) # 将迭代器添加到模型中 model.build_vocab(tagged_line )
F: --my_data ----model ----mason_1.txt ----mason_2.txt
“mason_1.txt”内容 我,爱你,河南大学 你,的,母校 我,爱你,河南大学
“mason_2.txt”内容 我,爱你,软件学院 我,敬爱,导师
from gensim.models.doc2vec import Doc2Vec from gensim.models.doc2vec import TaggedDocument
import os
class TaggedData(object): """
继承object类,使用yield实现大数据量文件的批量训练Doc2Vec模型
""" def __init__(self, dir_name): """ 初始化目录
:param dir_name: 文件目录 """ self.dir_name = dir_name
def __iter__(self): """ 实现迭代器 """ for f_name in os.listdir(self.dir_name): f_name = os.path.join(self.dir_name, f_name) if not os.path.isfile(f_name): continue
# 读取文件 with open(f_name, "r", encoding="utf-8") as fin: for item_no, line in enumerate(fin): # 切分文件 words = line.split(",") # 注意:我的文件是一行对应一篇文章 # TaggedDocument(文章的词列表, [文章表标签]) # 自己定义唯一的文章标签,方便后续查找文章向量 yield TaggedDocument(words, tags=['%s_%s' % (f_name, item_no)])
def train_model(): # 设置迭代器 tagged_data = TaggedData("F:\\my_data") # 构建模型 model = Doc2Vec(dim=0, vector_size=100, window=8, epochs=2, min_count=2, workers=4) # 将迭代器添加到模型中 # 注意:documents也可以接收[TaggedDocument(doc, tags=[tag)]列表 # 可以根据自己的需求将文章组合为列表 model.build_vocab(documents=tagged_data)
print("---** 多次训练模型 **---") # 注意文章的数据不能太少,至少5个文章以上 # 否则会报“you must first build vocabulary before training the model”错误 for i in range(3): model.train(documents=tagged_data, total_examples=model.corpus_count, epochs=model.epochs)
# 打印 print("---** 统计文章数量 **---") print(model.docvecs.count)
print("---** 文章标签(列表) **---") print(model.docvecs.offset2doctag)
print("---** 文章向量(numpy列表) **---") print(model.docvecs.vectors_docs)
print("---** 文章统计(字典) **---") # 'F:\\my_data\\mason_1.txt_0': Doctag(offset=0, word_count=3, doc_count=1), # '文章标签': Doctag(offset=对应vectors_docs和offset2doctag的索引, word_count=单词数量, doc_count=文章频次) print(model.docvecs.doctags)
print("---** 统计与“F:\\my_data\\mason_1.txt_0”文章最相似的文章(列表) **---") # ('F:\\my_data\\mason_2.txt_0', -0.04498976841568947) # ('文章标签', 相似度) print(model.docvecs.most_similar(model.docvecs.doctags.get("F:\\my_data\\mason_1.txt_0")))
print("---** 比较两篇文章的相似度 **---") # 注意:这里比较只能在已有文章中查找 # similarity(文章1标签,文章2标签) print(model.docvecs.similarity("F:\\my_data\\mason_1.txt_0", "F:\\my_data\\mason_1.txt_1")) # similarity(文章1索引,文章2标签) print(model.docvecs.similarity(0, 1))
print("---** 计算文章的词向量 **---") words=["河南大学", "软件学院"] print(model.infer_vector(words))
print("---** 模型的保存 **---") model.save("F:\\my_data\\model\\henu.model")
print("---** 模型的加载 **---") model = Doc2Vec.load("F:\\my_data\\model\\henu.model")
# Word2Vec与Doc2Vec的用法相同,不同之处在于 # model.wv:是对应Word2Vec的方法 # model.docvecs:是对应Doc2Vec的方法
if __name__ == '__main__': train_model()
Word2Vec与Doc2Vec的用法基本相同,不同之处在于“model.wv”是对应Word2Vec的方法,“model.docvecs”是对应Doc2Vec的方法。