赞
踩
词向量作为文本的基本结构——词的模型。良好的词向量可以达到语义相近的词在词向量空间里聚集在一起,这对后续的文本分类,文本聚类等等操作提供了便利,这里简单介绍词向量的训练,主要是记录学习模型和词向量的保存及一些函数用法。
本文采用的是搜狗实验室的搜狗新闻语料库,数据链接 http://www.sogou.com/labs/resource/cs.php
下载下来的文件名为: news_sohusite_xml.full.tar.gz
(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
送给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)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
分词的结果是:
并且会保存3个文件:
corpusSegDone_1.txt
corpusSegDone_1.model
corpusSegDone_1.vector
由于这里运行需要一段时间,所以没有进行验证测试。
由于训练需要一定的时间,所以这里只讲下思路。
维基百科数据量不够大,百度百科数据量较全面,内容上面百度百科大陆相关的信息比较全面,港澳台和国外相关信息维基百科的内容比较详细,因此训练时将两个语料一起投入训练,形成互补,另外还加入了1.1万公司行业数据
模型:gensim工具包word2vec模型,安装使用简单,训练速度快
语料:百度百科500万词条+维基百科30万词条+1.1万条领域数据
分词:jieba分词,自定义词典加入行业词,去除停用词
硬件:根据自己的电脑硬件而定
分词代码:
# 多线程分词 # 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
使用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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
import gensim
model = gensim.models.Word2Vec(documents, size=300)
model.train(documents, total_examples=len(documents), epochs=10)
model.save("../input/Word2vec.w2v")
- 1
- 2
- 3
- 4
加载词向量
import gensim
word2vec = gensim.models.word2vec.Word2Vec.load("./input/Quora.w2v").wv
- 1
- 2
保存词向量
model.wv.save_Word2Vec_format(embedding_path,binary=True)
#model.wv.save_Word2Vec_format(embedding_path,binary=False)非二进制
- 1
- 2
加载词向量
import gensim
word2vec = gensim.models.KeyedVectors.load_word2vec_format(embedding_path,binary=True)
- 1
- 2
保存数组数据的文件可以是二进制格式或者文本格式,二进制格式的文件可以是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')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
(2)gensim.models.Word2Vec.load的办法导入
model = gensim.models.Word2Vec.load('xxx/word2vec_wx')
pd.Series(model.most_similar(u'微信',topn = 360000))
- 1
- 2
(3)Numpy的话可以用numpy.load:
import numpy
word_2x = numpy.load('xxx/word2vec_wx.wv.syn0.npy')
- 1
- 2
(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
- 1
- 2
- 3
增量训练
# 增量训练
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。