打印词性及其同义词

4 投票
3 回答
4945 浏览
提问于 2025-04-16 17:27

我有一段代码,它可以从输入的文本文件中读取一个单词,然后使用WordNet打印出这个单词的同义词、定义和例句。这个代码会根据词性把同义词分开,也就是说,动词的同义词和形容词的同义词会分别打印出来。

比如,对于单词“flabbergasted”(惊讶的),它的同义词有:1)flabbergast(使惊讶)、boggle(使困惑)、bowl over(使震惊),这些都是动词;2)dumbfounded(目瞪口呆的)、dumfounded(震惊的)、flabbergasted(惊讶的)、stupefied(愚蠢的)、thunderstruck(震惊的)、dumbstruck(目瞪口呆的)、dumbstricken(惊呆的),这些都是形容词。

我想知道如何在打印同义词的时候,也把词性一起打印出来?下面是我目前写的代码:


import nltk
from nltk.corpus import wordnet as wn
tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
fp = open('sample.txt','r')
data = fp.read()
tokens= nltk.wordpunct_tokenize(data)
text = nltk.Text(tokens)
words = [w.lower() for w in text]
for a in words:
   print a 
syns = wn.synsets(a)
for s in syns:
   print 
   print "definition:" s.definition
   print "synonyms:"
   for l in s.lemmas:
      print l.name
   print "examples:"
   for b in s.examples:
      print b
   print 

3 个回答

1

一个词元(lemma)有一个叫做 synset 的属性,这个属性也有自己的词性,存放在 pos 属性里。所以,如果我们有一个词元叫 l,我们可以这样来获取它的词性:

>>> l = Lemma('gladden.v.01.joy')
>>> l.synset.pos
'v'

更一般来说,我们可以把这个过程扩展成一个循环,来读取你的文件。我使用 with 语句是因为它在循环完成后会自动关闭文件,这样比较方便。

>>> with open('sample.txt') as f:
...     raw = f.read()
...     for sentence in nltk.sent_tokenize(raw):
...         sentence = nltk.wordpunct_tokenize(sentence)
...         for word in sentence:
...             for synset in wn.synsets(word):
...                 for lemma in synset.lemmas:
...                     print lemma.name, lemma.synset.pos
...

如果你想确保只选择和你正在讨论的单词具有相同词性的词元,那么你也需要先找出那个单词的词性:

>>> import nltk
>>> from nltk.corpus import wordnet as wn
>>> with open('sample.txt') as f:
...     raw = f.read()
...     for sentence in nltk.sent_tokenize(raw):
...         sentence = nltk.pos_tag(nltk.wordpunct_tokenize(sentence))
...         for word, pos in sentence:
...             print word, pos

我会把如何对比这两者留给读者自己去练习。

1

看起来你的缩进搞错了:

for a in words:
   print a 
syns = wn.synsets(a)

似乎 syns = wn.synsets(a) 这行代码应该放在 words 的循环里面,这样你才能对每个单词都执行这个操作:

for w in words:
    print w
    syns = wn.synsets(w)
    for s in syns:
        print
        print "definition:", s.definition
        print "synonyms:"
        for l in s.lemmas:
            print l.name
        print "examples:"
        for b in s.examples:
            print b
    print
2

你只需要在一个同义词集合(synset)上调用 pos() 方法,就可以得到它的词性。如果想列出一个词的所有词性,可以这样做:

>>> from nltk.corpus import wordnet as wn
>>> syns = wn.synsets('dog')
>>> set([x.pos() for x in syns])
{'n', 'v'}

不过很遗憾,这个方法似乎没有在任何地方详细说明,除了源代码,那里展示了可以在同义词集合上调用的其他方法。

同义词集合的属性,可以通过同名的方法访问:

  • name: 这个同义词集合的标准名称,是用这个同义词集合的第一个词形成的。注意,这个名称可能和创建这个同义词集合时传入的名称不同,因为可能用了不同的词来识别这个同义词集合。
  • pos: 这个同义词集合的词性,对应模块中的属性,比如形容词(ADJ)、形容词(ADJ_SAT)、副词(ADV)、名词(NOUN)或动词(VERB)。
  • lemmas: 这个同义词集合的词条对象列表。
  • definition: 这个同义词集合的定义。
  • examples: 这个同义词集合的例句列表。
  • offset: 这个同义词集合在WordNet字典文件中的偏移量。
  • lexname: 包含这个同义词集合的词典编纂者文件的名称。

撰写回答