1. 如何用nltk来找到text中相似的word

如果我们想搜索某一篇文章(text)中相似的词(word),可以使用nltk这个强大的NLP模块。下面以nltk自带的shakespeare数据集来做示例。

第一次使用nltk,需要先运行下面的代码来下载shakespeare数据集。

import nltk
nltk.download('shakespeare')

然后,我们就可以加载shakespeare数据集来做实验了:

import  nltk
text = nltk.Text(word.lower() for word in nltk.corpus.shakespeare.words(('hamlet.xml')))

只要使用nltk.Text.similar(word),就能找到text中跟某个word相似的其他所有word了,如下示例

text.similar('woman')

我们就能得到与woman相似的所有词:

matter at eaten but fit this to vulcan by like servant disclose
follows twice laertes it cat such sin

可以看到,这些输出的词中,有的确实与woman有一点点相似,比如“vulcan”和“servant”。但还有大量的词是与woman没有任何关系的,比如“twice”。

那问题来了,nltk.Text.similar是根据什么来衡量两个词的相似度呢?

2. nltk.Text.similar源码

网上并没有太多关于nltk.Text.similar的原理解释,所以只有查阅源码,才能看到细节。

nltk.Text.similar的源码在https://github.com/nltk/nltk/blob/develop/nltk/text.py,其中有一个函数similar(self, word, num=20),这就是nltk.Text.similar的实现,核心代码如下:

def similar(self, word, num=20):"""Distributional similarity: find other words which appear in thesame contexts as the specified word; list most similar words first.:param word: The word used to seed the similarity search:type word: str:param num: The number of words to generate (default=20):type num: int:seealso: ContextIndex.similar_words()"""word = word.lower()# 统一转换为小写进行比较wci = self._word_context_index._word_to_contextsif word in wci.conditions():# 根据上下文context相同来查找其它词contexts = set(wci[word])fd = Counter(wfor w in wci.conditions()for c in wci[w]if c in contexts and not w == word)# most_common是根据出现次数从到到低来输出words = [w for w, _ in fd.most_common(num)]print(tokenwrap(words))

从源码中,我们可以看到, nltk.Text.similar是用Distributional similarity来衡量两个word是否相似。Distributional similarity的做法,首先找到与给定词(the specified word)具有相同上下文(same context)的所有词,然后根据这些词的出现次数,按出现次数从高到低依次输出(most similar words first)。

举个例子,假如有如下一篇文档:

C3 W4 C4
C1 W3 C2
C1 W3 C2
C1 W3 C2
C1 W2 C2
C1 W2 C2
C1 W1 C2
C1 W C2

与词W有相同上下文(C1 X C2)的,是词W1,W2,W3。但W3出现了3次,W2出现了2次,所以W3先输出,W2后输出。

通过阅读nltk.Text.similar源码,我们理解了它判断两个word是否相似,是根据上下文来判断,而非我们人理解的相似度。因为nltk.Text.similar根据上下文,只能找到相似,或不相似的词,所以也就无法做量化的相似度衡量(比如W1与W2相似度为0.8)。

我们再来人为构建几个例子,通过实例深入理解nltk.Text.similar。

3. 上下文similar实例

通过如下代码,我们可以找到语料s中与boy相似的其它词。

import nltks = '''A B C boy D E F G
A B C dog D E F G
A B C cat D E F G
A A A man B B B B
'''tokens = nltk.word_tokenize(s)
text = nltk.Text(tokens)text.similar('boy')

可以得到结果为“cat dog”,这个容易理解,应为“cat”和“dog”的上下文(A B C X D E F G)与“boy”相同。预料中的“man”虽然逻辑上与“boy”应该更具有相似性,但应为nltk.Text.similar是根据上下文来判断相似性,而不是根据逻辑来判断相似性,所以输出结果中没有“man”。

根据源码中similar()的定义similar(self, word, num=20),我们还发现similar()的另一个参数num,它默认是20,指的是输出20个与给定词相似的词,我们将本例中的代码更改为num=1,即text.similar('boy',1),则输出只有1个词“cat”。

本例中,boy的上下文为"A B C" 与 “D E F G”,那similar()在进行相似度搜索是,是完全根据"A B C" 与 "D E F G"都相同才算相似词吗?还是上下文有一个搜索长度的限制,比如只考虑boy之前的3个单词和与之后的3个单词?我发现源码中并无类似的参数,所以设计了如下实验来进行验证。

4. 上下文的长度是多少?

下面是改动了各个词相似的上下文(单词)长度,用来测试上下文长度的例子(查找语料s中与boy相似的词):

import nltks = '''A B C boy D E F G
C dog D
A B B cat D E F G
A A c man d B B B
'''tokens = nltk.word_tokenize(s)
text = nltk.Text(tokens)
text.similar('boy')

代码的输出是“dog man”,所以我们得到两个结论

  1. 上下文,只考虑待搜索词的前一个词和后一个词,即boy(上下文为C X D)与dog(上下文为C X D)相似

  2. 上下文搜索时,不考虑大小写,即boy(上下文为C X D)与man(上下文为c X d)相似

5. 参考

  1. How to load and analysis corpus shakespeare
  2. Understand nltk.Text.similar
  3. nltk source code here

