一、概述

训练语料来源:维基媒体 https://dumps.wikimedia.org/backup-index.html 汉语数据

用word2vec训练词向量,并用所学得的词向量,计算 pku_sim_test.txt 文件中每行两个词间的余弦距离作为两词相似度,并输出到文件中。

二、数据准备及预处理

语料库的下载地址:https://dumps.wikimedia.org/zhwiki/20191120/zhwiki-20191120-pages-articles-multistream.xml.bz2

语料库文章的提取

下载完成之后,解压缩得到的是一个xml文件,里面包含了许多的文章,也有许多的日志信息。此实验只需要提取xml文件里面的文章就可以了。

可以通过工具WikiExtractor来提取xml文件中的文章。先将整个WikiExtractor项目clone或者下载到本地,通过命令行窗口来运行,命令如下:(每个文件分割的大小为500M)

> git init
> git clone https://github.com/attardi/wikiextractor
> python .\wikiextractor\WikiExtractor.py -b 500M -o zhwiki zhwiki-20190401-pages-articles-multistream.xml.bz2

使用WikiExtractor提取文章,会在指定目录下产生一个AA的文件夹,里面会包含几个文件。

中文简体和繁体的转换

因为维基百科语料库中的文章内容里面的简体和繁体是混乱的,所以我们需要将所有的繁体字转换成为简体。这里我们利用OpenCC来进行转换。

OpenCC项目地址: https://github.com/BYVoid/OpenCC, 将OpenCC安装到本地电脑后,执行命令:(t2s.json: 繁体转简体)

> opencc -i .\zhwiki\AA\wiki_00
-o .\zhwiki\BB\wiki_00
-c D:\opencc-1.0.4-win32\opencc-1.0.4\share\opencc\t2s.json

正则表达式提取文章内容并进行分词:

当前目录下的segmentWords.py中的代码共执行了三个步骤的操作:

(1)过滤标签内容:使用WikiExtractor提取的文章,会包含许多的,所以需要将这些不相关的内容通过正则表达式来去除。

(2)分词及去停用词:通过jieba对文章进行分词,在分词的时候还需要将停用词去除。

(3)合并保存文件:将分割之后的文章保存到文件中,每一行表示一篇文章,每个词之间使用空格进行分隔。

Jieba项目地址:https://github.com/fxsjy/jieba

#segmentWords.py

import logging
import jieba
import os
import re def get_stopwords():
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',level=logging.INFO)
#加载停用词表
stopword_set = set()
with open("./stop_words/stopwords.txt",'r',encoding="utf-8") as stopwords:
for stopword in stopwords:
stopword_set.add(stopword.strip("\n"))
return stopword_set '''
使用正则表达式解析文本
'''
def parse_zhwiki(read_file_path,save_file_path):
#过滤掉<doc>
regex_str = "[^<doc.*>$]|[^</doc>$]"
file = open(read_file_path,"r",encoding="utf-8")
#写文件
output = open(save_file_path,"w+",encoding="utf-8")
content_line = file.readline()
#获取停用词表
stopwords = get_stopwords()
#定义一个字符串变量,表示一篇文章的分词结果
article_contents = ""
cnt = 0
while content_line:
match_obj = re.match(regex_str,content_line)
content_line = content_line.strip("\n")
if len(content_line) > 0:
if match_obj:
#使用jieba进行分词
words = jieba.cut(content_line,cut_all=False)
for word in words:
if word not in stopwords:
article_contents += word+" "
else:
if len(article_contents) > 0:
output.write(article_contents+"\n")
article_contents = ""
cnt += 1
if (cnt % 10000 == 0):
print("已处理", cnt/10000, "万行")
content_line = file.readline()
output.close() '''
将维基百科语料库进行分类
'''
def generate_corpus():
zhwiki_path = "./zhwiki/BB"
save_path = "./zhwiki/BB"
for i in range(3):
print("开始处理第", i, "个文件")
file_path = os.path.join(zhwiki_path,str("wiki_0%s"%str(i)))
parse_zhwiki(file_path,os.path.join(save_path,"wiki_corpus0%s"%str(i))) '''
合并分词后的文件
'''
def merge_corpus():
output = open("./zhwiki/BB/wiki_corpus","w",encoding="utf-8")
input = "./zhwiki/BB"
for i in range(3):
print("开始合并第", i, "个文件")
file_path = os.path.join(input,str("wiki_corpus0%s"%str(i)))
file = open(file_path,"r",encoding="utf-8")
line = file.readline()
while line:
output.writelines(line)
line = file.readline()
file.close()
output.close() if __name__ == "__main__":
# # wiki数据处理
print("开始正则,jieba处理数据")
generate_corpus() # 文件合并
print("开始合并文件")
merge_corpus() # 打印数据 显示
input_file = "./zhwiki/BB/wiki_corpus"
file = open(input_file,"r",encoding="utf-8")
line = file.readline()
num = 1
while line:
print(line)
line = file.readline()
num += 1
if num > 10:
break

