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种不同的含义。根据书上的代码来获得每个含义的定义、相关词条近义词、每个含义在句子中的示例:
'box.n.01').lemma_names > wn.synset(
<bound method Synset.lemma_names of Synset('box.n.01')>
'box.n.01').definition > wn.synset(
<bound method Synset.definition of Synset('box.n.01')>
'box.n.01').examples > wn.synset(
<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 wn
bed=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: 1
entity.n.01 ,physical_entity.n.01 ,causal_agent.n.01 ,person.n.01 ,adult.n.01 ,woman.n.01 ,
Hypernym Path: 2
entity.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: 3
entity.n.01 ,physical_entity.n.01 ,causal_agent.n.01 ,person.n.01 ,female.n.02 ,woman.n.01 ,
Hypernym Path: 4
entity.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 wn
type='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=0
for 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))
结果如下:
119034 :
152763 :
1.2833560159282222 :
关于如何计算其他单词词性的平均多义性。正如实例所示,名词表示为n。类似地,动词表示为v,副词表示为r,形容词表示为a。
以上是关于Python3自然语言处理——WordNet的主要内容,如果未能解决你的问题,请参考以下文章