说明:由于在学习自然语言处理,读了很多篇博文,就想着动手实验一下,本文主要参考了中英文*语料上的Word2Vec实验,其中在实验阶段出现了一些预期之外的错误,参考其他博文进行了微调。这篇博文更像是篇错误整理吧。后续可能还会更新更多的错误,或者大家有什么错误都可以贴上来,一起讨论。
一、环境配置
WIN10 + Anaconda3,Anaconda集成了几乎所有的依赖库,如numpy、scipy和gensim,如果你是只安装了python,那么也可以参考网上教程安装这些东西,不过可能会报错,主要是版本的问题,因此我还是推荐安装Anaconda。
二、中文*word2vec测试
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Pan Yang (panyangnlp@gmail.com)
# Copyrigh 2017
from __future__ import print_function
import logging
import os.path
import six
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))
# check and process input arguments
if len(sys.argv) != 3:
print("Using: python process_wiki.py enwiki.xxx.xml.bz2 wiki.en.text")
sys.exit(1)
inp, outp = sys.argv[1:3]
space = " "
i = 0
output = open(outp, 'w')
wiki = WikiCorpus(inp, lemmatize=False, dictionary={})
for text in wiki.get_texts():
if six.PY3:
output.write(b' '.join(text).decode('utf-8') + '\n')
# ###another method###
# output.write(
# space.join(map(lambda x:x.decode("utf-8"), text)) + '\n')
else:
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")
(C:\Anaconda3) E:\NLP\word2vec-for-wiki-master>python process_wiki.py enwiki-latest-pages-articles.xml.bz2 wiki.en.text
Traceback (most recent call last):
File "process_wiki.py", line 30, in <module>
output.write(space.join(text).decode() + '\n')
TypeError: sequence item 0: expected str instance, bytes found
UnicodeEncodeError: 'gbk' codec can't encode character '\xf6' in position 89
output = open(outp, 'w')
output = open(outp, 'w', encoding='utf-8')
完整的process_wiki.py文件如下
# -*- coding: utf-8 -*-
__author__ = 'huang'
import os
import logging
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)
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', encoding='utf-8')
wiki = WikiCorpus(inp, lemmatize=False, dictionary={})
for text in wiki.get_texts():
data = space.join(text)
output.write(str(data) + '\n')
i = i + 1
if i % 10000 == 0:
logger.info('Saved ' + str(i) + ' articles')
output.close()
logger.info('Finished ' + str(i) + ' articles')
以上两种process_wiki.py,总有一款适合你。
然后执行
python process_wiki.py enwiki-latest-pages-articles.xml.bz2 wiki.en.text
一切正常执行,
语料库不大,所以没跑多久(用的办公电脑,渣配置,i3二代,内存8G),得到了一个大约1G的text文档wiki.zh.text,
内容格式大致为
歐幾里得 西元前三世紀的希臘數學家 現在被認為是幾何之父 此畫為拉斐爾的作品 雅典學院
数学 是利用符号语言研究數量 结构 变化以及空间等概念的一門学科 从某种角度看屬於形式科學的一種
數學透過抽象化和邏輯推理的使用 由計數 計算 數學家們拓展這些概念
對數學基本概念的完善 早在古埃及 而在古希臘那裡有更為嚴謹的處理 從那時開始
數學的發展便持續不斷地小幅進展 世紀的文藝復興時期 致使數學的加速发展 直至今日 今日 數學使用在不同的領域中 包括科學 工程
2016-07-28 10:48:11,057: INFO: Saved 10000 articles2016-07-28 10:49:44,660: INFO: Saved 20000 articles2016-07-28 10:51:04,023: INFO: Saved 30000 articles2016-07-28 10:52:13,199: INFO: Saved 40000 articles2016-07-28 10:53:07,548: INFO: Saved 50000 articles2016-07-28 10:53:45,695: INFO: Saved 60000 articles2016-07-28 10:54:18,993: INFO: Saved 70000 articles2016-07-28 10:54:51,188: INFO: Saved 80000 articles2016-07-28 10:55:50,520: INFO: Saved 90000 articles····
这里推荐一款软件,几乎可以秒开G级文件,EmEditor,非常好用,如果有更好的软件,欢迎分享哦~
接下来我犯了一个错误,当时看的是英文*数据的教程,直接执行了
python train_word2vec_model.py wiki.en.text wiki.en.text.model wiki.en.text.vector
train_word2vec_model.py代码为
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import os
import sys
import multiprocessing
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
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)
inp, outp1, outp2 = sys.argv[1:4]
model = Word2Vec(LineSentence(inp), size=400, window=5, min_count=5,
workers=multiprocessing.cpu_count())
# trim unneeded model memory = use(much) less RAM
# model.init_sims(replace=True)
model.save(outp1)
model.wv.save_word2vec_format(outp2, binary=False)
按照常规程序,应该还需要对语料库进行繁简转换,分词,可以按照先前给的教程执行,这里我说一下我的运行结果。
大概跑了一个多小时吧,程序训练结束,生成了wiki.zh.text.model、wiki.zh.text.model.syn1neg.npy、wiki.zh.text.model.wv.syn0.npy、wiki.zh.text.vector等文件。 加载完成后就可以愉快地使用了,进入ipython后,首先调用gensim,如果出现了警告In [1]: import gensim
C:\Anaconda3\lib\site-packages\gensim\utils.py:860: UserWarning: detected Windows; aliasing chunkize to chunkize_serial
warnings.warn("detected Windows; aliasing chunkize to chunkize_serial")
In [1]: import warnings
In [2]: warnings.filterwarnings(action='ignore',category=UserWarning,module='gensim')
In [3]: import gensim
In [4]:
由于一直看的是英文语料的教程,所以直接使用的
model = gensim.models.Word2Vec.load_word2vec_format("wiki.en.text.vector", binary=False)
很自然的报错了,
UnpicklingError: could not find MARK
然后终于意识到自己一直使用的是英文语料的教程,执行如下命令,
model = gensim.models.Word2Vec.load("wiki.zh.text.model")
小tips:在执行ipython时,需先进入到model目录下,否则会报找不到该文件的错误。
model.most_similar(u"足球")
会提示你该命令即将被移除了,请使用 self.wv.most_similar(),于是调用
result = model.wv.most_similar(u'足球')
整个调用流程如下
In [1]: import warnings
In [2]: warnings.filterwarnings(action='ignore',category=UserWarning,module='gensim')
In [3]: import gensim
In [4]: model = gensim.models.Word2Vec.load("wiki.zh.text.model")
In [5]: result = model.wv.most_similar(u'足球')
In [6]: for e in result:
...: print(e)
...:
('籃球', 0.9209551811218262)
('排球', 0.9010016918182373)
('棒球', 0.8731895685195923)
('高爾夫球', 0.8449806571006775)
('網球', 0.843244194984436)
('橄欖球', 0.8404449820518494)
('板球', 0.8161724805831909)
('高爾夫', 0.8071038722991943)
('欖球', 0.8043543696403503)
('滑雪', 0.8014159202575684)
鉴于办公电脑配置较低(加载模型卡了十多分钟...),其他的就没有测试了,有兴趣的朋友可以多做一些测试。
值得注意的是,本人并没有按照教程上所说,进行繁简转换,以及分词,可以看到结果中,繁简体也是能够识别的,因为没有化简的结果进行对比,所以不知道是否有影响(如果词库里对于一个词既有繁体也有简体,比如“网球”、“網球”,那么对于结果肯定是有影响的)。
3、结语
撰写博客已经是在实验之后了,为了写的清楚一些,特地重现了一遍实验,导致电脑又卡死一次。在重现的过程也遇到了新的问题,也算是对知识点的巩固吧,就想以这样的形式记录下来。
这是本人第一次写博客,格式有点乱,写的不清楚的地方还请大家指正,可以在评论区提出您的意见或建议~
PS:本人目前为在读研究生,研究方向为自然语言处理,数据挖掘,应用领域为中医,如果有志同道合的朋友可以一起研讨一下。