修改 python nltk.word_tokenize 排除“#”作为分隔符

Modify python nltk.word_tokenize to exclude "#" as delimiter

我正在使用 Python 的 NLTK 库来标记我的句子。

如果我的代码是

text = "C# billion dollars; we don't own an ounce C++"
print nltk.word_tokenize(text)

我得到这个作为我的输出

['C', '#', 'billion', 'dollars', ';', 'we', 'do', "n't", 'own', 'an', 'ounce', 'C++']

符号 ;.# 被视为分隔符。有没有办法从分隔符集中删除 #,例如 + 不是分隔符,因此 C++ 显示为单个标记?

我希望我的输出是

['C#', 'billion', 'dollars', ';', 'we', 'do', "n't", 'own', 'an', 'ounce', 'C++']

我希望 C# 被视为一个令牌。

NLTK 使用正则表达式来标记文本,因此您可以使用它的正则表达式标记器来定义您自己的正则表达式。

我将为您创建一个示例,其中文本将根据任何 space 字符(制表符、换行符、ecc)和几个其他符号进行拆分,例如:

>>> txt = "C# billion dollars; we don't own an ounce C++"
>>> regexp_tokenize(txt, pattern=r"\s|[\.,;']", gaps=True)
['C#', 'billion', 'dollars', 'we', 'don', 't', 'own', 'an', 'ounce', 'C++']

另一个想法:不要改变文本的标记化方式,只需遍历标记并将每个“#”与前面的标记连接起来。

txt = "C# billion dollars; we don't own an ounce C++"
tokens = word_tokenize(txt)

i_offset = 0
for i, t in enumerate(tokens):
    i -= i_offset
    if t == '#' and i > 0:
        left = tokens[:i-1]
        joined = [tokens[i - 1] + t]
        right = tokens[i + 1:]
        tokens = left + joined + right
        i_offset += 1

>>> tokens
['C#', 'billion', 'dollars', ';', 'we', 'do', "n't", 'own', 'an', 'ounce', 'C++']

在处理多词标记化时,另一种方法是使用 NLTK 重新标记提取的标记 Multi-Word Expression tokenizer

mwtokenizer = nltk.MWETokenizer(separator='')
mwtokenizer.add_mwe(('c', '#'))
mwtokenizer.tokenize(tokens)