如何使用NLTK的默认标记生成器来获取跨度而不是字符串?

时间:2015-02-23 16:22:41

标签: python nltk tokenize

NLTK的默认标记器nltk.word_tokenizer链接两个标记器,一个句子标记器,然后是一个对句子进行操作的单词标记器。它的开箱即用非常好。

>>> nltk.word_tokenize("(Dr. Edwards is my friend.)")
['(', 'Dr.', 'Edwards', 'is', 'my', 'friend', '.', ')']

我想使用相同的算法,除非让它将偏移元组返回到原始字符串而不是字符串标记。

通过偏移,我的意思是可以作为原始字符串索引的2-ples。例如,我有

>>> s = "(Dr. Edwards is my friend.)"
>>> s.token_spans()
[(0,1), (1,4), (5,12), (13,15), (16,18), (19,25), (25,26), (26,27)]

因为s [0:1]是"(",s [1:4]是"博士"等等。

是否有一个NLTK调用可以执行此操作,还是必须编写自己的偏移算法?

4 个答案:

答案 0 :(得分:7)

是的,nltk中的大多数标记符都有一个名为span_tokenize的方法,但遗憾的是你使用的标记符并没有。

默认情况下,word_tokenize函数uses a TreebankWordTokenizerTreebankWordTokenizer实施具有相当强大的implementation但目前缺少一种重要方法span_tokenize的实现。

我发现span_tokenize没有TreebankWordTokenizer的实现,所以我相信你需要实现自己的span_tokenize。子类化TokenizerI可以使这个过程变得不那么复杂。

您可能会发现PunktWordTokenizer的{​​{1}}方法可用作starting point

我希望这些信息有所帮助。

答案 1 :(得分:2)

至少由于NLTK 3.4 TreebankWordTokenizer支持span_tokenize

>>> from nltk.tokenize import TreebankWordTokenizer as twt
>>> list(twt().span_tokenize('What is the airspeed of an unladen swallow ?'))
[(0, 4),
 (5, 7),
 (8, 11),
 (12, 20),
 (21, 23),
 (24, 26),
 (27, 34),
 (35, 42),
 (43, 44)]

答案 2 :(得分:0)

pytokenizations具有有用的功能get_original_spans以获取跨度:

# $ pip install pytokenizations
import tokenizations
text = "(Dr. Edwards is my friend.)"
tokens = nltk.word_tokenize(text)
tokenizations.get_original_spans(tokens, text)
>>> [(0,1), (1,4), (5,12), (13,15), (16,18), (19,25), (25,26), (26,27)]

有关其他有用的功能,请参见the documentation

答案 3 :(得分:0)

NLTK版本3.5的TreebankWordDetokenizer支持函数span_tokenize(),因此不再需要编写自己的偏移量算法:

>>> from nltk.tokenize import TreebankWordTokenizer
>>> s = '''Good muffins cost $3.88\\nin New (York).  Please (buy) me\\ntwo of them.\\n(Thanks).'''
>>> expected = [(0, 4), (5, 12), (13, 17), (18, 19), (19, 23),
... (24, 26), (27, 30), (31, 32), (32, 36), (36, 37), (37, 38),
... (40, 46), (47, 48), (48, 51), (51, 52), (53, 55), (56, 59),
... (60, 62), (63, 68), (69, 70), (70, 76), (76, 77), (77, 78)]
>>> list(TreebankWordTokenizer().span_tokenize(s)) == expected
True
>>> expected = ['Good', 'muffins', 'cost', '$', '3.88', 'in',
... 'New', '(', 'York', ')', '.', 'Please', '(', 'buy', ')',
... 'me', 'two', 'of', 'them.', '(', 'Thanks', ')', '.']
>>> [s[start:end] for start, end in TreebankWordTokenizer().span_tokenize(s)] == expected
True