当前位置:网站首页>word2vec训练中文词向量
word2vec训练中文词向量
2022-07-01 13:14:00 【全栈程序员站长】
大家好,又见面了,我是你们的朋友全栈君。
词向量作为文本的基本结构——词的模型。良好的词向量可以达到语义相近的词在词向量空间里聚集在一起,这对后续的文本分类,文本聚类等等操作提供了便利,这里简单介绍词向量的训练,主要是记录学习模型和词向量的保存及一些函数用法。
一、搜狐新闻
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.txt2.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.htmlhttps://www.jianshu.com/p/87798bccee48https://blog.csdn.net/sinat_26917383/article/details/69803018
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/131448.html原文链接:https://javaforall.cn
边栏推荐
- Report on the 14th five year plan and future development trend of China's integrated circuit packaging industry Ⓓ 2022 ~ 2028
- 香港科技大学李泽湘教授:我错了,为什么工程意识比上最好的大学都重要?
- The future of game guild in decentralized games
- Redis explores cache consistency
- During Oracle CDC data transmission, the CLOB type field will lose its value during update. There is a value before update, but
- Content Audit Technology
- MySQL statistical bill information (Part 2): data import and query
- Analysis report on the development prospect and investment strategic planning of China's wafer manufacturing Ⓔ 2022 ~ 2028
- Update a piece of data from the database. Will CDC get two pieces of data with OP fields D and C at the same time? I remember before, only OP was U
- SVG钻石样式代码
猜你喜欢

我花上万学带货:3天赚3元,成交靠刷单

Hardware development notes (9): basic process of hardware development, making a USB to RS232 module (8): create asm1117-3.3v package library and associate principle graphic devices

Redis exploration: cache breakdown, cache avalanche, cache penetration

Meta enlarge again! VR new model posted on CVPR oral: read and understand voice like a human

Professor Li Zexiang, Hong Kong University of science and technology: I'm wrong. Why is engineering consciousness more important than the best university?

Feign & Eureka & Zuul & Hystrix 流程

nexus搭建npm依赖私库

Wave animation color five pointed star loader loading JS special effects

香港科技大学李泽湘教授:我错了,为什么工程意识比上最好的大学都重要?

Feign & Eureka & zuul & hystrix process
随机推荐
Analysis report on the development prospect and investment strategic planning of China's wafer manufacturing Ⓔ 2022 ~ 2028
华为HMS Core携手超图为三维GIS注入新动能
声明一个抽象类Vehicle,它包含私有变量numOfWheels和公共函数Vehicle(int)、Horn()、setNumOfWheels(int)和getNumOfWheels()。子类Mot
Some summary of pyqt5 learning (overview of the general meaning of some signals and methods)
我选的热门专业,四年后成了“天坑”
1553B环境搭建
Wang Xing's infinite game ushers in the "ultimate" battle
PG basics -- Logical Structure Management (trigger)
The future of game guild in decentralized games
There are still many things to be done in the second half of the year
10. Page layout, guess you like it
Operator-1 first acquaintance with operator
SVG钻石样式代码
ZABBIX 6.0 source code installation and ha configuration
Content Audit Technology
Nexus builds NPM dependent private database
Analysis report on the development prospect and investment strategy of the global and Chinese laser chip industry Ⓑ 2022 ~ 2027
Example code of second kill based on MySQL optimistic lock
7. Icons
北斗通信模块 北斗gps模块 北斗通信终端DTU