基于Gensim的维基百科语料库中文词向量训练

环境:  
Win10 +Anaconda(自带Python3.6) 
IDE: 
Pycharm (其Interperter使用的是Anaconda自带的Python3.6)

安装Gensim库:
在Anaconda Prompt中输入:
pip install gensim 
等待其显示安装完毕即可

1.首先获取维基百科语料库资源
我是在其中下载的当时最新的压缩文件
注:文件名在网站中的结尾为xml.bz2

2.将wiki的xml文件处理成正常的txt文件
需要用特殊的脚本处理而不能直接压缩(与维基百科保存格式有关)
github中有更为全面的WikiExtractor
有兴趣可以去研究一下
此处直接使用普通压缩文件to txt处理脚本即可
代码如下:

     
     
  1. import logging
  2. import os.path
  3. import sys
  4. from gensim.corpora import WikiCorpus
  5. if __name__ == '__main__':
  6. program = os.path.basename(sys.argv[ 0])
  7. logger = logging.getLogger(program)
  8. logging.basicConfig(format= '%(asctime)s: %(levelname)s: %(message)s')
  9. logging.root.setLevel(level=logging.INFO)
  10. logger.info( "running %s" % ' '.join(sys.argv))
  11. # check and process input arguments
  12. if len(sys.argv) < 3:
  13. print(globals()[ '__doc__'] % locals())
  14. sys.exit( 1)
  15. inp, outp = sys.argv[ 1: 3]
  16. space = b' '
  17. i = 0
  18. output = open(outp, 'w',encoding= 'utf-8')
  19. wiki = WikiCorpus(inp, lemmatize= False, dictionary={})
  20. for text in wiki.get_texts():
  21. s = space.join(text)
  22. s = s.decode( 'utf8') + "\n"
  23. output.write(s)
  24. i = i + 1
  25. if (i % 10000 == 0):
  26. logger.info( "Saved " + str(i) + " articles")
  27. output.close()
  28. logger.info( "Finished Saved " + str(i) + " articles")
使用process.py脚本(即以上代码) 将维基百科的下载文件转化成text文件
在命令行中输入
python process.py zhwiki-latest-pages-articles.xml.bz2 wiki.zh.text

就可以看到正在解压的过程了,过程还是需要不少时间的
部分生成结果:

需要注意
文件可能过大而无法打开

3.使用opencc将繁体txt转换为简体txt
下载地址:
无需安装,解压即可使用
将我们前面生成的wiki.zh.text拖动至opencc-1.0.1-win64文件夹中,打开cmd并在当前文件夹中输入如下指令:
opencc -i wiki.zh.text -o wiki.zh.jian.text -c t2s.json
这一步骤非常快,我只用了1分钟不到
然后可以看到目录中生成了wiki.zh.jian.text文件
打开后可以查看其中内容

可以看到已经成功全部转化为了简体字
但是做词向量训练之前仍缺少最后一步,就是分词

4.分词
英文中空格就已经将其句子分词完毕
而中文就相对复杂,但我们可以借助jieba库来分词
在Testjieba.py中分词
打开wiki.zh.jian.text,从该文件中一行行读取简体字并进行分词,分词结果放在zh.jian.wiki.seg.txt中
代码如下:


     
     
  1. import jieba
  2. import jieba.analyse
  3. import jieba.posseg as pseg
  4. import codecs, sys
  5. def cut_words(sentence):
  6. #print sentence
  7. return " ".join(jieba.cut(sentence)).encode( 'utf-8')
  8. f = codecs.open( 'wiki.zh.jian.text', 'r', encoding= "utf8")
  9. target = codecs.open( "zh.jian.wiki.seg.txt", 'w', encoding= "utf8")
  10. print( 'open files')
  11. line_num = 1
  12. line = f.readline()
  13. while line:
  14. print( '---- processing ', line_num, ' article----------------')
  15. line_seg = " ".join(jieba.cut(line))
  16. target.writelines(line_seg)
  17. line_num = line_num + 1
  18. line = f.readline()
  19. f.close()
  20. target.close()
  21. exit()
  22. while line:
  23. curr = []
  24. for oneline in line:
  25. #print(oneline)
  26. curr.append(oneline)
  27. after_cut = map(cut_words, curr)
  28. target.writelines(after_cut)
  29. print( 'saved', line_num, 'articles')
  30. exit()
  31. line = f.readline1()
  32. f.close()
  33. target.close()

每一行读入后进行每一行的分词
直接运行该py文件即可(注意将 在opencc文件夹中生成的wiki.zh.jian.text放入Testjieba.py所在文件夹)
查看分词结果如下:

5.进行词向量训练
创建词向量结果模型代码如下:


     
     
  1. from __future__ import print_function
  2. import logging
  3. import os
  4. import sys
  5. import multiprocessing
  6. from gensim.models import Word2Vec
  7. from gensim.models.word2vec import LineSentence
  8. if __name__ == '__main__':
  9. program = os.path.basename(sys.argv[ 0])
  10. logger = logging.getLogger(program)
  11. logging.basicConfig(format= '%(asctime)s: %(levelname)s: %(message)s')
  12. logging.root.setLevel(level=logging.INFO)
  13. logger.info( "running %s" % ' '.join(sys.argv))
  14. # check and process input arguments
  15. if len(sys.argv) < 4:
  16. print( "Useing: python train_word2vec_model.py input_text "
  17. "output_gensim_model output_word_vector")
  18. sys.exit( 1)
  19. inp, outp1, outp2 = sys.argv[ 1: 4]
  20. model = Word2Vec(LineSentence(inp), size= 200, window= 5, min_count= 5,
  21. workers=multiprocessing.cpu_count())
  22. model.save(outp1)
  23. model.wv.save_word2vec_format(outp2, binary= False)
其中
model = Word2Vec(LineSentence(inp), size=200, window=5, min_count=5,
    workers=multiprocessing.cpu_count())
代码是训练词向量的关键,定义了滑动窗口大小与最小有效词数量
并在下方保存word2vec格式的模型

在命令行中输入
python word2vec_model.py zh.jian.wiki.seg.txt wiki.zh.model wiki.zh.text.vector
源文件为zh.jian.wiki.seg.txt
目标文件为wiki.zh.model

训练时间大致为25分钟(1080Ti训练结果下)

6.测试训练模块成果
代码如下


     
     
  1. from gensim.models import Word2Vec
  2. en_wiki_word2vec_model = Word2Vec.load( 'wiki.zh.model')
  3. testwords = [ '孩子', '数学', '学术', '白痴', '篮球']
  4. for i in range( 5):
  5. res = en_wiki_word2vec_model.most_similar(testwords[i])
  6. print(testwords[i])
  7. print(res)

首先导入gensim.models中的Word2Vec模块

然后使用Word2Vec模块中方法加载模块,之后便可以使用其中的most_similar方法进行词向量寻找并打印结果

测试结果展示:


总结:
可以看到还是大部分make sense的
但是也有一些词不太相近或者更相近的答案而并非首选。
很大一部分原因是因为语料库的不足,因为语料库中资料仅有1.3G,对于中文训练来说是大大不足的。
环境:  
Win10 +Anaconda(自带Python3.6) 
IDE: 
Pycharm (其Interperter使用的是Anaconda自带的Python3.6)

安装Gensim库:
在Anaconda Prompt中输入:
pip install gensim 
等待其显示安装完毕即可

1.首先获取维基百科语料库资源
我是在其中下载的当时最新的压缩文件
注:文件名在网站中的结尾为xml.bz2

2.将wiki的xml文件处理成正常的txt文件
需要用特殊的脚本处理而不能直接压缩(与维基百科保存格式有关)
github中有更为全面的WikiExtractor
有兴趣可以去研究一下
此处直接使用普通压缩文件to txt处理脚本即可
代码如下:

  
  
  1. import logging
  2. import os.path
  3. import sys
  4. from gensim.corpora import WikiCorpus
  5. if __name__ == '__main__':
  6. program = os.path.basename(sys.argv[ 0])
  7. logger = logging.getLogger(program)
  8. logging.basicConfig(format= '%(asctime)s: %(levelname)s: %(message)s')
  9. logging.root.setLevel(level=logging.INFO)
  10. logger.info( "running %s" % ' '.join(sys.argv))
  11. # check and process input arguments
  12. if len(sys.argv) < 3:
  13. print(globals()[ '__doc__'] % locals())
  14. sys.exit( 1)
  15. inp, outp = sys.argv[ 1: 3]
  16. space = b' '
  17. i = 0
  18. output = open(outp, 'w',encoding= 'utf-8')
  19. wiki = WikiCorpus(inp, lemmatize= False, dictionary={})
  20. for text in wiki.get_texts():
  21. s = space.join(text)
  22. s = s.decode( 'utf8') + "\n"
  23. output.write(s)
  24. i = i + 1
  25. if (i % 10000 == 0):
  26. logger.info( "Saved " + str(i) + " articles")
  27. output.close()
  28. logger.info( "Finished Saved " + str(i) + " articles")
使用process.py脚本(即以上代码) 将维基百科的下载文件转化成text文件
在命令行中输入
python process.py zhwiki-latest-pages-articles.xml.bz2 wiki.zh.text

就可以看到正在解压的过程了,过程还是需要不少时间的
部分生成结果:

需要注意
文件可能过大而无法打开

