词义消岐简介

词义消岐,英文名称为Word Sense Disambiguation,英语缩写为WSD,是自然语言处理(NLP)中一个非常有趣的基本任务。

那么,什么是词义消岐呢?通常,在我们的自然语言中,不管是英语,还是中文,都有多义词存在。这些多义词的存在,会让人对句子的意思产生混淆,但人通过学习又是可以正确地区分出来的。

以**“小米”**这个词为例,如果仅仅只是说“小米”这个词语,你并不知道它实际指的到底是小米科技公司还是谷物。但当我们把词语置于某个特定的语境中,我们能很好地区分出这个词语的意思。比如,

雷军是小米的创始人。

在这个句子中,我们知道这个“小米”指的是小米科技公司。比如

我今天早上喝了一碗小米粥。

在这个句子中,“小米”指的是谷物、农作物。

所谓词义消岐,指的是在特定的语境中,识别出某个歧义词的正确含义。

那么,词义消岐有什么作用呢?词义消岐可以很好地服务于语言翻译和智能问答领域,当然,还有许多应用有待开发~

词义消岐实现

比较经典的词义消岐的算法为Lesk算法,该算法的想法很简单,通过对某个歧义词构建不同含义的语料及待判别句子中该词语与语料的重合程度来实现

我们以词语“火箭”为例,选取其中的两个义项(同一个词语的不同含义):NBA球队名 和 燃气推进装置 ,如下:

获取语料

  首先,我们利用爬虫爬取这两个义项的百度百科网页,以句子为单位,只要句子中出现该词语,则把这句话加入到这个义项的预料中。爬虫的完整Python代码如下:

import requests
from bs4 import BeautifulSoup
from pyltp import SentenceSplitterclass WebScrape(object):def __init__(self, word, url):self.url = urlself.word = word# 爬取百度百科页面def web_parse(self):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 \(KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}req = requests.get(url=self.url, headers=headers)# 解析网页,定位到main-content部分if req.status_code == 200:soup = BeautifulSoup(req.text.encode(req.encoding), 'lxml')return soupreturn None# 获取该词语的义项def get_gloss(self):soup = self.web_parse()if soup:lis = soup.find('ul', class_="polysemantList-wrapper cmn-clearfix")if lis:for li in lis('li'):if '<a' not in str(li):gloss = li.text.replace('▪', '')return glossreturn None# 获取该义项的语料,以句子为单位def get_content(self):# 发送HTTP请求result = []soup = self.web_parse()if soup:paras = soup.find('div', class_='main-content').text.split('\n')for para in paras:if self.word in para:sents = list(SentenceSplitter.split(para))for sent in sents:if self.word in sent:sent = sent.replace('\xa0', '').replace('\u3000', '')result.append(sent)result = list(set(result))return result# 将该义项的语料写入到txtdef write_2_file(self):gloss = self.get_gloss()result = self.get_content()print(gloss)print(result)if result and gloss:with open('./%s_%s.txt' % (self.word, gloss), 'w', encoding='utf-8') as f:f.writelines([_ + '\n' for _ in result])def run(self):self.write_2_file()# NBA球队名
# url = 'https://baike.baidu.com/item/%E4%BC%91%E6%96%AF%E6%95%A6%E7%81%AB%E7%AE%AD%E9%98%9F/370758?fromtitle=%E7%81%AB%E7%AE%AD&fromid=8794081#viewPageContent'
# 燃气推进装置
url = 'https://baike.baidu.com/item/%E7%81%AB%E7%AE%AD/6308#viewPageContent'
WebScrape('火箭', url).run()

运行结果:

利用这个爬虫,我们爬取了“火箭”这个词语的两个义项的语料,生成了火箭_燃气推进装置.txt文件和火箭_NBA球队名.txt文件,这两个文件分别含有275和190个句子。以火箭_燃气推进装置.txt文件为例,前10个句子如下:

