使用nltk标记unicode

时间:2012-02-10 13:00:27

标签: python unicode nltk tokenize

我有使用utf-8编码的文本文件,其中包含'ö','ü'等字符。我想解析这些文件的文本形式,但我无法让tokenizer正常工作。如果我使用标准的nltk标记器:

f = open('C:\Python26\text.txt', 'r') # text = 'müsli pöök rääk'
text = f.read()
f.close
items = text.decode('utf8')
a = nltk.word_tokenize(items)

输出:[u'\ufeff', u'm', u'\xfc', u'sli', u'p', u'\xf6', u'\xf6', u'k', u'r', u'\xe4', u'\xe4', u'k']

Punkt tokenizer似乎做得更好:

f = open('C:\Python26\text.txt', 'r') # text = 'müsli pöök rääk'
text = f.read()
f.close
items = text.decode('utf8')
a = PunktWordTokenizer().tokenize(items)

输出:[u'\ufeffm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

在我无法弄清楚的第一个令牌之前仍然有'\ ufeff'(不是我不能删除它)。我究竟做错了什么?非常感谢。

3 个答案:

答案 0 :(得分:20)

\uFEFF char更有可能是从文件中读取的内容的一部分。我怀疑它是由tokeniser插入的。文件开头的\uFEFFByte Order Mark的弃用形式。如果它出现在其他任何地方,则将其视为zero width non-break space

该文件是由Microsoft记事本编写的吗?来自the codecs module docs

  

为了提高检测UTF-8编码的可靠性,Microsoft为其Notepad程序发明了一种UTF-8(Python 2.5称为“utf-8-sig”)的变体:在任何Unicode字符之前写入文件,写入UTF-8编码的BOM(看起来像字节序列:0xef,0xbb,0xbf)。

尝试使用codecs.open()来阅读您的文件。请注意消耗BOM的"utf-8-sig"编码。

import codecs
f = codecs.open('C:\Python26\text.txt', 'r', 'utf-8-sig')
text = f.read()
a = nltk.word_tokenize(text)

实验:

>>> open("x.txt", "r").read().decode("utf-8")
u'\ufeffm\xfcsli'
>>> import codecs
>>> codecs.open("x.txt", "r", "utf-8-sig").read()
u'm\xfcsli'
>>> 

答案 1 :(得分:13)

您应该确保将unicode字符串传递给nltk tokenizer。我得到了以下两个令牌化器的字符串相同的标记:

import nltk
nltk.wordpunct_tokenize('müsli pöök rääk'.decode('utf8'))
# output : [u'm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

nltk.word_tokenize('müsli pöök rääk'.decode('utf8'))
# output: [u'm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

答案 2 :(得分:4)

UFEE代码是“ZERO WIDTH NO-BREAK SPACE”字符,re模块不会将其视为空格,因此PunktWordTokenizer()使用正则表达式r'\w+|[^\w\s]+'使用unicode和dotall标志将此字符识别为单词。如果您不想手动删除该字符,可以使用以下标记生成器:

nltk.RegexpTokenizer(u'\w+|[^\w\s\ufeff]+')