新手入门:训练中文维基百科词向量word2vec实验
2017-12-21 15:26
295 查看
说明:由于在学习自然语言处理,读了很多篇博文,就想着动手实验一下,本文主要参考了中英文维基百科语料上的Word2Vec实验,其中在实验阶段出现了一些预期之外的错误,参考其他博文进行了微调。这篇博文更像是篇错误整理吧。后续可能还会更新更多的错误,或者大家有什么错误都可以贴上来,一起讨论。
执行需要将xml的wiki数据转换成text数据,执行process_wiki.py脚本实现,这里注意一个问题,大多数博客中说给出的是兼容python 2.x和3.x,包括Ubuntu,其实不然,使用它们给出的脚本,
可能会报一个有意思的错误
这主要是python3中str和bytes是两种不同的东西,中文维基百科数据的获取与预处理中也提到了这一点,于是继续查询资料,在这里找到了一个和我一样的伙伴,按照他的方法,对脚本进行了修改(有兴趣的朋友可以在原脚本上修改),但还是报了错误,
查找原因,按照http://www.jb51.net/article/64816.htm上所说,应该是打开文件时编码错误,于是在
指定编码格式utf-8,修改后为
完整的process_wiki.py文件如下
以上两种process_wiki.py,总有一款适合你。
然后执行
一切正常执行,
语料库不大,所以没跑多久(用的办公电脑,渣配置,i3二代,内存8G),得到了一个大约1G的text文档wiki.zh.text,
内容格式大致为
这里推荐一款软件,几乎可以秒开G级文件,EmEditor,非常好用,如果有更好的软件,欢迎分享哦~
接下来我犯了一个错误,当时看的是英文维基百科数据的教程,直接执行了
train_word2vec_model.py代码为
按照常规程序,应该还需要对语料库进行繁简转换,分词,可以按照先前给的教程执行,这里我说一下我的运行结果。
大概跑了一个多小时吧,程序训练结束,生成了wiki.zh.text.model、wiki.zh.text.model.syn1neg.npy、wiki.zh.text.model.wv.syn0.npy、wiki.zh.text.vector等文件。
加载完成后就可以愉快地使用了,进入ipython后,首先调用gensim,如果出现了警告
可以在import gensim之前加入两行命令
由于一直看的是英文语料的教程,所以直接使用的
很自然的报错了,
然后终于意识到自己一直使用的是英文语料的教程,执行如下命令,
小tips:在执行ipython时,需先进入到model目录下,否则会报找不到该文件的错误。
会提示你该命令即将被移除了,请使用 self.wv.most_similar(),于是调用
整个调用流程如下
鉴于办公电脑配置较低(加载模型卡了十多分钟...),其他的就没有测试了,有兴趣的朋友可以多做一些测试。
值得注意的是,本人并没有按照教程上所说,进行繁简转换,以及分词,可以看到结果中,繁简体也是能够识别的,因为没有化简的结果进行对比,所以不知道是否有影响(如果词库里对于一个词既有繁体也有简体,比如“网球”、“網球”,那么对于结果肯定是有影响的)。
在重现的过程也遇到了新的问题,也算是对知识点的巩固吧,就想以这样的形式记录下来。
这是本人第一次写博客,格式有点乱,写的不清楚的地方还请大家指正,可以在评论区提出您的意见或建议~
PS:本人目前为在读研究生,研究方向为自然语言处理,数据挖掘,应用领域为中医,如果有志同道合的朋友可以一起研讨一下。
一、环境配置
WIN10 + Anaconda3,Anaconda集成了几乎所有的依赖库,如numpy、scipy和gensim,如果你是只安装了python,那么也可以参考网上教程安装这些东西,不过可能会报错,主要是版本的问题,因此我还是推荐安装Anaconda。二、中文维基百科word2vec测试
首先下载中文语料:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2,只有1.4G大小。执行需要将xml的wiki数据转换成text数据,执行process_wiki.py脚本实现,这里注意一个问题,大多数博客中说给出的是兼容python 2.x和3.x,包括Ubuntu,其实不然,使用它们给出的脚本,
#!/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
这主要是python3中str和bytes是两种不同的东西,中文维基百科数据的获取与预处理中也提到了这一点,于是继续查询资料,在这里找到了一个和我一样的伙伴,按照他的方法,对脚本进行了修改(有兴趣的朋友可以在原脚本上修改),但还是报了错误,
UnicodeEncodeError: 'gbk' codec can't encode character '\xf6' in position 89
查找原因,按照http://www.jb51.net/article/64816.htm上所说,应该是打开文件时编码错误,于是在
output = open(outp, 'w')
指定编码格式utf-8,修改后为
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 4000 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 articles 2016-07-28 10:49:44,660: INFO: Saved 20000 articles 2016-07-28 10:51:04,023: INFO: Saved 30000 articles 2016-07-28 10:52:13,199: INFO: Saved 40000 articles 2016-07-28 10:53:07,548: INFO: Saved 50000 articles 2016-07-28 10:53:45,695: INFO: Saved 60000 articles 2016-07-28 10:54:18,993: INFO: Saved 70000 articles 2016-07-28 10:54:51,188: INFO: Saved 80000 articles 2016-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")
可以在import gensim之前加入两行命令
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:本人目前为在读研究生,研究方向为自然语言处理,数据挖掘,应用领域为中医,如果有志同道合的朋友可以一起研讨一下。
相关文章推荐
- torch入门笔记11:如何训练神经网络
- 机器学习入门(三):caffe训练过程概况和caffe.bin命令选项
- 新手入门:了解ftp服务与ftp协议(图)
- 蓝桥杯 入门训练 Fibonacci数列(1)
- 蓝桥杯:入门训练 圆的面积
- Uboot新手入门
- JAVA从菜鸟【入门】到新手【实习】一一Python项目实战学习规划
- WinForm调用WebService简单实例详解【新手入门】
- 刚入门新手求帮助!
- Android新手入门2016(7)--布局
- 蓝桥杯-入门训练-圆的面积
- 新手入门:巧用Webbrowser实现网络数据采集
- [转载]新手入门:Spring的一些学习方法及意见
- Java新手入门的30个基本概念
- C#新手入门代码 知道类实例化的个数
- 入门训练 Fibonacci数列
- 平面设计入门新手需看技巧
- Vue.js新手入门知识点
- 网络游戏程序员新手入门 [转]
- linux新手学习之Arch Linux入门经验分享