火箭主要分类
火箭美国大力神系列运载火箭
大力神4火箭于1985年开始研制,在1986年挑战者号航天飞机失事之后,成为发射大型军用卫星的主要运载火箭,承担美国空军地球同步轨道卫星(预警、通信、中继、气象)和近地轨道侦察卫星的发射任务。
其目标是在海南建成探空火箭探测和地面联合监测大气和电离层参数的综合探测系统。
揭秘长三甲系列:“金牌火箭”是这样炼成的
固体火箭的动力装置系统较为简单,它的主要部分就是固体火箭发动机,推进剂直接装在发动机的燃烧室壳体内。
火箭按动力能源
1965年起开始研制固体探空火箭“和平”2号和6号。
作为新能源火箭的代表,核能火箭的优点是其发动机比冲比化学能火箭的高,而推进剂只有一种,简化了火箭结构,适合执行长时间任务或星际任务。
中国在1958年以前曾发射过试验性火箭,1958年正式研制探空火箭,先后研制成T-7液体探空火箭和改进型 T-7A探空火箭。

实现算法

  我们以句子为单位进行词义消岐,即输入一句话,识别出该句子中某个歧义词的含义。这儿使用的算法比较简单,是以TF-IDF为权重的频数判别。以句子

赛季初的时候,火箭是众望所归的西部决赛球队。

为例,对该句子分词后,去掉停用词(stopwords),然后分别统计除了“火箭”这个词以外的TF-IDF值,累加起来,比较在两个义项下这个值的大小即可。
  实现这个算法的完整Python代码如下:

import os
import jieba
from math import log2# 读取每个义项的语料
def read_file(path):with open(path, 'r', encoding='utf-8') as f:lines = [_.strip() for _ in f.readlines()]return lines# 对示例句子分词
sent = '赛季初的时候,火箭是众望所归的西部决赛球队。'
wsd_word = '火箭'jieba.add_word(wsd_word)
sent_words = list(jieba.cut(sent, cut_all=False))# 去掉停用词
stopwords = [wsd_word, '我', '你', '它', '他', '她', '了', '是', '的', '啊', '谁', '什么', '都', \'很', '个', '之', '人', '在', '上', '下', '左', '右', '。', ',', '!', '?']sent_cut = []
for word in sent_words:if word not in stopwords:sent_cut.append(word)print(sent_cut)# 计算其他词的TF-IDF以及频数
wsd_dict = {}
for file in os.listdir('.'):if wsd_word in file:wsd_dict[file.replace('.txt', '')] = read_file(file)# 统计每个词语在语料中出现的次数
tf_dict = {}
for meaning, sents in wsd_dict.items():tf_dict[meaning] = []for word in sent_cut:word_count = 0for sent in sents:example = list(jieba.cut(sent, cut_all=False))word_count += example.count(word)if word_count:tf_dict[meaning].append((word, word_count))idf_dict = {}
for word in sent_cut:document_count = 0for meaning, sents in wsd_dict.items():for sent in sents:if word in sent:document_count += 1idf_dict[word] = document_count# 输出值
total_document = 0
for meaning, sents in wsd_dict.items():total_document += len(sents)# 计算tf_idf值
mean_tf_idf = []
for k, v in tf_dict.items():print(k + ':')tf_idf_sum = 0for item in v:word = item[0]tf = item[1]tf_idf = item[1] * log2(total_document / (1 + idf_dict[word]))tf_idf_sum += tf_idfprint('%s, 频数为: %s, TF-IDF值为: %s' % (word, tf, tf_idf))mean_tf_idf.append((k, tf_idf_sum))sort_array = sorted(mean_tf_idf, key=lambda x: x[1], reverse=True)
true_meaning = sort_array[0][0].split('_')[1]
print('\n经过词义消岐,%s在该句子中的意思为 %s .' % (wsd_word, true_meaning))

运行结果:

