wikipedia 训练繁体中文 embedding(word2vec)模型

由于课题任务需要一个繁体中文的word3vec, 折腾经过记录在此。希望以后少掉几个坑。
训练好的embedding放在网盘中, 密码:2um0

原文发布于个人博客(好望角),那里有更好的阅读体验。


get wiki

最新的wiki datas下载地址,目前有1.6G大小。

里面的内容以XML格式保存。节点信息如下:

<page>
  <title></title>
  <id></id>
  <timestamp></timestamp>
  <username></username>
  <comment></comment>
  <text xml:space="preserve"></text>
</page>
初步处理

直接解压真的太蠢了。
为了节省时间,免去自己写代码处理Wiki的烦恼,Wikipedia Extractor先初步处理。(服务器非root用户,安装命令加上--user

git clone https://github.com/attardi/wikiextractor.git wikiextractor
cd wikiextractor
python setup.py install --user
python WikiExtractor.py -b 1024M -o extracted zhwiki-latest-pages-articles.xml.bz2

执行过程如下,可以看到一共处理了1012693篇文章,输出如下所示:

INFO: 6205533   手語新聞
INFO: 6205536   班傑明·古根海姆
INFO: 6205549   同意
INFO: 6205556   2018年荷蘭網路監控法公民投票
INFO: 6205594   李儒新
INFO: 6205610   深圳信息职业技术学院
INFO: 6205626   停下來等著你 (2018年電視劇)
INFO: 6205642   簡單矩陣的快速演算法設計
INFO: 6205644   斯義桂
INFO: 6205646   焦耳效应
INFO: 6205648   1925年世界大賽
INFO: 6205653   True (方力申專輯)
INFO: 6205657   华睿2号
INFO: 6205664   河內郡 (大阪府)
INFO: 6205691   京都寺町三条商店街的福爾摩斯
INFO: 6205675   莫莉·比什死亡事件
INFO: 6205703   都筑郡
INFO: 6205701   皇座法庭所屬分庭庭長
INFO: 6205709   冬瓜餅
INFO: 6205710   吸血鬼莫比亞斯
INFO: 6205712   淘綾郡
INFO: 6205714   明石香織
INFO: Finished 71-process extraction of 1012693 articles in 1114.1s (909.0 art/s)

通过以上抽取后得到两个文件wiki_00wiki_01。里面的格式类似下面

<doc id="5323477" url="https://zh.wikipedia.org/wiki?curid=5323477" title="結構與能動性">
文章内容
</doc>

在上面的基础上,我们在去掉一些不需要的特殊符号。

import re
import sys
import codecs
def filte(input_file):
    p5 = re.compile('<doc (.*)>')
    p6 = re.compile('</doc>')
    outfile = codecs.open('std_' + input_file, 'w', 'utf-8')
    with codecs.open(input_file, 'r', 'utf-8') as myfile:
        for line in myfile:
            line = p5.sub('', line)
            line = p6.sub('', line)
            outfile.write(line)
    outfile.close()
if __name__ == '__main__':
filte(input_file)
    input_file = sys.argv[1]
繁体转简体

首先安装opencc-python
网上一大堆教程,全是深坑!其实直接按照代码仓库作者的方法安装就好了。

git clone https://github.com/yichen0831/opencc-python.git
cd opencc-python
python setup.py install --user

但是,如果追求效率,可以安装opencc C++ 版本,python代码的效率堪忧。

看文档不难发现,繁体字也分为香港区和台湾省,要用怎么样的转换看具体需求就好

from opencc import OpenCC

opencc = OpenCC('s2hk')
for filename in ['wiki_01','wiki_00']:
    with open('std_'+filename,'r',encoding='utf-8') as fin, open('hk_'+filename,'w',encoding='utf-8') as fou:
        for index , line in enumerate(fin.readlines()):
            hk = opencc.convert(line)
            if index % 10000 == 0:
                print(index,hk)
            fou.write(hk)

得到了两个文件分别大小为 1024M154M

jieba Segment

先把两个wiki文件合并cat hk_wiki_00 hk_wiki_01 > hk_wiki

python -m jieba -d " " ./hk_wiki > ./SegHk_wiki
train word2vec

运行下面写好的脚本,

# -*- coding: utf-8 -*-
from gensim.models import word2vec
from gensim.models import KeyedVectors
import logging
import os

if not os.path.exists('./word2vec_tradiCN/'):
    os.makedirs('./word2vec_tradiCN/')

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.LineSentence('./SegHk_wiki')

for number in [50,100,200,300]:
    model = word2vec.Word2Vec(sentences,size=number,window=5,min_count=5,workers=20)
    # min-count 表示设置最低频率,默认为5,如果一个词语在文档中出现的次数小于该阈值,那么该词就会被舍弃; size代表词词向量的维度
    # 为了后续建模读取vector方便,我们的保存格式应该和glove vector 保持一致
    model.wv.save_word2vec_format('./word2vec_tradiCN/Wiki'+str(number)+'.txt', binary=False)

然而出现了Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.这个错误
运行conda install nomkl安装nomkl,这是anaconda的问题。

test word2vec

如果用python2,运行下面的测试脚本可能会出现如下错误KeyError: "word '\xe7\xb8\xbd\xe7\xb5\xb1' not in vocabulary"
这个是python2对于中文的支持不太友好造成的,用python3即可表现正常。

# -*- coding: utf-8 -*-
from gensim.models.keyedvectors import KeyedVectors
for number in [50,100,200,300]:
    wv = KeyedVectors.load_word2vec_format('./word2vec_tradiCN/Wiki'+ str(number)+'.txt', binary=False)
    print(number, wv.similarity('總統','民國')) #两个词的相关性
    print(number, wv.most_similar(['倫敦','中國'],['北京']),'\n\n') # 北京is to中国 as 伦敦is to?
  • 注意,繁体中文,测试的时候也要用繁体的
  • 这里直接测试了四组不同大小的embedding,可以对比效果。以这个简单的测试来说,200d embedding效果比较好。
  • 当然,在实际中,效果怎么样,还是要实际测试。
50 0.08906988
50 [('美國', 0.8497380614280701), ('英國', 0.8156374096870422), ('荷蘭', 0.7635571956634521), ('加拿大', 0.7618951201438904), ('蘇格蘭', 0.7564111948013306), ('法國', 0.7498287558555603), ('冰島', 0.7447660565376282), ('愛爾蘭', 0.7290477752685547), ('德國', 0.7261558175086975), ('哥倫比亞', 0.715803861618042)]


100 0.0021609096
100 [('英國', 0.7518529891967773), ('美國', 0.716768741607666), ('蘇格蘭', 0.706271767616272), ('德國', 0.6398693323135376), ('法國', 0.6289862394332886), ('愛爾蘭', 0.6286278963088989), ('荷蘭', 0.6277433633804321), ('英格蘭', 0.625410795211792), ('加拿大', 0.6076068878173828), ('威爾斯', 0.6075741052627563)]


200 0.044366393
200 [('英國', 0.6959728598594666), ('蘇格蘭', 0.6404226422309875), ('美國', 0.6401909589767456), ('英格蘭', 0.6158463358879089), ('愛爾蘭', 0.5740842223167419), ('德國', 0.5558757781982422), ('威爾斯', 0.5539498925209045), ('法國', 0.5375431776046753), ('荷蘭', 0.5276069641113281), ('威爾士', 0.5051602721214294)]


300 0.034565542
300 [('英國', 0.6512337923049927), ('蘇格蘭', 0.5884094834327698), ('英格蘭', 0.5666802525520325), ('美國', 0.5420516729354858), ('愛爾蘭', 0.5202239751815796), ('威爾斯', 0.48060378432273865), ('荷蘭', 0.4763559103012085), ('德國', 0.4744102358818054), ('法國', 0.4675533175468445), ('北愛爾蘭', 0.46320733428001404)]
网盘链接

训练好的四个embedding包含892594个词,都放到了网盘中,可以按需下载。 密码:2um0

参考文献

word2vec实战:获取和预处理中文维基百科(Wikipedia)语料库,并训练成word2vec模型

猜你喜欢

转载自blog.csdn.net/huhehaotechangsha/article/details/81171619