前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于维基百科的中文词语相关度计算

基于维基百科的中文词语相关度计算

作者头像
张宏伦
发布2018-06-07 14:43:03
7240
发布2018-06-07 14:43:03
举报
文章被收录于专栏:宏伦工作室宏伦工作室

首先来一个简单的问题,“乔布斯”和“苹果”这两个词有关联吗?如果有,有多大的相关度?

背景介绍

传统的文档相关度一般是基于特征提取所得的向量相关度,而词语相关度也经常在不少实际应用中涉及到。对于要比较的两个词语,相对于仅仅在“相等”和“不等”这两者间做一个选择,更好的方法应当是对相关度的大小作一个数值性刻画。如果“1”对应完全相关,“0”对应完全不相关(当然也可以将相关度最小值设为-1),那么可以用“0”至“1”之间的一个浮点数来刻画两个词语的相关度。

衡量两个词语的相关度一般通过比较其上下文环境来实现,越相似或者说越相关的两个词越有可能同时出现在一段话中,或者出现在类似的上下文环境中。所以我们需要一个完整且丰富的语料来构建所有词语可能出现的上下文环境,在此语料的基础上训练得到包含于其中的任意词语两两之间的相关度。

看到“我爱nlp”网站上的一篇文章,讲解如何基于维基百科数据计算词语的相关度,点击阅读原文即可访问。维基百科可以说是最常用最权威的开放网络数据集之一,作为极少数的人工编辑、内容丰富、格式规范的文本语料,各类语言的维基百科在NLP等诸多领域应用广泛。维基百科提供了开放的词条文本整合下载,可以找到你需要的指定时间、指定语言、指定类型、指定内容的维基百科数据。

gensim是一个NLP的主题模型(Topic Model)python库,其包含的word2vec模型可用来训练文本数据,即将词语映射为向量,通过计算向量的相关度来实现词语间相关度的计算,接下来将详细讲述这一过程。

预备工作

gensim的安装不用多说,pip或者easy_install皆可,详情请参考其主页或者Github上的安装介绍。

因为手边有一些中文新闻分析的需求,所以针对中文维基百科数据进行处理,下载数据压缩包,文件大概1G左右。

数据提取

首先需要从压缩包中提取出中文维基的条目文本。在压缩包路径下编辑process_wiki.py文件,内容如下:

#!/usr/bin/env python # -*- coding: utf-8 -*- import logging import os.path 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 globals()['__doc__'] % locals() 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(): 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")

之后在终端中执行以下命令即可得到中文维基数据,保存至wiki.zh.text文件中,一共25W多行,每行对应一条维基条目的所有文本内容。

python process_wiki.py zhwiki-latest-pages-articles.xml.bz2 wiki.zh.text

中文维基的一个很大的问题是混杂了很多繁体字,不便于阅读和使用。可以使用开源工具opencc进行繁简中文的转化。我的环境是macos,使用brew即可方便安装。opencc配置好后,在终端中运行以下命令进行繁简转化,将简体中文维基数据保存至wiki.zh.jian.text中。

opencc -i wiki.zh.text -o wiki.zh.jian.text -c t2s.json

现在每行对应一条维基条目的文本内容,我们需要对语句进行中文分词,这样得到的数据才是由一个个词语组成的语料。还是在压缩包所在的路径下,编辑segment_wiki.py,使用结巴分词进行中文分词。编辑好后运行即可,分词结果保存至wiki.zh.word.text中。

#!/usr/bin/env python # coding:utf8 import jieba import sys reload(sys) sys.setdefaultencoding('utf8') jieba.enable_parallel(4) fr = open('wiki.zh.jian.text', 'r') fw = open('wiki.zh.word.text', 'w') count = 0 for line in fr: count += 1 print count result = '' line = line.rstrip('\n').split() for item in line: item = jieba.cut(item) for i in item: result += i + ' ' fw.write(result[:-1] + '\n') fr.close() fw.close()

这样,就基本完成模型训练之前的数据准备工作了。

模型训练

我们使用gensim包提供的word2vec模型进行训练,还是在压缩包所在路径下,编辑train_word2vec_model.py文件,内容如下:

#!/usr/bin/env python # -*- coding: utf-8 -*- import logging import os.path import sys import multiprocessing from gensim.corpora import WikiCorpus 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.save_word2vec_format(outp2, binary=False)

之后在终端中执行以下命令即可进行模型的训练,训练过程可能需要十几分钟的时间,耐心等待不要着急,训练完毕后会生成wiki.zh.text.model、wiki.zh.text.model.syn0.npy、wiki.zh.text.model.syn1.npy、wiki.zh.text.vector四个文件。

python train_word2vec_model.py wiki.zh.word.text wiki.zh.text.model wiki.zh.text.vector

模型使用

现在我们可以使用训练好的模型来获取词语之间的相关度了,使用以下命令加载训练好的模型:

import gensim model = gensim.models.Word2Vec.load("wiki.zh.text.model")

此处的model提供了两个有用的函数:most_similar()和similarity()。前者对于给定词语遍历其他所有词语并返回与其相关度最高的10个词语,后者则直接返回两个词语的相关度。看看以下例子,和我们的日常生活认知还是挺吻合的。

>> result = model.most_similar(u'足球') >> for e in result: ... print e[0], e[1] ... 甲级联赛 0.728107869625 联赛 0.624911427498 乙级 0.619551062584 足球联赛 0.61553055048 俱乐部 0.600710988045 中作赛 0.588489711285 印超 0.583016633987 fwa 0.58231317997 港超联 0.582292079926 中国足球协会 0.579757452011 >> print model.similarity(u'男人', u'女人') 0.773828387262 >> print model.similarity(u'男人', u'老人') 0.204776343779

后记

word2vec为词语间相关度的计算提供了一个更好的解决方案,也有利于帮我们寻找类似“乔布斯”和“苹果”这样的词语之间所隐含的关联,在具体应用中往往能实现更符合语义要求的结果。现在模型已经有了,不妨大开脑洞去实践一些有意思的应用吧!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 宏伦工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档