['赛季', '初', '时候', '众望所归', '西部', '决赛', '球队']
火箭_NBA球队名:
赛季, 频数为: 61, TF-IDF值为: 187.86335874071477
初, 频数为: 1, TF-IDF值为: 5.861086905995394
时候, 频数为: 1, TF-IDF值为: 7.861086905995394
西部, 频数为: 19, TF-IDF值为: 89.13207618650854
决赛, 频数为: 8, TF-IDF值为: 35.21324229886477
球队, 频数为: 43, TF-IDF值为: 155.36585387972775
火箭_燃气推进装置:
初, 频数为: 3, TF-IDF值为: 17.58326071798618经过词义消岐,火箭在该句子中的意思为 NBA球队名 .

测试

  接着,我们对上面的算法和程序进行更多的测试。

输入句子为:

三十多年前,战士们在戈壁滩白手起家,建起了我国的火箭发射基地。

输出结果为:

['三十多年', '前', '战士', '们', '戈壁滩', '白手起家', '建起', '我国', '发射', '基地']
火箭_NBA球队名:
前, 频数为: 3, TF-IDF值为: 10.617476433324095
们, 频数为: 1, TF-IDF值为: 6.539158811108031
火箭_燃气推进装置:
前, 频数为: 9, TF-IDF值为: 31.852429299972282
我国, 频数为: 5, TF-IDF值为: 31.38062202637119
发射, 频数为: 110, TF-IDF值为: 257.1277444932219经过词义消岐,火箭在该句子中的意思为 燃气推进装置 .

输入句子为:

对于马刺这样级别的球队,常规赛只有屈指可数的几次交锋具有真正的意义,今天对火箭一役是其中之一。

输出结果为:

['对于', '马刺', '这样', '级别', '球队', '常规赛', '只有', '屈指可数', '几次', '交锋', '具有', '真正', '意义', '今天', '对', '一役', '其中', '之一']
火箭_NBA球队名:
对于, 频数为: 1, TF-IDF值为: 7.2761244052742375
球队, 频数为: 43, TF-IDF值为: 155.36585387972775
常规赛, 频数为: 14, TF-IDF值为: 70.75224777512906
只有, 频数为: 1, TF-IDF值为: 6.861086905995394
对, 频数为: 12, TF-IDF值为: 47.450355724642506
之一, 频数为: 1, TF-IDF值为: 6.539158811108031
火箭_燃气推进装置:
对于, 频数为: 1, TF-IDF值为: 7.2761244052742375
这样, 频数为: 1, TF-IDF值为: 7.861086905995394
只有, 频数为: 2, TF-IDF值为: 13.722173811990787
具有, 频数为: 3, TF-IDF值为: 20.58326071798618
真正, 频数为: 1, TF-IDF值为: 7.861086905995394
意义, 频数为: 1, TF-IDF值为: 7.861086905995394
对, 频数为: 13, TF-IDF值为: 51.40455203502938
其中, 频数为: 5, TF-IDF值为: 31.38062202637119
之一, 频数为: 3, TF-IDF值为: 19.617476433324093经过词义消岐,火箭在该句子中的意思为 NBA球队名 .

输入的句子为:

从1992年开始研制的长征二号F型火箭,是中国航天史上技术最复杂、可靠性和安全性指标最高的运载火箭。

输出结果为:

