将TextBlob中的POS标签转换为Wordnet兼容输入
我正在使用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')]