Токенизация юникода с использованием nltk - PullRequest
18 голосов
/ 10 февраля 2012

У меня есть текстовые файлы, использующие кодировку 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 работает лучше:: [u'\ufeffm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

До первого токена все еще есть '\ ufeff', который я не могу понять (не то, что я не могу его удалить).Что я делаю неправильно?Помощь очень ценится.

Ответы [ 3 ]

20 голосов
/ 10 февраля 2012

Скорее всего, символ \uFEFF является частью содержимого, считанного из файла.Я сомневаюсь, что он был вставлен токенизатором.\uFEFF в начале файла является устаревшей формой Byte Order Mark .Если он появляется где-то еще, то он обрабатывается как пробел нулевой ширины без перерывов .

Был ли файл записан Microsoft Notepad?Начиная с модуль кодеков docs :

Чтобы повысить надежность, с которой может быть обнаружена кодировка UTF-8, Microsoft изобрела вариант UTF-8 (который вызывает Python 2.5)utf-8-sig ") для его программы Notepad: Перед тем, как в файл будет записан какой-либо из символов Unicode, записывается спецификация в кодировке UTF-8 (которая выглядит как последовательность байтов: 0xef, 0xbb, 0xbf).

Попробуйте прочитать ваш файл, используя codecs.open().Обратите внимание на кодировку "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'
>>> 
13 голосов
/ 29 марта 2012

Вы должны убедиться, что вы передаете строки 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 голосов
/ 10 февраля 2012

код UFEE является символом "ZERO WIDTH NO-BREAK SPACE", и он не рассматривается как пробел модулем re, поэтому PunktWordTokenizer(), использующий регулярное выражение r'\w+|[^\w\s]+' с флагами unicode и dotall, распознает этот персонаж как слово. Если вы не хотите удалять символ вручную, вы можете использовать следующий токенизатор:

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