['从', '1992', '年', '开始', '研制', '长征二号', 'F', '型', '中国', '航天史', '技术', '最', '复杂', '、', '可靠性', '和', '安全性', '指标', '最高', '运载火箭']
火箭_NBA球队名:
从, 频数为: 6, TF-IDF值为: 23.44134357365111
1992, 频数为: 2, TF-IDF值为: 13.078317622216062
年, 频数为: 64, TF-IDF值为: 150.61070501098862
开始, 频数为: 2, TF-IDF值为: 9.078317622216062
中国, 频数为: 11, TF-IDF值为: 39.74475331806989
最, 频数为: 2, TF-IDF值为: 6.937538966433267
、, 频数为: 25, TF-IDF值为: 62.15118686621173
和, 频数为: 31, TF-IDF值为: 64.47154296659276
最高, 频数为: 8, TF-IDF值为: 52.31327048886425
火箭_燃气推进装置:
从, 频数为: 24, TF-IDF值为: 93.76537429460444
1992, 频数为: 1, TF-IDF值为: 6.539158811108031
年, 频数为: 44, TF-IDF值为: 103.54485969505468
开始, 频数为: 17, TF-IDF值为: 77.16569978883652
研制, 频数为: 24, TF-IDF值为: 102.6269857265817
型, 频数为: 13, TF-IDF值为: 48.51345055765555
中国, 频数为: 23, TF-IDF值为: 83.10266602869159
技术, 频数为: 20, TF-IDF值为: 88.03310574716193
最, 频数为: 3, TF-IDF值为: 10.4063084496499
复杂, 频数为: 3, TF-IDF值为: 20.58326071798618
、, 频数为: 149, TF-IDF值为: 370.4210737226219
可靠性, 频数为: 2, TF-IDF值为: 14.552248810548475
和, 频数为: 97, TF-IDF值为: 201.73353766966122
最高, 频数为: 1, TF-IDF值为: 6.539158811108031
运载火箭, 频数为: 111, TF-IDF值为: 257.7340185324972经过词义消岐,火箭在该句子中的意思为 燃气推进装置 .

输入句子为:

到目前为止火箭已经在休斯顿进行了电视宣传,并在大街小巷竖起广告栏。

输出结果为:

['到', '目前为止', '已经', '休斯顿', '进行', '电视', '宣传', '并', '大街小巷', '竖起', '广告栏']
火箭_NBA球队名:
到, 频数为: 3, TF-IDF值为: 10.012574849815142
已经, 频数为: 1, TF-IDF值为: 7.2761244052742375
休斯顿, 频数为: 9, TF-IDF值为: 51.220457140977736
进行, 频数为: 2, TF-IDF值为: 8.321294375708604
并, 频数为: 6, TF-IDF值为: 24.01863546520693
火箭_燃气推进装置:
到, 频数为: 17, TF-IDF值为: 56.73792414895247
已经, 频数为: 1, TF-IDF值为: 7.2761244052742375
进行, 频数为: 28, TF-IDF值为: 116.49812125992045
并, 频数为: 18, TF-IDF值为: 72.0559063956208经过词义消岐,火箭在该句子中的意思为 燃气推进装置 .

总结:

这个算法,虽然有一定的效果,但是也不总是识别正确。比如,对于最后一个测试的句子,识别的结果就是错误的,其实“休斯顿”才是识别该词语义项的关键词,但很遗憾,在笔者的算法中,“休斯顿”的权重并不高。
  对于词义消岐算法,如果还是用这个思路,那么有以下几方面需要改进:

  • 语料大小及丰富程度;
  • 停用词的扩充;
  • 更好的算法。

