测试环境:
win7 ultimate(en)
Anaconda 3
一、安装Word2vec
Word2vec需要使用第三方gensim模块, gensim模块依赖numpy和scipy两个包,因此需要依次下载对应版本的numpy、scipy、gensim。
不过如果你使用Anaconda的话,前两个包已经安装好了,可能直接使用pip命令安装第三个包即可。
二、下载训练数据
下载地址如下:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2
三、转换数据格式
解压后的数据是一个XML文件,而我们在Word2vec中使用的数据需要是txt格式的,所以必须进行转换,代码如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- #将xml的wiki数据转换为text格式 import logging import os.path import sys from gensim.corpora import WikiCorpus 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)) if len(sys.argv) < 3: print(globals()['__doc__'] % locals()) sys.exit(1) inp, outp = sys.argv[1:3] space = " " i = 0 output = open(outp, 'w') wiki =WikiCorpus(inp, lemmatize=False, dictionary=[])#gensim里的维基百科处理类WikiCorpus for text in wiki.get_texts():#通过get_texts将维基里的每篇文章转换位1行text文本,并且去掉了标点符号等内容 output.write(space.join(text) + "\n") i = i+1 if (i % 10000 == 0): logger.info("Saved "+str(i)+" articles.") output.close() logger.info("Finished Saved "+str(i)+" articles.")
没想到第一次运行失败,出现了“UnicodeEncodeError: 'gbk' codec can't encode character '\xf6' in position 892: i llegal multibyte sequence”的出错信息。
后来将output = open(outp, 'w')改成output = open(outp, 'w',,encoding='utf-8')终于正常了。
代码运行了一个多小时,运行完成了30万篇文章。
四、繁体转换
由于数据中包含有繁体文字,所以我们要用opencc将所有繁体字转换成简体字。
先下载opencc,再解压缩,然后将步骤三生成的文件复制到opencc文件夹,并在这个文件夹打开dos窗口(Shift+鼠标右键->在此处打开命令窗口),输入如下命令行:
opencc -i wiki.zh.txt -o wiki.zh.simp.txt -c t2s.json
几分钟后,会生成一个新的文件,即转成了简体中文的文件。
下载opencc,网址:https://bintray.com/package/files/byvoid/opencc/OpenCC
五、查看文件
我们的txt文件有1G多,用记事本之类的打开容易死机,可以用python自带的IO进行读取。
import codecs,sys f = codecs.open(‘wiki.zh.simp.txt‘,‘r‘,encoding="utf8") line = f.readline() print(line)
可以看到,原来的繁体已经转化成简体中文了。
六、分词
利用结巴分词进行分词处理,大约需要半个钟。
# -*- coding: utf-8 -*- #逐行读取文件数据进行jieba分词 import jieba import jieba.analyse import jieba.posseg as pseg #引入词性标注接口 import codecs,sys if __name__ == '__main__': f = codecs.open('wiki.zh.simp.txt', 'r', encoding='utf8') target = codecs.open('wiki.zh.simp.seg.txt', 'w', encoding='utf8') print ('open files.') lineNum = 1 line = f.readline() while line: print ('---processing ',lineNum,' article---') seg_list = jieba.cut(line,cut_all=False) line_seg = ' '.join(seg_list) target.writelines(line_seg) lineNum = lineNum + 1 line = f.readline() print ('well done.') f.close() target.close()
7、Word2Vec模型训练
代码如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- #使用gensim word2vec训练脚本获取词向量 import warnings warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')# 忽略警告 import logging import os.path import sys import multiprocessing from gensim.corpora import WikiCorpus from gensim.models import Word2Vec from gensim.models.word2vec import LineSentence if __name__ == '__main__': #print open('/Users/sy/Desktop/pyRoot/wiki_zh_vec/cmd.txt').readlines() #sys.exit() 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为原始c版本word2vec的vector格式的模型 fdir = '/Users/sy/Desktop/pyRoot/wiki_zh_vec/' inp = fdir + 'wiki.zh.simp.seg.txt' outp1 = fdir + 'wiki.zh.text.model' outp2 = fdir + 'wiki.zh.text.vector' # 训练skip-gram模型 model = Word2Vec(LineSentence(inp), size=400, window=5, min_count=5, workers=multiprocessing.cpu_count()) # 保存模型 model.save(outp1) model.wv.save_word2vec_format(outp2, binary=False)
代码运行完成后得到如下四个文件,其中wiki.zh.text.model是建好的模型,wiki.zh.text.vector是词向量。
五、模型测试
代码如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- #测试训练好的模型 import warnings warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')# 忽略警告 import sys reload(sys) sys.setdefaultencoding('utf8') import gensim if __name__ == '__main__': fdir = '/Users/sy/Desktop/pyRoot/wiki_zh_vec/' model = gensim.models.Word2Vec.load(fdir + 'wiki.zh.text.model') word = model.most_similar(u"足球") for t in word: print(t[0],t[1]) ''' word = model.most_similar(positive=[u'皇上',u'国王'],negative=[u'皇后']) for t in word: print t[0],t[1] print model.doesnt_match(u'太后 妃子 贵人 贵妃 才人'.split()) print model.similarity(u'书籍',u'书本') print model.similarity(u'逛街',u'书本') '''
最终的结果:
除了word2vec,还可以用 Doc2Vec 得到文档/段落/句子的向量表达,大家可以尝试一下。
原载:蜗牛博客
网址:http://www.snailtoday.com
尊重版权,转载时务必以链接形式注明作者和原始出处及本声明。