使用nltk进行Unicode的分词化

20

我有一些使用UTF-8编码的文本文件,其中包含像'ö'、'ü'等字符。我想解析这些文件中的文本,但是我无法让令牌化器正常工作。如果我使用标准的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分词似乎做得更好:

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个回答

20
更可能的情况是\uFEFF字符是从文件中读取的内容的一部分。我怀疑它不是由标记器插入的。\uFEFF在文件开头是字节顺序标记的已弃用形式。如果它出现在其他任何地方,则被视为零宽度不间断空格
这个文件是由Microsoft Notepad编写的吗?来自编解码器模块文档

为了增加检测UTF-8编码的可靠性,微软发明了UTF-8的变体(Python 2.5称之为“utf-8-sig”)用于其记事本程序:在任何Unicode字符被写入文件之前,都会写入一个UTF-8编码的BOM(它看起来像这样的字节序列:0xef,0xbb,0xbf)。

尝试使用codecs.open()读取文件。请注意,使用"utf-8-sig"编码可消耗BOM。
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'
>>> 

13

你应该确保将Unicode字符串传递给nltk分词器。我在我的机器上使用这两个分词器得到了与您的字符串相同的标记化结果:

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

4

UFEE码是一种“零宽不换行空格”字符,在re模块中不被视为空格,因此使用带有Unicode和dotall标志的正则表达式r'\w+|[^\w\s]+'PunktWordTokenizer()将识别此字符为单词。如果您不想手动删除该字符,则可以使用以下分词器:

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

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