自然语言处理(NLP)之词义消歧(WSD)的简介与实现相关推荐

  1. NLP 迷思之四:词义消歧(WSD)是NLP应用的瓶颈

    本文转载自http://blog.sciencenet.cn/blog-362400-526304.html 引用老友: 受教了.谢谢立委. 我同意"成语从来不是问题".成问题的应 ...

  2. 自然语言处理之使用gensim.Word2Vec训练词向量进行词义消歧

    自然语言处理之使用gensim.Word2Vec训练词向量进行词义消歧 NLP中进行词义消歧的一个非常方便且简单的方法就是训练词向量,通过词向量计算余弦值,来推断某个词在句子中的含义.python中的 ...

  3. 【NLP入门教程】七、词义消歧

    词义消歧(Word Sense Disambiguation, WSD)其目标是确定文本中词汇的正确含义.由于许多单词具有多种含义,词义消歧对于理解和分析文本具有关键作用. 1. 词义消歧的挑战 词义 ...

  4. 基于在线百科知识库的多义词词义消歧项目

    WordMultiSenseDisambiguation WordMultiSenseDisambiguation, chinese multi-wordsense disambiguation ba ...

  5. nlp2-数学基础(信息论,概率论、词义消歧)

    文章目录 概率论 信息论 计算熵 计算信息熵.条件熵.联合熵 波利尼亚语 熵率 噪声信道模型 建立一个翻译 词义消歧(WSD 贝叶斯 最大熵的消歧方法 概率论 在自然语言处理中,以句子为处理单位时一般 ...

  6. 情绪分析,词性分析和词义消歧

    情绪分析 情绪分析侧重于主观陈述--意见.情绪.情绪:很难用几个关键词来表达. 主观性分类 Subjectivity classification 通常是情感分析的第一步:主观与客观文本 opinio ...

  7. 汉语语义消歧之 -- 词义消歧简介

    总算是到正题上了... 词义消歧,亦称语义消歧,是计算语言学领域的基础性关键研究课题. 对于许多词语(特别是汉语词语和一部分专有名词),一个词有许多种意思. 例如专有名词"卡特", ...

  8. 大规模数据的词义消歧的混合词义分类方法——阅读整理总结

    介绍: 尽管最近的研究证明了神经语言模型的优越性,但是WSD研究的范围仍然是几个单词的意义只能在几个领域中确定.因此,有必要朝着开发一个高度可扩展的过程的方向发展,这个过程可以处理在不同领域中出现的词 ...

  9. 生成句法分析树以及从一个小例子来看词义消歧及语义角色标注

    一.生成句法分析树 把一句话按照句法逻辑组织成一棵树,由人来做这件事是可行的,但是由机器来实现是不可思议的,然而算法世界就是这么神奇,把一个十分复杂的过程抽象成仅仅几步操作,甚至不足10行代码,就能让 ...

最新文章

  1. UVA 11752 超级幂
  2. python对文件的操作_python的 随手记----对文件的操作
  3. 两款旋转编码器测量LDP3806,BH60
  4. metapath2vec: Scalable Representation Learning for Heterogeneous Networks
  5. uva 12426 Counting Triangles 计算几何
  6. 【安卓开发 】Android初级开发(十二)Android向系统日历中添加事件
  7. css居中无效的解决办法
  8. 当你使用微信和QQ的时候,请不要忘记ICQ这个伟大的公司!
  9. ApplicationId 与 PackageName
  10. [Angular 6] 初学angular,环境全部最新,[ ng serve ] 不能启动,卡在 95% 不动 => 解决方案
  11. OPNET网络仿真分析-1.1.1、网络仿真简介
  12. oracle语法和sql的区别吗,ORACLE和SQL语法区别归纳
  13. 计算机监控系统sacad,一套幼儿园智能化弱电CAD设计图,可以作为投标技术文件模板...
  14. 传奇脚本称号(封号)设置的详解
  15. java毕业设计社区食堂供餐源码+lw文档+mybatis+系统+mysql数据库+调试
  16. 记录使用浏览器扫码功能(pad 笔记本 手机)
  17. html中竖线怎么写,HTML如何写出竖线
  18. Proteus 8.12 仿真软件安装
  19. 实用分享-鼠标自动点击助手
  20. 一阶高低通滤波器设计及实现

热门文章

  1. 溢价 5 倍欲将 SiFive 收入麾下,英特尔的绝地反击战
  2. 参数量110亿,附赠750GB数据集,Google提NLP预训练模型T5
  3. 免费开源!新学期必收藏的AI学习资源,从课件、工具到源码都齐了
  4. AI找Bug,一键快速预测
  5. AI一分钟 | 特斯拉官方回应致死事故:鉴定报告尚不完整
  6. redisTemplate分布式锁演变、redission分布式锁实现!
  7. Sharding-jdbc教程:Springboot整合sharding-jdbc实现读写分离
  8. NLP入门必知必会(一):Word Vectors
  9. PostgreSQL_case when
  10. 【廖雪峰python入门笔记】list_倒序访问