Python3自然语言处理——WordNet

Posted 引文空间

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3自然语言处理——WordNet相关的知识,希望对你有一定的参考价值。

1.WordNet介绍

WordNet 是面向语义的英语词典,类似于传统辞典,但具有更丰富的结构。NLTK 中包括英语 WordNet,共有 155,287 个词和 117,659 个同义词集合。我们将以寻找同义词和它们在 WordNet 中如何访问开始。

>>> from nltk.corpus import wordnet as wn>>> box='box'>>> box_synsets=wn.synsets(box)>>> box_synsets[Synset('box.n.01'), Synset('box.n.02'), Synset('box.n.03'), Synset('corner.n.08'), Synset('box.n.05'), Synset('box.n.06'), Synset('box.n.07'), Synset('box.n.08'), Synset('box.n.09'), Synset('box.n.10'), Synset('box.v.01'), Synset('box.v.02'), Synset('box.v.03')]

从输出可以看出,列表中包含13个synset,说明单词“box”存在着13种不同的含义。根据书上的代码来获得每个含义的定义、相关词条近义词、每个含义在句子中的示例:

>>> wn.synset('box.n.01').lemma_names<bound method Synset.lemma_names of Synset('box.n.01')>>>> wn.synset('box.n.01').definition<bound method Synset.definition of Synset('box.n.01')>>>> wn.synset('box.n.01').examples<bound method Synset.examples of Synset('box.n.01')>

我们可以看见Python3的输出与书上Python2的输出有所差别,不能直接显示我们想看的内容。在Python3中,我们可以添加for循环,迭代已经获得的Synsets列表并执行相关操作:

for synset in box_synsets: print(synset) print(synset.definition()) print(synset.lemma_names()) print(synset.examples())

结果如下:

Synset('box.n.01')a (usually rectangular) container; may have a lid['box']['he rummaged through a box of spare parts']Synset('box.n.02')private area in a theater or grandstand where a small group can watch the performance['box', 'loge']['the royal box was empty']Synset('box.n.03')the quantity contained in a box['box', 'boxful']['he gave her a box of chocolates']Synset('corner.n.08')a predicament from which a skillful or graceful escape is impossible['corner', 'box']['his lying got him into a tight corner']Synset('box.n.05')a rectangular drawing['box']['the flowchart contained many boxes']Synset('box.n.06')evergreen shrubs or small trees['box', 'boxwood'][]Synset('box.n.07')any one of several designated areas on a ball field where the batter or catcher or coaches are positioned['box']["the umpire warned the batter to stay in the batter's box"]Synset('box.n.08')the driver's seat on a coach['box', 'box_seat']['an armed guard sat in the box with the driver']Synset('box.n.09')separate partitioned area in a public place for a few people['box']['the sentry stayed in his box to avoid the cold']Synset('box.n.10')a blow with the hand (usually on the ear)['box']['I gave him a good box on the ear']Synset('box.v.01')put into a box['box', 'package']['box the gift, please']Synset('box.v.02')hit with the fist['box']["I'll box your ears!"]Synset('box.v.03')engage in a boxing match['box'][]

用这种方法,我们可以成功打印出单词box包含的13个含义的定义、词条和例句。


2.上位词与下位词

下位词(hyponym)与通用词(比如bat)相比较具有更具体的含义。更具体的含义指板球棒、棒球棒、食肉蝙蝠、壁球拍等等。这些下位词使我们在沟通中想要表达的含义更加具体。与下位词相反,上位词(hypernym)是更具有一般性的形式或词,包含相同的概念。就之前的例子而言,bat是一个更通用的词,它可能表示棍棒、棒、手工品、哺乳动物、动物或生物体。我们可以继续将它泛化成物质实体、生物或物体来作为bat这个词的上位词。为了探讨上位词和下位词的概念,我们选择同义词集bed.n.01(bed的第一个词义)和woman.n.01(woman的第一个词义)作为范例。在本节我们将介绍上位词和下位词的用法和含义。

from nltk.corpus import wordnet as wnbed=wn.synset('bed.n.01')woman=wn.synset('woman.n.01')

上位词

print(woman.hypernyms())

结果如下:

[Synset('adult.n.01'), Synset('female.n.02')]

woman隶属于WordNet数据库层次结构中的adult和female类别。

现在我们打印从根节点到woman.n.01节点的路径:

woman_paths=woman.hypernym_paths()for idx,path in enumerate(woman_paths): print('\n\nHypernym Path:',idx+1) for synset in path: print(synset.name(),',',end='')

结果如下:

Hypernym Path: 1entity.n.01 ,physical_entity.n.01 ,causal_agent.n.01 ,person.n.01 ,adult.n.01 ,woman.n.01 ,
Hypernym Path: 2entity.n.01 ,physical_entity.n.01 ,object.n.01 ,whole.n.02 ,living_thing.n.01 ,organism.n.01 ,person.n.01 ,adult.n.01 ,woman.n.01 ,
Hypernym Path: 3entity.n.01 ,physical_entity.n.01 ,causal_agent.n.01 ,person.n.01 ,female.n.02 ,woman.n.01 ,
Hypernym Path: 4entity.n.01 ,physical_entity.n.01 ,object.n.01 ,whole.n.02 ,living_thing.n.01 ,organism.n.01 ,person.n.01 ,female.n.02 ,woman.n.01 ,