word2vec模型的训练

当前目录下的train.py中word2vec的参数设置(size=100, window=5, sg=1, hs=0, negative=5),符合实验要求(前后2窗口,100维,SGNS)。

#train.py

import logging
from gensim.models import word2vec def main():
logging.basicConfig(format="%(asctime)s:%(levelname)s:%(message)s",level=logging.INFO)
sentences = word2vec.LineSentence("./zhwiki/BB/wiki_corpus")
# size:单词向量的维度
# window: 窗口大小
# sg=1: 使用skip-gram
# hs=0: 使用negative sample
model = word2vec.Word2Vec(sentences, size=100, window=5, sg=1, hs=0, negative=5)
# 保存模型 必须3个一起用
# model.save("./model/wiki_corpus.bin")
# model.save("./model/wiki_corpus.model") # 训练为一个单独二进制压缩文件 可独立使用
model.wv.save_word2vec_format("./model/wiki_corpus_binary.bin", binary=True) if __name__ == "__main__":
main()

计算两个词的相似度:

当前目录下的compute.py中的代码共执行了以下步骤:

(1)读取训练得到的模型,以及待计算相似的pku_sim_test.txt文件

(2)字符串以\t\n为分隔符切分为列表格式,并计算相似度

(3)结果保存为result.txt文件

#compute.py

import re
from gensim.models import KeyedVectors def main():
# 读取模型以及待计算数据
model = KeyedVectors.load_word2vec_format("./model/wiki_corpus_binary.bin", binary=True)
f = open('./pku_sim_test.txt', encoding='utf-8')
out = open('result.txt', 'w', encoding='utf-8') # 字符串切分为列表
wordlist = []
while True:
line = f.readline()
if not line:
break
wordlist.append(re.split(r'[\t\n]', line)) # 计算相似度
cnt = 0
resTotal = 0.0
for i in range(len(wordlist)):
words = wordlist[i]
try:
res = model.similarity(words[0], words[1])
except KeyError:
words[2] = 'OOV'
wordlist[i] = words
print(words)
continue words[2] = str("%.4f"%res)
wordlist[i] = words
print(words)
cnt += 1
resTotal += res print("查到的比例为:%.4f"%(cnt/len(wordlist)))
print("平均相似度为:%.4f"%(resTotal/cnt)) # 结果保存
lines = []
for i in range(len(wordlist)):
line = wordlist[i]
oneline = line[0] + '\t' + line[1] + '\t' + line[2] + '\n'
lines.append(oneline)
out.writelines(lines)
f.close()
out.close() if __name__ == '__main__':
main()

最新文章

  1. spark快速大数据分析学习笔记*初始化sparkcontext(一)
  2. PHP截取中文无乱码函数——cutstr
  3. Codeforces Round #275 Div.1 B Interesting Array --线段树
  4. [UIImage resizableImageWithCapInsets:]使用注意
  5. [转]使用Xcode和Instruments调试解决iOS内存泄露
  6. 在32位Windows 8或Windows 7上安装Windows Phone 8 SDK
  7. hdoj 1513 Palindrome【LCS+滚动数组】
  8. 检测android的网络链接状态
  9. Oracle触发器(trigger):view,schema,database
  10. printf参数的问题
  11. linkin大话面向对象--多态
  12. ElasticSearch常用操作
  13. css学习_css布局案例
  14. 004-CSS怎样让背景充满整个屏幕
  15. EL表达式具体解释
  16. Git 换行符检查 CRLF 与 LF
  17. 【洛谷P4735】最大异或和
  18. idea+maven+springboot+mybatis+springmvc+shiro
  19. 基于Arcface 免费离线人脸识别 2.0 Demo C#
  20. WCF错误:413 Request Entity Too Large 的一个解决方法

热门文章

  1. tornado自定义分页扩展
  2. ARTS Week 8
  3. Android Studio 学习笔记(二):布局简介和xmlns说明
  4. 动手学习Pytorch(7)--LeNet
  5. JumpServer部署与管理
  6. 安装ik分词插件
  7. 搭建Samba服务器、多部门共享,互不干扰,超实用
  8. 基于 H5 Canvas 实现楼宇新风系统
  9. [MacOS-Memcached]安装
  10. 国产安全自主可控IT智能运维管理解决方案