有没有一个用于将句子分割成单词列表的库?

4
我正在查看适用于Python的nltk,但它将won't分割(tokenize)为['wo',"n't"]。是否有更健壮的库可以解决这个问题?
我知道我可以构建某种正则表达式来解决这个问题,但我正在寻找一个库/工具,因为它会更加直接。例如,在基本的正则表达式中使用句号和逗号后,我意识到像'Mr.'这样的单词会破坏系统。
如果句子是“you won't?”,split()会给我["you", "won't?"]。所以有一个额外的'?'需要处理。我正在寻找一个经过验证的方法,可以避免上述提到的问题以及许多其他例外情况。当然,如果找不到任何方法,我会采用split(regex)。

3
抱歉如果我漏掉了什么,但为什么不使用text.split()函数呢? - Artsiom Rudzenka
5个回答

9

自然语言工具包(NLTK)可能是你需要的。

>>> from nltk.tokenize import word_tokenize
>>> word_tokenize("'Hello. This is a test.  It works!")
["'Hello", '.', 'This', 'is', 'a', 'test', '.', 'It', 'works', '!']
>>> word_tokenize("I won't fix your computer")
['I', 'wo', "n't", 'fix', 'your', 'computer']

默认情况下,nltk.tokenize.word_tokenize使用TreebankWordTokenizer,这是一个单词分词器,它使用Penn Treebank约定将句子分词。
请注意,此分词器假设文本已经被分成句子。
您可以在此页面上测试NLTK提供的各种分词器(例如WordPunctTokenizerWhitespaceTokenizer...)。

3
为什么要将“won't”拆分为“wo”和“n't”? - Cascabel
因为它实际上是两个单词,"won't" = "will not"。当然,它不够聪明,不能用"will"替换"wo",但例如在“don't”的情况下,它并不那么糟糕 :)。 - skorks
@Jefromi ntlk.word_tokenize 是一个单词分词器,它使用 Penn Treebank 使用的惯例来分词句子。根据这种分词方法,动词缩略形式和名词的盎格鲁-撒克逊属格被分成其组成的语素,并且每个语素都被单独标记(例如:won't --> wo n'the'll -> he 'll)。 - Paolo Moretti

5
尽管你所说的话,NLTK绝对是你最好的选择。在那里,你不会找到比标记器更“经过试验和测试”的方法(因为有些基于专门为此训练的分类器)。你只需要选择适合你需求的正确的标记器。我们来看下面这个句子:
I am a happy teapot that won't do stuff?

这里是NLTK中各种分词器将其拆分的方法。
TreebankWordTokenizer
I am a happy teapot that wo n't do stuff ?

WordPunctTokenizer

I am a happy teapot that won ' t do stuff ?

PunktWordTokenizer

I am a happy teapot that won 't do stuff ?

WhitespaceTokenizer

I am a happy teapot that won't do stuff?

您最好的选择可能是结合多种方法。例如,您可以首先使用PunktSentenceTokenizer对句子进行分词,这通常非常准确。然后,对于每个句子,在需要时删除末尾的标点符号。接下来,使用WhitespaceTokenizer,这样您就可以避免最终的标点符号/单词组合,例如stuff?,因为您已经从每个句子中删除了最终的标点符号,但您仍然知道句子的分界线(例如将它们存储在数组中),并且您不会意外地分解won't等单词。

3

@Karthick,这是我很久以前用过的一个简单算法,可以将文本拆分为单词列表:

  1. 输入文本
  2. 逐个字符迭代文本。
  3. 如果当前字符在“字母表”中,则将其附加到单词上。否则 - 将先前创建的单词添加到列表中并开始一个新单词。

alphabet = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
text = "I won't answer this question!"

word = ''
wordlist = []

for c in text:
    if c in alphabet:
        word += c
    else:
        if len(word) > 0:
            wordlist.append(word)
        word = ''

print wordlist
['I', "won't", 'answer', 'this', 'question']

这只是一个启动平台,您完全可以修改此算法使其更智能 :)


我想我只能这样做(使用正则表达式和分割)。=) - Karthick

1
NLTK 具有多种不同的分词器,您可以在 text-processing.com word tokenization demo 上查看每个分词器的演示。对于您的情况来说,最好的选择似乎是使用 WhitespaceTokenizer,这基本上与执行 string.split() 相同。

0
你可以尝试这个:
op = []
string_big = "One of Python's coolest features is the string format operator  This operator is unique to strings"
Flag = None
postion_start = 0
while postion_start < len(string_big):
    Flag = (' ' in string_big)
    if Flag == True:
        space_found = string_big.index(' ')
        print(string_big[postion_start:space_found])
        #print(space_found)
        op.append(string_big[postion_start:space_found])
        #postion_start = space_found
        string_big = string_big[space_found+1:len(string_big)]
        #print string_big
    else:
        op.append(string_big[postion_start:])
        break

print op

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接