Home >  > Word2vec应用第一次手记

Word2vec应用第一次手记

0

测试环境:
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')终于正常了。

Snap102

代码运行了一个多小时,运行完成了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是词向量。

Snap108

五、模型测试
代码如下:

#!/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'书本')
    '''

最终的结果:
Snap109

除了word2vec,还可以用 Doc2Vec 得到文档/段落/句子的向量表达,大家可以尝试一下。

原载:蜗牛博客
网址:http://www.snailtoday.com
尊重版权,转载时务必以链接形式注明作者和原始出处及本声明。

本文暂无标签

发表评论

*

*