将TextBlob中的POS标签转换为Wordnet兼容输入

2 投票
2 回答
2236 浏览
提问于 2025-04-18 14:54

我正在使用Python和nltk加上Textblob进行一些文本分析。很有意思的是,你可以为wordnet添加一个词性(POS),这样可以让你在寻找同义词时更具体。不过不幸的是,nltk和Textblob中的标记方式和wordnet对它的同义词集(synset)所期待的输入格式并不“兼容”。

举个例子 wordnet.synsets()需要你提供的词性是n(名词)、v(动词)、a(形容词)、r(副词)中的一种,像这样:

wn.synsets("dog", POS="n,v,a,r")

但是,来自upenn_treebank的标准词性标记看起来是这样的:

JJ, VBD, VBZ, etc.

所以我在寻找一个好的方法来在这两者之间进行转换。

有没有人知道除了暴力破解之外,还有什么好的方法可以实现这个转换?

2 个回答

0

这里有一个简单的函数,可以把宾夕法尼亚大学树库的标签转换成Wordnet的标签(a,v,r,n):

Penn2Wn = lambda t='VB': t[0].lower() if t[0] in ('V','R','J') else 'n'

就像@alvas的帖子中提到的,它会根据第一个字符的大小写来决定,如果合适的话,就用小写的第一个字符,或者默认用'n'。你可以用以下代码来测试:

Penn2Wn('VB')
Penn2Wn('PRP')
2

如果 textblob 使用的是 PennTreeBank (ptb) 标签集,那么只需要用词性标签的第一个字母来对应 WN 的词性标签。

WN 词性标签集包括:'a' 代表形容词/副词,'s' 代表卫星形容词,'n' 代表名词,'v' 代表动词。

试试:

>>> from nltk import word_tokenize, pos_tag
>>> from nltk.corpus import wordnet as wn
>>> text = 'this is a pos tagset in some foo bar paradigm'
>>> pos_tag(word_tokenize(text))
[('this', 'DT'), ('is', 'VBZ'), ('a', 'DT'), ('pos', 'NN'), ('tagset', 'NN'), ('in', 'IN'), ('some', 'DT'), ('foo', 'NN'), ('bar', 'NN'), ('paradigm', 'NN')]
>>> for tok, pos in pos_tag(word_tokenize(text)):
...     pos = pos[0].lower()
...     if pos in ['a', 'n', 'v']:
...             wn.synsets(tok, pos)
... 
[Synset('be.v.01'), Synset('be.v.02'), Synset('be.v.03'), Synset('exist.v.01'), Synset('be.v.05'), Synset('equal.v.01'), Synset('constitute.v.01'), Synset('be.v.08'), Synset('embody.v.02'), Synset('be.v.10'), Synset('be.v.11'), Synset('be.v.12'), Synset('cost.v.01')]
[Synset('polonium.n.01'), Synset('petty_officer.n.01'), Synset('po.n.03'), Synset('united_states_post_office.n.01')]
[]
[]
[Synset('barroom.n.01'), Synset('bar.n.02'), Synset('bar.n.03'), Synset('measure.n.07'), Synset('bar.n.05'), Synset('prevention.n.01'), Synset('bar.n.07'), Synset('bar.n.08'), Synset('legal_profession.n.01'), Synset('stripe.n.05'), Synset('cake.n.01'), Synset('browning_automatic_rifle.n.01'), Synset('bar.n.13'), Synset('bar.n.14'), Synset('bar.n.15')]
[Synset('paradigm.n.01'), Synset('prototype.n.01'), Synset('substitution_class.n.01'), Synset('paradigm.n.04')]

撰写回答