如上所述,woman.n.01有两个上位词,即adult和female。我们还可以再输出中显示在WordNet数据库层次结构中从实体根节点到woman的四条不同路径。

下位词

以下两行代码将获取同义词bed.n.01的下位词并打印:

types_of_beds=bed.hyponyms()print('Types of beds(Hyponyms):\n',types_of_beds)

结果如下:

Types of beds(Hyponyms): [Synset('berth.n.03'), Synset('built-in_bed.n.01'), Synset('bunk.n.03'), Synset('bunk_bed.n.01'), Synset('cot.n.03'), Synset('couch.n.03'), Synset('deathbed.n.02'), Synset('double_bed.n.01'), Synset('four-poster.n.01'), Synset('hammock.n.02'), Synset('marriage_bed.n.01'), Synset('murphy_bed.n.01'), Synset('plank-bed.n.01'), Synset('platform_bed.n.01'), Synset('sickbed.n.01'), Synset('single_bed.n.01'), Synset('sleigh_bed.n.01'), Synset('trundle_bed.n.01'), Synset('twin_bed.n.01'), Synset('water_bed.n.01')]

在WordNet中,这些是单词词义bed.n.01的下位词或更具体的术语。

我们还可以打印出对我们来说更有意义的实际单词或词条(lemma):

print(sorted(set(lemma.name()for synset in types_of_beds for lemma in synset.lemmas())))

结果如下:

['Murphy_bed', 'berth', 'built-in_bed', 'built_in_bed', 'bunk', 'bunk_bed', 'camp_bed', 'cot', 'couch', 'deathbed', 'double_bed', 'four-poster', 'hammock', 'marriage_bed', 'plank-bed', 'platform_bed', 'sack', 'sickbed', 'single_bed', 'sleigh_bed', 'truckle', 'truckle_bed', 'trundle', 'trundle_bed', 'twin_bed', 'water_bed']

bed.n.01同义词词集有20个下位词,它们的含义更加具体且明确。由于几乎没有歧义,在层次结构中,下位词通常与叶子结点或非常接近叶子的结点相对应。


3.平均多义性

多义性意味着一个单词或短语有许多种可能的含义。正如之前看到的那样,英语是一种多歧义的语言,对层级结构中的大多数单词来说,通常包含一种以上的含义。我们必须根据WordNet中所有单词特定的语言特性来计算平均多义性。我们会展示如何计算一个单词在某种词性(POS)下的多义性,对于其余3类词性的多义性计算,你只需要修改相应程序即可。我们会在实例中提供足够的提示,让你更容易掌握。下面我们来看看单独计算名词的平均多义性的实例。

我们用n表示名词,对其进行初始化:

from nltk.corpus import wordnet as wntype='n'

该实例最重要的代码行如下:

synsets=wn.all_synsets(type)

这个API返回WordNet数据库中名词类型的所有同义词集。同样,如果将词性改为动词、副词或形容词,API将返回相应类型的所有单词。

把每个同义词集的所有词条合并成一个可以进一步处理的大列表。添加如下代码:

lemmas=[]for synset in synsets: for lemma in synset.lemmas(): lemmas.append(lemma.name())

这段代码非常直观,用一个嵌套的for循环迭代同义词集(synsets)列表和每个同义词集(synset)中的词条(lemmas)列表,并将它们添加到词条(lemmas)大列表中。

虽然这个大列表包含了所有词条,但仍存在一个问题。它是一个列表,所以有一些重复的内容,我们需要删除重复项,我们可以将一个列表转换成一个集合,就可以自动删除其中重复的内容:

lemmas=set(lemmas)

下面就可以计算WordNet数据库中所有词条含义的数量的总和:

count=0for lemma in lemmas: count=count+len(wn.synsets(lemma,type))

我们把重点放在wn.synsets API(lemma,type)上。这个API的输入是一个单词/词条(作为第一个参数)及其所属的词性,返回该单词/词条的所有含义。需要注意的是,输出取决于你提供的词性类别,因为它仅返回给定词性下的所有含义。现在已有平均多义性计算所需的所有数值,接下来只需要计算并打印出结果:

print('Total distinct lemmas:',len(lemmas))print('Total senses:',count)print('Average polysemy:',count/len(lemmas))

结果如下:

Total distinct lemmas: 119034Total senses: 152763Average polysemy: 1.2833560159282222

关于如何计算其他单词词性的平均多义性。正如实例所示,名词表示为n。类似地,动词表示为v,副词表示为r,形容词表示为a。

以上是关于Python3自然语言处理——WordNet的主要内容,如果未能解决你的问题,请参考以下文章

Python 的十个自然语言处理工具

python3+Cobal Strikeshellcode免杀技术

词义相似度计算

Python自然语言处理工具小结

《统计自然语言处理基础》容易忘记的知识点

如何升级到python3版本并且安装pip3及ipython3