创建ngram时,有没有办法告诉#textblob不要将let's之类的收缩分割为let's?我知道从技术上讲它们是两个单独的词,但我想将它们保持为一个。

最佳答案

您似乎在这里有两个选择:


更改tokenizer used in TextBlob
后处理令牌。


后者比较容易,但是比较慢。

改变模式

TextBlob接受nltk分词器,而我对它们更加熟悉,因此我们将使用它。 nltk的WordPunctTokenizer是具有"\\w+|[^\\w\\s]+"模式的RepexpTokenizer:

>>> nltk.tokenize.RegexpTokenizer("\\w+|[^\\w\\s]+").tokenize("Let's check this out.")
['Let', "'", 's', 'check', 'this', 'out', '.']


析取符前是\w+,它表示单词字符。析取符后是[^\w\s],它匹配非字符或空格(即标点符号)的任何内容。

如果要在单词中包含'以获得"let's",则可以将该字符添加到分离词的单词字符部分:

>>> nltk.tokenize.RegexpTokenizer("[\\w']+|[^\\w\\s]+").tokenize("Let's check this out.")
["Let's", 'check', 'this', 'out', '.']


后期处理

但是,正则表达式方法并不完美。我怀疑TextBlob的内置令牌生成器可能比我们可以使用正则表达式破解的更好。如果您严格希望将收缩作为一个标记,则建议仅对TextBlob的输出进行后处理。

>>> tokens = ["Let", "'s", "check", "this", "out", "."]
>>> def postproc(toks):
...     toks_out = []
...     while len(toks) > 1:
...             bigram = toks[:2]
...             if bigram[1][0] == "'":
...                     toks_out.append("".join(bigram))
...                     toks = toks[2:]
...             else:
...                     toks_out.append(bigram[0])
...                     toks = toks[1:]
...     toks_out.extend(toks)
...     return toks_out
...
>>> postproc(tokens)
["Let's", 'check', 'this', 'out', '.']


这样就可以完全解决您想要修复的问题,但是整个后期处理确实会增加代码的运行时间。

关于python - 用textblob ngram保留收缩,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30550411/

10-11 06:35