一、概述

训练语料来源:维基媒体 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()

【计算语言学实验】基于 Skip-Gram with Negative Sampling (SGNS) 的汉语词向量学习和评估的更多相关文章

  1. word2vec 中的数学原理具体解释(五)基于 Negative Sampling 的模型

      word2vec 是 Google 于 2013 年开源推出的一个用于获取 word vector 的工具包,它简单.高效,因此引起了非常多人的关注. 因为 word2vec 的作者 Tomas ...

  2. word2vec原理(三) 基于Negative Sampling的模型

    word2vec原理(一) CBOW与Skip-Gram模型基础 word2vec原理(二) 基于Hierarchical Softmax的模型 word2vec原理(三) 基于Negative Sa ...

  3. 论文解读(SelfGNN)《Self-supervised Graph Neural Networks without explicit negative sampling》

    论文信息 论文标题:Self-supervised Graph Neural Networks without explicit negative sampling论文作者:Zekarias T. K ...

  4. word2vec改进之Negative Sampling

    训练网络时往往会对全部的神经元参数进行微调,从而让训练结果更加准确.但在这个网络中,训练参数很多,每次微调上百万的数据是很浪费计算资源的.那么Negative Sampling方法可以通过每次调整很小 ...

  5. 词表征 2:word2vec、CBoW、Skip-Gram、Negative Sampling、Hierarchical Softmax

    原文地址:https://www.jianshu.com/p/5a896955abf0 2)基于迭代的方法直接学 相较于基于SVD的方法直接捕获所有共现值的做法,基于迭代的方法一次只捕获一个窗口内的词 ...

  6. DL4NLP——词表示模型(三)word2vec(CBOW/Skip-gram)的加速:Hierarchical Softmax与Negative Sampling

    上篇博文提到,原始的CBOW / Skip-gram模型虽然去掉了NPLM中的隐藏层从而减少了耗时,但由于输出层仍然是softmax(),所以实际上依然“impractical”.所以接下来就介绍一下 ...

  7. Notes on Noise Contrastive Estimation and Negative Sampling

    Notes on Noise Contrastive Estimation and Negative Sampling ## 生成负样本 在常见的关系抽取应用中,我们经常需要生成负样本来训练一个好的系 ...

  8. [DeeplearningAI笔记]序列模型2.7负采样Negative sampling

    5.2自然语言处理 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.7 负采样 Negative sampling Mikolov T, Sutskever I, Chen K, et a ...

  9. 21.实验基于_version进行乐观锁并发控制

    21.实验基于_version进行乐观锁并发控制 主要知识点: 实验基于_version进行乐观锁并发控制 1.实验实战演练基于_version进行乐观锁并发控制 (1)先构造一条数据出来 PUT / ...

随机推荐

  1. JSP&Servlet学习笔记----第1/2章

    HTML(HyperText Markup Language):超文本标记语言 HTTP(HyperText Transfer Protocol):超文本传输协议 URL(Uniform Resour ...

  2. windows下编译LUA-cjson

    下载地址:http://www.kyne.com.au/~mark/software/lua-cjson.php 编译环境:win7 + MINGW 修改下载得到的lua-cjson-2.1.0.zi ...

  3. Comet OJ Contest #0 解方程(暴力)

    题意: 给定自然数n,求满足$\displaystyle \sqrt{x-\sqrt{n}}=\sqrt{z}-\sqrt{y}$的x,y,z,输出解的个数以及所有解 xyz的和 n<=1e9, ...

  4. HDU 3068 最长回文 (Manacher最长回文串)

    Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等   Input 输 ...

  5. Linux系统之网络文件共享与数据实时同步实践

    1.实现基于MYSQL验证的vsftpd虚拟用户访问 首先环境说明,数据库服务器是192.168.0.10,vsftpd服务器是192.168.0.30 1)安装vsftpd [root@test-c ...

  6. ELK搭建(docker环境)

    ELK是Elasticsearch.Logstash.Kibana的简称,这三者是核心套件,但并非全部. Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大功能:是一套开 ...

  7. python学习(7)关于列表操作相关命令以及浅复制深复制

    在python中,[]表示的是列表.列表有各种操作命令. 1.append()方法,添加一个元素到列表尾部. 注意append()方法与extend()方法有区别:list.append(object ...

  8. javascript HierarchicalTaskAnalysis-hta编程(.hta)

    main.hta  code: <script>window.resizeTo(400,300);</script> <head> <hta:applicat ...

  9. 【Java并发工具类】Java并发容器

    前言 Java并发包有很大一部分都是关于并发容器的.Java在5.0版本之前线程安全的容器称之为同步容器.同步容器实现线程安全的方式:是将每个公有方法都使用synchronized修饰,保证每次只有一 ...

  10. HDU 1017 直接暴力。

    C - 3 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...