创建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/