-
2020-12-22 21:09:31
Word2vec训练中文词向量
发布时间:2018-08-16 10:55,
浏览次数:445
, 标签:
Word
vec
Word2vec训练中文词向量
将所有的语料读入到列表中,把每一句已经分好词的句子作为列表中的一个元素,类似:
[[‘i’,’am’,’a’,’girl’],[‘he’,’is’,’a’,’boy’]]
from gensim.models import Word2Vec
import os
import sys
##下面的代码是训练字向量的代码
sentence = []
word = []
tag = 0
with open('data_all.txt',encoding='utf-8') as fp: ##
print(type(fp))
for line in fp.readlines():
# print(line)
line = line.strip()
if line == '':
continue
tag += 1
print(tag)
if tag >10000:
break
if tag == 1:
line1 = ['']+line.split()
sentence.append(line1)
word.append('')
else:
sentence.append(line.split())
for each in line.split():
if each not in word:
word.append(each)
# print(len(sentence))
model = Word2Vec(sentence, sg=1, size=100, window=5, min_count=1,
negative=3, sample=0.001, hs=1, workers=4)
model.save('dict_data_model')
model = Word2Vec.load('dict_data_model') #加载模型
f1 = open('data_vec.txt','w',encoding='utf-8')
f1.write(str(len(word))+' '+str(100)+'\n')
for each in word:
# print (each)
str1 = ''
for e in model[each]:
if str1 == '':
str1 = str(e)
else:
str1 = str1+' '+str(e)
f1.write(each+' '+str1+'\n')
f1.close()
print(len(word))
print(len(list(set(word))))
当训练词向量的语料比较大时,会出现内存不够的问题,于是可以使用下面的代码进行修改:
class sentences_generator():
def __init__(self,filename):
self.filename = filename
def __iter__(self):
for line in open(self.filename):
sentence = line.rstrip(' ')
yield sentence
sentence = sentences_generator('data_all.txt')
model = Word2Vec(sentence, sg=1, size=100, window=5, min_count=1,
negative=3, sample=0.001, hs=1, workers=4)
model.save('dict_data_model')
model = Word2Vec.load('dict_data_model') #加载模型
f1 = open('data_vec.txt','w',encoding='utf-8')
f1.write(str(len(word))+' '+str(100)+'\n')
for each in word:
# print (each)
str1 = ''
for e in model[each]:
if str1 == '':
str1 = str(e)
else:
str1 = str1+' '+str(e)
f1.write(each+' '+str1+'\n')
f1.close()
print(len(word))
print(len(list(set(word))))
相关的博客网址:https://blog.csdn.net/thriving_fcl/article/details/51406780
第一种方法是将语料转换为一个python的list作为输入,但是语料较大时,大到报内存不够的错误时,该方法就失效了
第二种方法主要是为了解决第一种方法出现的问题,“
gensim的API并不要求sentences必须是list对象,只要输入的sentences是iterable的就行,那我们只要一次载入一个句子,训练完之后再将其丢弃,内存就不会因为语料过大而不够了。我们通过下面的代码就可以生成一个iterator。事先已经将训练语料
分词,词与词之间采用空格分开,并保存在一个文档里。
其实用一个函数也可以生成一个迭代器,只不过函数生成的迭代器迭代一轮就失效了,而这里需要迭代多轮。第一轮统计词频,用于生成哈夫曼树。后续用于训练,因此封装成一个类。
”(此段是引用上面博客中的内容)
##相关参数的解释
sg 定义训练算法,默认是sg=0,采用CBOW,否则sg=1采用skip-gram
size 是特征向量的维数,默认值为100维
window 设置当前词汇与上下文词汇的最大间距,默认值为5窗口
alpha 是最初学习速率,随着训练的进行,逐渐减少至0
seed 用于随机数生成器
min_count 设置最低有效词频,过滤掉一些低频词
max_vocab_size
设置词向量训练期间的最大RAM,如果词汇量超过这个就减掉词频最小的那个,设置None则不限制,每1000万字大概需要1Gb内存
sample 设置高频词随机下采样的阈值,默认值为1e-3,有效范围为(0,1e-5)
workers 设置几个工作线程来训练模型(有效利用多核机器)
hs 如果设置为1,将用于模型训练。如果设置为0(默认),同时negative设置为非零,将使用负采样
negative 如果> 0,将使用负采样,该数值指定应取出多少“噪声字”(通常在5-20之间)。默认值为5,如果设置为0,则不使用负采样
cbow_mean = 如果设置为0,使用上下文词向量的和。如果设为1(默认),则使用平均值,仅适用于使用cbow时。
hashfxn 散列函数,用于随机初始化权重以增加训练的可重复性。默认是Python的基本内置哈希函数
iter 语料库中的迭代次数(epochs),默认值为5
trim_rule
词汇修剪规则,指定某些词是否应保留在词汇表中,被修剪掉或使用默认值处理(如果字计数
)或接受参数(word,count,min_count)的可调用并返回utils.RULE_DISCARD,utils.RULE_KEEP或utils.RULE_DEFAULT。注意:规则(如果给出)仅在build_vocab()期间用于修剪词汇表,不会作为模型的一部分存储。
sorted_vocab 如果设为1(默认),在分配词索引之前,通过降序对词汇表进行排序。
batch_words
传递给工作线程(以及此cython例程)的示例批次的目标大小(以字为单位)。默认值为10000.(如果单个文本长度大于10000个字,则会传递更大的批次,但标准的cython代码会截断到最大值。)
更多相关内容 -
word2vec中文词向量
2019-09-28 20:54:44使用gensim对维基百科作为预训练语料(约1.6G语料),生成词汇量约13000个词汇,维度为300,文件大小为45.6MB。使用方法,参考博客:https://blog.csdn.net/qq_36426650/article/details/87738919 -
word2vec训练中文词向量
2018-09-26 16:27:45良好的词向量可以达到语义相近的词在词向量空间里聚集在一起,这对后续的文本分类,文本聚类等等操作提供了便利,这里简单介绍词向量的训练,主要是记录学习模型和词向量的保存及一些函数用法。 一、搜狐新闻 1. ...词向量作为文本的基本结构——词的模型。良好的词向量可以达到语义相近的词在词向量空间里聚集在一起,这对后续的文本分类,文本聚类等等操作提供了便利,这里简单介绍词向量的训练,主要是记录学习模型和词向量的保存及一些函数用法。
一、搜狐新闻
1. 中文语料库准备
本文采用的是搜狗实验室的搜狗新闻语料库,数据链接 http://www.sogou.com/labs/resource/cs.php
下载下来的文件名为: news_sohusite_xml.full.tar.gz
2. 数据预处理
2.1 数据解压缩并取出内容
(1)cd 到原始文件目录下,执行解压命令:
tar -zvxf news_sohusite_xml.full.tar.gz
(2)取出内容
由于这里的搜狐的材料中每个 对中存储的是文本内容。
所以取出 中的内容,执行如下命令:cat news_tensite_xml.dat | iconv -f gbk -t utf-8 -c | grep "<content>" > corpus.txt
得到文件名为corpus.txt的文件,可以通过vim 打开
vim corpus.txt
2.2 使用jieba分词
送给word2vec的文件是需要分词的,分词可以采用jieba分词实现,jieba安装很简单,这里不再讲解。
分词的代码如下:#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Sep 11 18:46:22 2018 @author: lilong """ """ 由原始文本进行分词后保存到新的文件 """ import jieba import numpy as np filePath='corpus_1.txt' fileSegWordDonePath ='corpusSegDone_1.txt' # 打印中文列表 def PrintListChinese(list): for i in range(len(list)): print (list[i]) # 读取文件内容到列表 fileTrainRead = [] with open(filePath,'r') as fileTrainRaw: for line in fileTrainRaw: # 按行读取文件 fileTrainRead.append(line) # jieba分词后保存在列表中 fileTrainSeg=[] for i in range(len(fileTrainRead)): fileTrainSeg.append([' '.join(list(jieba.cut(fileTrainRead[i][9:-11],cut_all=False)))]) if i % 100 == 0: print(i) # 保存分词结果到文件中 with open(fileSegWordDonePath,'w',encoding='utf-8') as fW: for i in range(len(fileTrainSeg)): fW.write(fileTrainSeg[i][0]) fW.write('\n') """ gensim word2vec获取词向量 """ import warnings import logging import os.path import sys import multiprocessing import gensim from gensim.models import Word2Vec from gensim.models.word2vec import LineSentence # 忽略警告 warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim') if __name__ == '__main__': program = os.path.basename(sys.argv[0]) # 读取当前文件的文件名 logger = logging.getLogger(program) logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s',level=logging.INFO) logger.info("running %s" % ' '.join(sys.argv)) # inp为输入语料, outp1为输出模型, outp2为vector格式的模型 inp = 'corpusSegDone_1.txt' out_model = 'corpusSegDone_1.model' out_vector = 'corpusSegDone_1.vector' # 训练skip-gram模型 model = Word2Vec(LineSentence(inp), size=50, window=5, min_count=5, workers=multiprocessing.cpu_count()) # 保存模型 model.save(out_model) # 保存词向量 model.wv.save_word2vec_format(out_vector, binary=False)
分词的结果是:
并且会保存3个文件:
corpusSegDone_1.txt
corpusSegDone_1.model
corpusSegDone_1.vector由于这里运行需要一段时间,所以没有进行验证测试。
二、维基百科
由于训练需要一定的时间,所以这里只讲下思路。
1. 数据预处理
维基百科数据量不够大,百度百科数据量较全面,内容上面百度百科大陆相关的信息比较全面,港澳台和国外相关信息维基百科的内容比较详细,因此训练时将两个语料一起投入训练,形成互补,另外还加入了1.1万公司行业数据
模型:gensim工具包word2vec模型,安装使用简单,训练速度快
语料:百度百科500万词条+维基百科30万词条+1.1万条领域数据
分词:jieba分词,自定义词典加入行业词,去除停用词
硬件:根据自己的电脑硬件而定2. 分词
- 准备一个停用词词典,训练时要去除停用词的干扰
- 分词工具有中科院分词,哈工大的LTP分词,jieba分词,分词效果中科院的分词效果不错,而这里直接使用jieba进行分词,使用简单方便,分词速度快。
- 自定义词典:由于百科数据有很多专属名词,很多比较长,如果直接分词,很大情况下会被切开,这不是我们想要的结果,比如:中国人民解放军,可能会被分成:中国 人民 解放军,jieba虽然有新词发现功能,为保证分词准确度,jieba的作者建议我们还是使用自定义词典。
- 自定义词典抽取:从百度百科抽取了200万的词条,由于自定义词典包含英文单词时会导致jieba对英文单词进行分词,所以需要用正则表达式去除词条中的英文数据,并且去除一些单字词,还有一些词条里面较短词,如"在北京",这类词会导致分词出现问题,也需要使用正则去除,也有简单粗暴的方法,直接保留3个汉字及以上的中文词条,去除之后得到170万大小的自定义词典。
- 分词
分词代码:
# 多线程分词 # jieba.enable_parallel() #加载自定义词典 jieba.load_userdict("F:/baike_spider/dict/baike_word_chinese") #加载停用词 def getStopwords(): stopwords = [] with open("stop_words.txt", "r", encoding='utf8') as f: lines = f.readlines() for line in lines: stopwords.append(line.strip()) return stopwords #分词 def segment(): file_nums = 0 count = 0 url = base_url + 'processed_data/demo/' fileNames = os.listdir(url) for file in fileNames: # 遍历每个文件 # 日志信息 logging.info('starting ' + str(file_nums) + 'file word Segmentation') segment_file = open(url + file + '_segment', 'a', encoding='utf8') # 每个文件单独处理 with open(url + file, encoding='utf8') as f: text = f.readlines() for sentence in text: sentence = list(jieba.cut(sentence)) sentence_segment = [] for word in sentence: if word not in stopwords: sentence_segment.append(word) segment_file.write(" ".join(sentence_segment)) del text f.close() segment_file.close() # 日志信息 logging.info('finished ' + str(file_nums) + 'file word Segmentation') file_nums += 1
- 由于python多线程只能单核多线程,如果是多核的机器并不能有效使用cpu,jieba是使用python写的,所以jieba只支持并行分词,并行分词指的是多进程分词,并且不支持windows。
- 在linux试过jieba自带的并行分词,开启并行分词之后,jieba后台会自动开启多个进程,并且并行分词需要一次性将训练语料读取到内存并传入jieba.cut(file.read())中才会有效果,如果类似我代码中逐行传入,开启多进程是不起作用的,jieba多进程原理是,jieba后台会自动将语料切分分配给指定进程处理,分好词后再合并。
- 8核16g内存Linux虚拟机,发现开启jieba并行分词,1g的语料数据,很快就爆内存了
- 单进程的jieba分词,不需要一次性加载所有语料数据,可逐行读取语料,内存占用不大,运行稳定。因此将语料数据分成8份,手动开启8个进程分别分词,这样每个进程内存占用都很稳定,比jieba自带的并行分词性能好,20g的数据,开启HMM模式,分词大概花了10个小时
3. word2vec训练
使用gensim工具包的word2vec训练,使用简单速度快,效果比Google 的word2vec效果好,用tensorflow来跑word2vec模型,16g的内存根本跑不动
gensim word2vec 训练代码如下,非常简单:import logging import multiprocessing import os.path import sys import jieba from gensim.models import Word2Vec from gensim.models.word2vec import PathLineSentences if __name__ == '__main__': # 日志信息输出 program = os.path.basename(sys.argv[0]) logger = logging.getLogger(program) logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s') logging.root.setLevel(level=logging.INFO) logger.info("running %s" % ' '.join(sys.argv)) # check and process input arguments # if len(sys.argv) < 4: # print(globals()['__doc__'] % locals()) # sys.exit(1) # input_dir, outp1, outp2 = sys.argv[1:4] input_dir = 'segment' outp1 = 'baike.model' outp2 = 'word2vec_format' fileNames = os.listdir(input_dir) # 训练模型 # 输入语料目录:PathLineSentences(input_dir) # embedding size:256 共现窗口大小:10 去除出现次数5以下的词,多线程运行,迭代10次 model = Word2Vec(PathLineSentences(input_dir), size=256, window=10, min_count=5, workers=multiprocessing.cpu_count(), iter=10) model.save(outp1) model.wv.save_word2vec_format(outp2, binary=False) # 运行命令:输入训练文件目录 python word2vec_model.py data baike.model baike.vector
- 由于语料太大,不能一次性加载到内存训练,gensim提供了PathLineSentences(input_dir)这个类,会去指定目录依次读取语料数据文件,采用iterator方式加载训练数据到内存。
- 从训练日志可以看到,其过程是先依次读取每个文件,生成总的vocab词典,用来统计count,训练时用来过滤min_count小于我们制定数量的词,vocab总词典生成后,会依次读入语料进行model训练,训练速度非常快。
三、word2vec词向量的保存与加载
- 以model.save()方法保存词向量
保存词向量
import gensim model = gensim.models.Word2Vec(documents, size=300) model.train(documents, total_examples=len(documents), epochs=10) model.save("../input/Word2vec.w2v")
加载词向量
import gensim word2vec = gensim.models.word2vec.Word2Vec.load("./input/Quora.w2v").wv
- 存为二进制的词向量
保存词向量
model.wv.save_Word2Vec_format(embedding_path,binary=True) #model.wv.save_Word2Vec_format(embedding_path,binary=False)非二进制
加载词向量
import gensim word2vec = gensim.models.KeyedVectors.load_word2vec_format(embedding_path,binary=True)
- 使用numpy进行保存和加载
保存数组数据的文件可以是二进制格式或者文本格式,二进制格式的文件可以是Numpy专用的二进制类型和无格式类型。
使用
np.save()
保存npy文件,np.load()
加载npy文件。模型导出与导入:
最简单的导入与导出
(1)word2vec.save即可导出文件,这边没有导出为.bin
# 模型保存与载入 model.save('/tmp/mymodel') new_model = gensim.models.Word2Vec.load('/tmp/mymodel') odel = Word2Vec.load_word2vec_format('/tmp/vectors.txt', binary=False) # 载入 .txt文件 # using gzipped/bz2 input works too, no need to unzip: model = Word2Vec.load_word2vec_format('/tmp/vectors.bin.gz', binary=True) # 载入 .bin文件 word2vec = gensim.models.word2vec.Word2Vec(sentences(), size=256, window=10, min_count=64, sg=1, hs=1, iter=10, workers=25) word2vec.save('word2vec_wx')
(2)gensim.models.Word2Vec.load的办法导入
model = gensim.models.Word2Vec.load('xxx/word2vec_wx') pd.Series(model.most_similar(u'微信',topn = 360000))
(3)Numpy的话可以用numpy.load:
import numpy word_2x = numpy.load('xxx/word2vec_wx.wv.syn0.npy')
(4)其他的导入方式,导入txt格式+bin格式 :
from gensim.models.keyedvectors import KeyedVectors word_vectors = KeyedVectors.load_word2vec_format('/tmp/vectors.txt', binary=False) # C text format word_vectors = KeyedVectors.load_word2vec_format('/tmp/vectors.bin', binary=True) # C binary format
增量训练
# 增量训练 model = gensim.models.Word2Vec.load(temp_path) more_sentences = [['Advanced', 'users', 'can', 'load', 'a', 'model', 'and', 'continue', 'training', 'it', 'with', 'more', 'sentences']] model.build_vocab(more_sentences, update=True) model.train(more_sentences, total_examples=model.corpus_count, epochs=model.iter)
不能对C生成的模型进行再训练
仅用做记录学习。
参考:
https://www.cnblogs.com/Newsteinwell/p/6034747.html
https://www.jianshu.com/p/87798bccee48
https://blog.csdn.net/sinat_26917383/article/details/69803018 -
Word2Vec:采用Word2Vec训练词向量,数据集:STS
2021-05-01 04:16:01Word2Vec 采用Word2Vec训练词向量,数据集:STS -
NLP:使用 gensim 中的 word2vec 训练中文词向量
2021-06-17 14:08:30本内容主要介绍使用 gensim 中的 word2vec 训练中文词向量。文章目录
前言
本内容主要介绍使用 gensim 中的 word2vec 训练中文词向量。
1.1 下载数据集
本内容使用 wiki 中文语料作为训练数据。可以在 wiki 官网下载中文语料,下载后得到一个名为
zhwiki-latest-pages-articles.xml.bz2
的压缩文件,解压后里面是一个 xml 文件。下载地址:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2
1.2 预处理
1.2.1 将原始 xml 文件转换为 txt 文件
因为下载得到的数据是一份 xml 文件,里面存在各种标签,所以我们需要对其进行处理,然后将其保存到一个 txt 文件中。我们可以借助 gensim 中提供的
gensim.corpora.WikiCorpus
实现这个操作,示例代码如下:from gensim.corpora import WikiCorpus class ZhWikiPreProcessor: def convert_xml_to_text(self, input_file, output_file): with open(output_file, mode='w', encoding='utf-8') as out_f: index = 0 space = ' ' wiki_corpus = WikiCorpus(input_file, dictionary=[]) for text in wiki_corpus.get_texts(): # 保存到文件中 out_f.write(space.join(text) + '\n') index += 1 # 打印处理进度 if index % 1000 == 0: print("Saved {} articles...".format(index)) zh_wiki_xml_file = r'.\zhwiki\zhwiki-latest-pages-articles.xml.bz2' zh_wiki_text_file = r'.\zhwiki\zh_wiki_original_text.txt' preprocessor = ZhWikiPreProcessor() # 将 xml 内容转换为 txt 内容 preprocessor.convert_xml_to_text(zh_wiki_xml_file, zh_wiki_text_file)
1.2.2 中文繁体转简体
因为上面获取到的 Wiki 中文语料中包含了很多繁体字,所以我们需要将繁体字转换为简体字。可以使用 OpenCC 实现这个操作,示例代码如下:
from opencc import OpenCC class ZhWikiPreProcessor: def convert_t2s(self, input_file, output_file): with open(output_file, mode='w', encoding='utf-8') as output_f: with open(input_file, mode='r', encoding='utf-8') as input_f: index = 0 cc = OpenCC('t2s') for line in input_f.readlines(): # 将中文繁体转换为中文简体 line = cc.convert(line.strip()) # 保存到文件中 output_f.write(line + '\n') index += 1 # 打印处理进度 if index % 1000 == 0: print('Converted {} articles...'.format(index)) zh_wiki_text_file = r'.\zhwiki\zh_wiki_original_text.txt' zh_wiki_simple_text_file = r'.\zhwiki\zh_wiki_simple_text.txt' preprocessor = ZhWikiPreProcessor() # 将中文繁体转换为中文简体 preprocessor.convert_t2s(zh_wiki_text_file, zh_wiki_simple_text_file)
如果想了解更多关于 OpenCC 的信息,可以参照 这里。
1.2.3 分词
下面需要对训练文本进行分词操作,就是将句子分解成一个个的词。中文分词工具有中科院计算所 NLPIR、哈工大 LTP、清华大学 THULAC、北京大学 PKUSeg、FoolNLTK、HanLP、jieba 等。本内容采用了
jieba
分词工具(其使用简单方便、流行度高),示例代码如下:import jieba class ZhWikiPreProcessor: def text_segment(self, input_file, output_file): with open(output_file, mode='w', encoding='utf-8') as output_f: with open(input_file, mode='r', encoding='utf-8') as input_f: index = 0 for line in input_f.readlines(): # 对文本进行分词操作 words = jieba.cut(line.strip(), cut_all=False) # 将词之间使用空格分隔,并保存到文件中 output_f.write(' '.join(words) + '\n') index += 1 # 打印处理进度 if index % 1000 == 0: print("Segment text {} lines...".format(index)) zh_wiki_simple_text_file = r'.\zhwiki\zh_wiki_simple_text.txt' zh_wiki_simple_segment_text_file = r'.\zhwiki\zh_wiki_simple_segment_text.txt' preprocessor = ZhWikiPreProcessor() # 对文本进行分词操作 preprocessor.text_segment(zh_wiki_simple_text_file, zh_wiki_simple_segment_text_file)
1.2.4 去除停用词
有时候我们可能需要去除停用词。在原有分词代码的基础上,需要新增两处修改:a. 获取停用词集合;b. 移除分词结果中的停用词。示例代码如下:
import jieba class ZhWikiPreProcessor: def text_segment(self, input_file, output_file, stopwords_file=None): # 获取停用词集合(01.新增加内容) if stopwords_file is not None: stopwords_set = self.get_stopwords(stopwords_file) else: stopwords_set = set() with open(output_file, mode='w', encoding='utf-8') as output_f: with open(input_file, mode='r', encoding='utf-8') as input_f: index = 0 for line in input_f.readlines(): # 对文本进行分词操作 words = jieba.cut(line.strip(), cut_all=False) # 去除停用词(02.新增加内容) words = [word for word in words if word not in stopwords_set] # 将词之间使用空格分隔,并保存到文件中 output_f.write(' '.join(words) + '\n') index += 1 # 打印处理进度 if index % 1000 == 0: print("Segment text {} lines...".format(index)) @staticmethod def get_stopwords(stopwords_file): stopwords_set = set() with open(stopwords_file, mode='r', encoding='utf-8') as f: for stopword in f.readlines(): stopwords_set.add(stopword.strip()) return stopwords_set
1.3 训练词向量
本内容使用 gensim 工具包中的 word2vec 进行训练,示例代码如下:
from gensim.models import Word2Vec from gensim.models.word2vec import LineSentence def train_zhwiki(): # 训练数据文件名 data_file = r'.\zhwiki\zh_wiki_segment_text.txt' # 保存的模型文件名 model_file = r'.\zhwiki\zh_wiki.model' vector_file = r'.\zhwiki\zh_wiki.vector' # 训练模型 model = Word2Vec(LineSentence(data_file), vector_size=100) # 保存模型 model.save(model_file) model.wv.save_word2vec_format(vector_file, binary=False)
下面列出
gensim.models.Word2Vec
的一些主要参数:参数名 说明 sentences 训练语料,需要是一个可迭代的对象,比如简单的列表或者 gensim 提供的 LineSentence 对象等。 corpus_file 训练语料文件,可以替代上面的 sentences。 vector_size 词向量的维度,默认值为 100。 window 目标词和上下文词的最大距离。 min_count 词频小于这个值的词,不计算其词向量,默认值为 5。 workers 训练模型时的线程数 sg word2vec 训练模型的选择。1 表示 skip-gram;否则为 CBOW。 hs 训练模型的优化算法的选择。1 表示使用层级 softmax;0 并且参数 negative 为非零时,使用负采样。 negative 指定负采样的个数。当设置为 0 时,将不会使用负采样。 cbow_mean 当使用 CBOW 时有效。0 表示使用上下文词向量的和;1 表示使用上下文词的平均值。 alpha 初始学习率。 min_alpha 最小学习率。 max_vocab_size 词表的最大数量。 epochs 训练的迭代次数。 callbacks 回调函数。 可以通过调整这些参数,从而使训练出来的模型达到最佳效果。
1.4 测试词向量
下面对训练的词向量效果进行测试,示例代码如下:
from gensim.models import Word2Vec def test_zhwiki_model(): # 模型文件名 model_file = r'.\zhwiki\zh_wiki.model' # 加载模型 model = Word2Vec.load(model_file) # 获取词的相似词 result = model.wv.most_similar('清华大学') for word in result: print(word) print('\n') # 获取两个词之间的余弦相似度 result = model.wv.similarity('男人', '女人') print(result)
将输出以下结果:
('北京大学', 0.886064350605011) ('武汉大学', 0.8563425540924072) ('清华', 0.8015897274017334) ('浙江大学', 0.7996682524681091) ('中山大学', 0.7982087135314941) ('复旦大学', 0.7962114214897156) ('中国人民大学', 0.7908720374107361) ('南开大学', 0.7769314050674438) ('南京大学', 0.775385320186615) ('华东师范大学', 0.7644416093826294) 0.915614
1.5 总结
从上面对词向量的测试结果看,效果还算可以。如果我们需要在实际项目中进行使用,可以考虑从以下几个方向入手:
- 提高分词的准确度。
- 维护一份有效的停用词表。
- 不断调整
gensim.models.Word2Vec
的参数。 - 其他。
参考
[2] 以 gensim 訓練中文詞向量
-
word2vec词向量训练及中文文本相似度计算
2021-01-27 16:13:34PS:第一部分主要是给大家引入基础内容作铺垫,这类文章很多,希望大家自己去学习更多更好的基础内容,这篇博客主要是介绍Word2Vec对中文文本的用法。统计语言模型的一般形式是给定已知的一组词, -
word2vec中文词向量.zip
2019-12-03 15:22:41使用gensim对维基百科作为预训练语料(约1.6G语料),生成词汇量约13000个词汇,维度为300,文件大小为45.6MB。使用方法,参考博客:https://blog.csdn.net/qq_36426650/article/details/87738919 -
『词向量』用Word2Vec训练中文词向量(二)—— 采用维基百科语料库
2020-03-14 13:51:51本文是在『词向量』用Word2Vec训练中文词向量(一)—— 采用搜狗新闻数据集 的基础上,将搜狗与维基两个语料库合并,进而训练出较好的词向量模型。本文是在『词向量』用Word2Vec训练中文词向量(一)—— 采用搜狗新闻数据集 的基础上,将两个语料库合并,进而训练出较好的词向量模型。
参考:基于word2vec使用中文wiki语料库训练词向量
小项目(Gensim库)–维基百科中文数据处理数据集下载
点此下载:wiki 语料库 选择最新的。
下载下的文件为 zhwiki-latest-pages-articles.xml.bz2,大小为1.75GB(下载速度特慢)。
数据集处理
(一)文本提取
有两种方法可以从压缩文件中提取出文本:
- 使用 gensim.corpora 的 WikiCorpus 来直接对维基语料库进行处理。保存到 wikiCorpus/wikiCorpus.txt
from gensim.corpora import WikiCorpus if __name__ == '__main__': print('主程序开始...') input_file_name = 'zhwiki-latest-pages-articles.xml.bz2' output_file_name = 'wikiCorpus/wikiCorpus.txt' print('开始读入wiki数据...') input_file = WikiCorpus(input_file_name, lemmatize=False, dictionary={}) print('wiki数据读入完成!') print('处理程序开始...') count = 0 with open(output_file_name, 'wb') as output_file: for text in input_file.get_texts(): output_file.write(' '.join(text).encode("utf-8")) output_file.write('\n'.encode("utf-8")) count = count + 1 if count % 10000 == 0: print('目前已处理%d条数据' % count) print('处理程序结束!') output_file.close() print('主程序结束!')
- 下载 Wikipedia Extractor 来提取文本。
数据集处理完成,一共 35w+ 条数据,效果如下所示。我们发现,已经去除了标点,简直不要太赞!!!
(二)化繁为简
下载 opencc ,进行繁简转换。
将 wikiCorpus.txt 复制到该文件夹中,用指示符 cd 到该文件夹,输入
opencc -i wikiCorpus.txt -o wikiCorpusSim.txt -c t2s.json
即可完成转化,将转化后的 wikiCorpusSim.txt 保存到 python project,效果如图所示:
(三)文档分词
如果之前做过搜狗数据集的话,这一步应该很熟悉了。
import jieba filePath = 'wikiCorpus/wikiCorpusSim.txt' # 简化后文本 fileSegWordDonePath = 'wikiCorpus/wikiCorpusSegDone.txt' # 分词处理后文本 # 将每一行文本依次存放到一个列表 fileTrainRead = [] with open(filePath, encoding='utf-8') as fileTrainRaw: for line in fileTrainRaw: fileTrainRead.append(line) # 用jieba进行分词 fileTrainSeg = [] file_userDict = 'dict.txt' # 自定义的词典 jieba.load_userdict(file_userDict) for i in range(len(fileTrainRead)): fileTrainSeg.append([' '.join(jieba.cut(fileTrainRead[i], cut_all=False))]) if i % 100 == 0: # 每处理100个就打印一次 print(i) # 处理后写入文件 with open(fileSegWordDonePath, 'wb') as fW: for i in range(len(fileTrainSeg)): fW.write(fileTrainSeg[i][0].encode('utf-8')) fW.write('\n'.encode("utf-8"))
(四)合并数据集
将之前处理好的搜狗数据集与维基合并,生成炒鸡无敌中文语料库。
filePath1 = 'wikiCorpus/wikiCorpusSegDone.txt' # wiki分词后语料库 filePath2 = 'sougouCorpus/sougouCorpusSegDone.txt' # 搜狗语料库 filePath3 = 'corpusFinal.txt' # 最终语料库 fileFinal = [] countS = 0 # sougou计数 countW = 0 # wiki计数 # 打开搜狗语料库 with open(filePath2, encoding='utf-8') as ff1: print("---成功导入搜狗语料库---") for line in ff1: fileFinal.append(line) countS = countS + 1 if countS % 10000 == 0: print("---------已导入%d篇搜狗文章---------" % countS) # 打开维基语料库 with open(filePath1, encoding='utf-8') as ff2: print("---成功导入wiki语料库---") for line in ff2: fileFinal.append(line) countW = countW + 1 if countW % 10000 == 0: print("---------已导入%d篇维基文章---------" % countW) # 打开最终文档,逐行写入 with open(filePath3, 'wb') as ff: for i in range(len(fileFinal)): ff.write(fileFinal[i].encode('utf-8')) if i % 10000 == 0: print("---------已合并%d篇文章---------" % i) print("---------一共读入%d行---------" % len(fileFinal)) print("---------完成合并---------")
一共有 212w+ 行数据(其中维基71w 行 + 搜狗 141w 行)
大小为 3.35GB
训练模型
还是用的老代码
import logging import sys import gensim.models as word2vec from gensim.models.word2vec import LineSentence, logger # import smart_open def train_word2vec(dataset_path, out_vector): # 设置输出日志 logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO) logger.info("running %s" % ' '.join(sys.argv)) # 把语料变成句子集合 sentences = LineSentence(dataset_path) # sentences = LineSentence(smart_open.open(dataset_path, encoding='utf-8')) # 或者用smart_open打开 # 训练word2vec模型(size为向量维度,window为词向量上下文最大距离,min_count需要计算词向量的最小词频) model = word2vec.Word2Vec(sentences, size=128, sg=1, window=6, min_count=5, workers=4, iter=6) # (iter随机梯度下降法中迭代的最大次数,sg为1是Skip-Gram模型) # 保存word2vec模型 model.save("word2vec.model") model.wv.save_word2vec_format(out_vector, binary=False) # 加载模型 def load_word2vec_model(w2v_path): model = word2vec.Word2Vec.load(w2v_path) return model # 计算词语最相似的词 def calculate_most_similar(self, word): similar_words = self.wv.most_similar(word) print(word) for term in similar_words: print(term[0], term[1]) # 计算两个词相似度 def calculate_words_similar(self, word1, word2): print(self.wv.similarity(word1, word2)) # 找出不合群的词 def find_word_dismatch(self, list): print(self.wv.doesnt_match(list)) if __name__ == '__main__': dataset_path = 'corpusFinal.txt' out_vector = 'corpusFinal.vector' train_word2vec(dataset_path, out_vector) # 训练模型 # model = load_word2vec_model("word2vec.model") # 加载模型 # calculate_most_similar(model, "病毒") # 找相近词 # calculate_words_similar(model, "法律", "制度") # 两个词相似度 # print(model.wv.__getitem__('男人')) # 词向量 # list = ["早饭", "吃饭", "恰饭", "嘻哈"] # find_word_dismatch(model, list)
与“病毒”相关的词:
写在最后
如果时间来不及训练模型,或者是出现了错误,可以加我的Q:2206300581(推荐,比较好发文件),我会提供分词后的结果【corpusSegDone.txt】以及训练好的模型【word2vec.model】。
参考文章
-
『词向量』用Word2Vec训练中文词向量(一)—— 采用搜狗新闻数据集
2020-03-11 23:03:38用搜狗新闻数据集来训练中文词向量(Word2Vec),自己做的时候踩了很多的坑,希望分享出来让大家少走弯路。 -
在python下实现word2vec词向量训练与加载实例
2020-09-16 17:31:42主要介绍了在python下实现word2vec词向量训练与加载实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
基于word2vec的中文词向量训练
2019-02-20 10:38:30基于word2vec的中文词向量训练 一、引言 在绝大多数的自然语言处理任务中,语料是无法直接用来特征提取,需要将其转化为计算机可以读取的数值,因此引入独热编码,即对于语料库中为每一个词汇设置编号。在大语料... -
基于中文对话文本使用Word2Vec进行训练得到的词向量
2020-12-27 11:24:51基于中文对话文本使用Word2Vec进行训练得到的词向量 -
利用word2vec训练词向量
2021-09-18 10:54:33利用word2vec训练词向量 这里的代码是在pycharm上运行的 一、数据预处理 我们选用的数据集是新闻数据集一共有五千条新闻数据,一共有四个维度 数据集:https://pan.baidu.com/s/14z–kvHYgwDAbgO0dxlHDg 提取码:9a... -
Python Word2vec训练医学短文本字/词向量实例实现,Word2vec训练字向量,Word2vec训练词向量,Word2vec训练...
2022-04-02 13:11:14Python Word2vec训练医学短文本字/词向量实例实现,Word2vec训练字向量,Word2vec训练词向量,Word2vec训练保存与加载模型,Word2vec基础 -
Word2Vec中文词向量
2022-02-22 22:21:54word2vec中文词向量中文词向量训练模型保存模型导入 中文词向量训练 from gensim.models import Word2Vec sentences = ["被告人 段 某 酒后 与 其 妻子 王1 某 一起 准备 回 家 , 走 到 鸡飞乡 澡塘街 富达 通讯 ... -
使用word2vec训练中文词向量
2018-08-15 13:05:021 对文本数据进行预处理:数据预处理,包括简繁体转换,去除xml符号,将单词条内容处理成单行数据,word2vec训练原理是基于词共现来训练词之间的语义联系的。不同词条内容需分开训练 2 中文分词:中文NLP很重要的... -
使用word2vec训练词向量
2021-03-11 14:51:59size:词向量的维度,默认值是100。这个维度的取值一般与我们的语料的大小相关,如果是不大的语料,比如小于100M的文本语料,则使用默认值一般就可以了。如果是超大的语料,建议增大维度。 window:即词向. -
【NLP_向量表示】使用Word2Vec训练词向量
2021-03-28 14:56:14重要参考 ... 完整代码 ...f=codecs.open('D:\Asian elephant\\biye\Spatial relation extraction\Train word vectors yourself\yuliao.txt','r',encoding="utf8") #将分完词的语料写入到wiki_ji. -
词向量模型(word2vec)总结笔记
2021-01-07 01:43:38引言 自从Mikolov在他2013年的论文“Efficient Estimation of Word Representation in Vector ...相较于传统NLP的高维、稀疏的表示法(One-hot Representation),Word2Vec训练出的词向量是低维、稠密的。 在上一篇文章里 -
gensim训练Word2Vec词向量模型
2022-04-18 13:58:37gensim训练Word2Vec词向量模型 -
中文的word2vec词向量
2018-05-05 18:12:38个人训练的一套word2vec中文词向量。维度为200维。python装gensim后可以直接用! -
加载glove或者word2vec训练好的词向量进行训练LSTM等模型的训练
2022-02-07 14:03:25可以使用torchtext来加载词向量然后直接初始化模型的embedding层就达到目的了。 加载glove词向量 这个比较方便 下面仅展示思路,代码不能跑 import torchtext # 定义一个field,用于数据预处理(切词等) TEXT = ... -
word2vec训练的词向量评估方法
2020-09-19 19:12:07对于词向量的评估方法有三种: (1)降维到二维结合常识看词分布是否同类的...(2) 结合人工标记的词库的词向量进行比对,计算余弦相似度评估。 (3) 用类比的方法,看两组相同词构成的向量是否平行。 ... -
Word2vec如何得到词向量
2021-04-16 10:49:09Word2Vec包含了两种词训练模型:CBOW模型和Skip-gram模型。 CBOW模型根据中心词W(t)周围的词来预测中心词 Skip-gram模型则根据中心词W(t)来预测周围词 模型计算word2vec的流程:以CBOW模型的流程为例 输入... -
WORD2VEC-使用GLOVE训练中文词向量
2021-07-22 15:44:36WORD2VEC-使用GLOVE训练中文词向量 准备语料 语料预处理 去停用词 去除所有标点符号 ?!@#$%^&*()~`,./| 重音字 过滤掉频率低的单词 处理数字 每个数字都替换为 #number 单词转小写 如下图: 训练语料 从...