3.使用opencc将繁体txt转换为简体txt
下载地址:
无需安装,解压即可使用
将我们前面生成的wiki.zh.text拖动至opencc-1.0.1-win64文件夹中,打开cmd并在当前文件夹中输入如下指令:
opencc -i wiki.zh.text -o wiki.zh.jian.text -c t2s.json
这一步骤非常快,我只用了1分钟不到
然后可以看到目录中生成了wiki.zh.jian.text文件
打开后可以查看其中内容

可以看到已经成功全部转化为了简体字
但是做词向量训练之前仍缺少最后一步,就是分词

4.分词
英文中空格就已经将其句子分词完毕
而中文就相对复杂,但我们可以借助jieba库来分词
在Testjieba.py中分词
打开wiki.zh.jian.text,从该文件中一行行读取简体字并进行分词,分词结果放在zh.jian.wiki.seg.txt中
代码如下:


  
  
  1. import jieba
  2. import jieba.analyse
  3. import jieba.posseg as pseg
  4. import codecs, sys
  5. def cut_words(sentence):
  6. #print sentence
  7. return " ".join(jieba.cut(sentence)).encode( 'utf-8')
  8. f = codecs.open( 'wiki.zh.jian.text', 'r', encoding= "utf8")
  9. target = codecs.open( "zh.jian.wiki.seg.txt", 'w', encoding= "utf8")
  10. print( 'open files')
  11. line_num = 1
  12. line = f.readline()
  13. while line:
  14. print( '---- processing ', line_num, ' article----------------')
  15. line_seg = " ".join(jieba.cut(line))
  16. target.writelines(line_seg)
  17. line_num = line_num + 1
  18. line = f.readline()
  19. f.close()
  20. target.close()
  21. exit()
  22. while line:
  23. curr = []
  24. for oneline in line:
  25. #print(oneline)
  26. curr.append(oneline)
  27. after_cut = map(cut_words, curr)
  28. target.writelines(after_cut)
  29. print( 'saved', line_num, 'articles')
  30. exit()
  31. line = f.readline1()
  32. f.close()
  33. target.close()

每一行读入后进行每一行的分词
直接运行该py文件即可(注意将 在opencc文件夹中生成的wiki.zh.jian.text放入Testjieba.py所在文件夹)
查看分词结果如下:

5.进行词向量训练
创建词向量结果模型代码如下:


  
  
  1. from __future__ import print_function
  2. import logging
  3. import os
  4. import sys
  5. import multiprocessing
  6. from gensim.models import Word2Vec
  7. from gensim.models.word2vec import LineSentence
  8. if __name__ == '__main__':
  9. program = os.path.basename(sys.argv[ 0])
  10. logger = logging.getLogger(program)
  11. logging.basicConfig(format= '%(asctime)s: %(levelname)s: %(message)s')
  12. logging.root.setLevel(level=logging.INFO)
  13. logger.info( "running %s" % ' '.join(sys.argv))
  14. # check and process input arguments
  15. if len(sys.argv) < 4:
  16. print( "Useing: python train_word2vec_model.py input_text "
  17. "output_gensim_model output_word_vector")
  18. sys.exit( 1)
  19. inp, outp1, outp2 = sys.argv[ 1: 4]
  20. model = Word2Vec(LineSentence(inp), size= 200, window= 5, min_count= 5,
  21. workers=multiprocessing.cpu_count())
  22. model.save(outp1)
  23. model.wv.save_word2vec_format(outp2, binary= False)
其中
model = Word2Vec(LineSentence(inp), size=200, window=5, min_count=5,
    workers=multiprocessing.cpu_count())
代码是训练词向量的关键,定义了滑动窗口大小与最小有效词数量
并在下方保存word2vec格式的模型

在命令行中输入
python word2vec_model.py zh.jian.wiki.seg.txt wiki.zh.model wiki.zh.text.vector
源文件为zh.jian.wiki.seg.txt
目标文件为wiki.zh.model

训练时间大致为25分钟(1080Ti训练结果下)

6.测试训练模块成果
代码如下


  
  
  1. from gensim.models import Word2Vec
  2. en_wiki_word2vec_model = Word2Vec.load( 'wiki.zh.model')
  3. testwords = [ '孩子', '数学', '学术', '白痴', '篮球']
  4. for i in range( 5):
  5. res = en_wiki_word2vec_model.most_similar(testwords[i])
  6. print(testwords[i])
  7. print(res)

首先导入gensim.models中的Word2Vec模块

然后使用Word2Vec模块中方法加载模块,之后便可以使用其中的most_similar方法进行词向量寻找并打印结果

测试结果展示:


总结:
可以看到还是大部分make sense的
但是也有一些词不太相近或者更相近的答案而并非首选。
很大一部分原因是因为语料库的不足,因为语料库中资料仅有1.3G,对于中文训练来说是大大不足的。

猜你喜欢

转载自blog.csdn.net/zhonglongshen/article/details/88096536
今日推荐