Извлечение слов с помощью nltk из немецкого текста - PullRequest
8 голосов
/ 05 февраля 2012

Я пытаюсь извлечь слова из немецкого документа, когда я использую следующий метод, описанный в руководстве по nltk, я не могу получить слова со специальными символами для конкретного языка.

ptcr = nltk.corpus.PlaintextCorpusReader(Corpus, '.*');
words = nltk.Text(ptcr.words(DocumentName))

Что следует делатьЯ делаю, чтобы получить список слов в документе?

Пример с nltk.tokenize.WordPunctTokenizer() для немецкой фразы Veränderungen über einen Walzer выглядит следующим образом:

In [231]: nltk.tokenize.WordPunctTokenizer().tokenize(u"Veränderungen über einen Walzer")

Out[231]: [u'Ver\xc3', u'\xa4', u'nderungen', u'\xc3\xbcber', u'einen', u'Walzer']

В этом примере "ä"рассматривается как разделитель, хотя "ü" нет.

Ответы [ 3 ]

11 голосов
/ 06 февраля 2012

Вызовите PlaintextCorpusReader с параметром encoding = 'utf-8':

ptcr = nltk.corpus.PlaintextCorpusReader(Corpus, '.*', encoding='utf-8')

Редактировать: я вижу ... у вас есть две отдельные проблемы здесь:

а) Проблема токенизации: при тестировании с литеральной строкой из немецкого языка, Вы думаете Вы ввод юникода. На самом деле вы говорите Python, чтобы взять байты между кавычками и преобразовать их в строку Unicode. Но ваши байты в настоящее время неверно истолкованы. Исправление: добавьте следующую строку в самый верх вашего исходный файл.

# -*- coding: utf-8 -*-

Внезапно ваши константы будут правильно отображаться и маркироваться:

german = u"Veränderungen über einen Walzer"
print nltk.tokenize.WordPunctTokenizer().tokenize(german)

Вторая проблема: получается, что Text() не использует юникод! если ты передайте ей строку в кодировке Unicode, она попытается преобразовать ее в чисто ASCII строка, которая, конечно, не на входе без ascii. Тьфу.

Решение: Я бы порекомендовал избегать использования nltk.Text полностью и работать с читателями корпуса напрямую. (В общем, это хорошая идея: см. Собственную документацию nltk.Text).

Но если вы должны использовать nltk.Text с немецкими данными, вот как: данные правильно, так что они могут быть токенизированы, но затем «закодировать» свой юникод обратно в список str Для немецкого это возможно, безопаснее всего использовать кодировку Latin-1, но, похоже, работает utf-8 тоже.

ptcr = nltk.corpus.PlaintextCorpusReader(Corpus, '.*', encoding='utf-8');

# Convert unicode to utf8-encoded str
coded = [ tok.encode('utf-8') for tok in ptcr.words(DocumentName) ]
words = nltk.Text(coded)
3 голосов
/ 06 февраля 2012

Взгляните на http://text -processing.com / demo / tokenize / Я не уверен, что ваш текст получает правильную кодировку, так как WordPunctTokenizer в демоверсии прекрасно обрабатывает слова.Как и PunktWordTokenizer.

1 голос
/ 06 февраля 2012

Вы можете попробовать простое регулярное выражение. Следующего достаточно, если вы хотите только слова; он проглотит всю пунктуацию:

>>> import re
>>> re.findall("\w+", "Veränderungen über einen Walzer.".decode("utf-8"), re.U)
[u'Ver\xe4nderungen', u'\xfcber', u'einen', u'Walzer']

Обратите внимание, что re.U меняет значение \w в RE на основе текущей локали, поэтому убедитесь, что она установлена ​​правильно. У меня установлено значение en_US.UTF-8, что вполне достаточно для вашего примера.

Также обратите внимание, что "Veränderungen über einen Walzer".decode("utf-8") и u"Veränderungen über einen Walzer" - это разные строки.

...