使用 textblob ngrams 保留收缩

Preserving contractions with textblob ngrams

有没有办法告诉#textblob 不是 在创建 ngram 时将 let's 等缩写拆分为 let's?我知道它们在技术上是两个独立的词,但我想将它们保持为一个。

看起来你有两个选择:

后者更容易,但更慢。

改变模式

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', '.']

Post-处理中

不过,正则表达式方法并不完美。我怀疑 TextBlob 的内置分词器可能比我们用正则表达式破解的要好一些。如果您确实想将缩写作为一个标记,我建议仅 post-processing 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', '.']

这样就可以准确地修复您想要修复的内容,但是整个 post- 处理确实会为您的代码增加 运行 时间。