通过源码发现nltk.Text.similar相似度衡量标准相关推荐

  1. zz在Ubuntu中通过源码安装编译安装软件(MySQL篇)

    使用Ubuntu Server作为本地测试环境已经有一段时间了,一直都是使用apt-get方式来安装各种应用软件,通过源码编译安装应用软件是Linux和Unix环 境下最常用的方式.通过源码编译安装的 ...

  2. 通过源码分析Android 的消息处理机制

    2019独角兽企业重金招聘Python工程师标准>>> #通过源码分析Android 的消息处理机制 我们知道,Android应用是通过消息来驱动的,每一个进程被fork之后,都会在 ...

  3. Linux下通过源码编译安装程序

    本文简单的记录了下,在Linux下如何通过源码安装程序,以及相关的知识. 一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 库文件:就是通常我们见到的 ...

  4. 本周两场直播丨通过源码了解openGauss多线程架构;Oracle数据库索引分裂详解。...

    1.管中窥豹之通过源码了解openGauss多线程架构-8月18日20:00 本讲座主要介绍openGauss的多线程架构,通过源码了解线程间通信机制.线程池的原理和优势.如何开启线程池等,力图通过多 ...

  5. 【Kafka】Kafka如何通过源码实现监控

    1.概述 问题导读: 1.kafka的消费者组的消费偏移存储,kafka支持两个版本? 2.ConsumerOffsetChecker类的作用是什么? 3.Kafka如何通过源码实现监控? 一,基本思 ...

  6. Nginx实战基础篇六 通过源码包编译安装部署LNMP搭建Discuz论坛

    Nginx实战基础篇六 通过源码包编译安装部署LNMP搭建Discuz论坛 版权声明: 本文遵循"署名非商业性使用相同方式共享 2.5 中国大陆"协议 您可以自由复制.发行.展览. ...

  7. Win10下通过源码编译安装QGIS

    1.前言 QGIS作为一款开源的桌面GIS软件,其易用性.稳定性和可扩展性受到越来越多的技术人员和学者的好评与支持,并且基于社区的开发模式使QGIS的研发和迭代非常迅速.目前,QGIS已经具有完整且稳 ...

  8. NoSQLRedis的介绍和Redis安装部署,通过yum在线安装Redis,通过源码安装Redis;

    目录 1.Redis简介 1).Redis是什么? 2).Redis能干嘛? 3).可以从哪里去下载Redis? 4).使用Redis进行的多种操作 5).Redis与其他数据库和软件的对比 2.Re ...

  9. AI电话销售机器人系统通过源码搭建安装的基本架构

    AI电话销售机器人系统通过源码搭建安装的基本架构 电话机器人系统,是通过云端智能语音识别+SIP,VOIP+底层呼叫控制(FS和ivr)+系统逻辑层搭建起来.系统逻辑功能包括根据预设话术,可自动拨打电 ...

最新文章

  1. oracle11g到底是什么6,Oracle11g六个重要进程
  2. python登录网页版微信发送消息
  3. 语义分析的一些方法(中篇)
  4. Codeforces 338 D. GCD Table
  5. 思科服务器 vmware虚拟多少个hba卡,利用Cisco UCS 管理虚拟机网络(上)
  6. percona zabbix mysql_zabbix采用percona监控mysql主从
  7. 分页输入框跳转 java_displaytag 分页-添加页码输入框跳转至指定页
  8. Forrester:华为云容器是容器混合云最佳选择
  9. 嵌入式操作系统内核原理和开发(优先级的修改)
  10. 西瓜书+实战+吴恩达机器学习(一)机器学习基础(数据集划分、分类回归评估指标)
  11. 惠普110a硒鼓加粉步骤_惠普打印机加粉教程(88a硒鼓/36a硒鼓/78a硒鼓)
  12. 智慧乡村建设不可照搬城市模式
  13. ajax 实时进度_三分钟搭建websocket实时在线聊天,项目经理也不敢这么写
  14. C++ modbus TCP 协议跟PLC通信
  15. 微信文章临时链接变永久链接
  16. 对已有apk进行重新签名
  17. 个人日记-学习究竟是什么读后感3-2020/7/13
  18. 【应用统计学】第一类/α/弃真错误与第二类/β/取伪错误的解释与举例
  19. 轻松5个步骤,解决企业内训师建设难题
  20. java计算机毕业设计苹果酒店住房管理源码+系统+数据库+lw文档+mybatis+运行部署

热门文章

  1. 摄影投票比赛链接制作微信投票的小程序可多选网络投票工具
  2. 数字签名功能及过程以及实例
  3. Python二维码生成器:将网址转换成图片二维码
  4. 夜间模式切换之开着火箭去月球Vue3版
  5. 声学参数-MEL-AutoVCPPG_hjk2标准: AutoVC超参数用WaveNet + GL恢复
  6. 佛經介紹 (佛教起信与入门)
  7. 关于接口中方法的implicitly与explicitly实现
  8. 7-8 字符串替换 (15 分)
  9. openGauss GRANT授权
  10. COSCon’22第七届中国开源年会火热筹备中,第一波赞助伙伴已集结,一起上车共赴开源盛宴吧~...