NLTK — декодирование Unicode в пользовательском корпусе

Я создал собственный корпус, используя CategorizedPlaintextCorpusReader nltk.

В файлах .txt моего корпуса есть символы Юникода, которые я не могу декодировать. Я предполагаю, что это тот факт, что это читатель «открытого текста», но, тем не менее, его нужно расшифровать.

Код:

import nltk
from nltk.corpus import CategorizedPlaintextCorpusReader
import os



mr = CategorizedPlaintextCorpusReader('C:\mycorpus', r'(?!\.).*\.txt',
        cat_pattern=os.path.join(r'(neg|pos)', '.*',))

for w in mr.words():
    print(w)

Это напечатает слова файлов, которые не содержат юникод, в токенизированном формате, а затем выдаст следующую ошибку:

for w in mr.words():
  File "C:\Python\Python36-32\lib\site-packages\nltk\corpus\reader\util.py", line 402, in iterate_from
    for tok in piece.iterate_from(max(0, start_tok-offset)):
  File "C:\Python\Python36-32\lib\site-packages\nltk\corpus\reader\util.py", line 296, in iterate_from
    tokens = self.read_block(self._stream)
  File "C:\Python\Python36-32\lib\site-packages\nltk\corpus\reader\plaintext.py", line 122, in _read_word_block
    words.extend(self._word_tokenizer.tokenize(stream.readline()))
  File "C:\Python\Python36-32\lib\site-packages\nltk\data.py", line 1168, in readline
    new_chars = self._read(readsize)
  File "C:\Python\Python36-32\lib\site-packages\nltk\data.py", line 1400, in _read
    chars, bytes_decoded = self._incr_decode(bytes)
  File "C:\Python\Python36-32\lib\site-packages\nltk\data.py", line 1431, in _incr_decode
    return self.decode(bytes, 'strict')
  File "C:\Python\Python36-32\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 30: invalid start byte

Я попытался декодировать с помощью:

mr.decode('unicode-escape') 

который выдает эту ошибку:

AttributeError: 'CategorizedPlaintextCorpusReader' object has no attribute 'decode'

Я использую Python 3.6.4.


person Yunter    schedule 21.02.2018    source источник
comment
Вы пытаетесь декодировать ридер, что невозможно. Вместо этого попробуйте расшифровать отдельные слова w.decode().   -  person DYZ    schedule 21.02.2018
comment
Спасибо за быстрый ответ, попытка декодировать «w» вызывает эту ошибку: AttributeError: объект «str» не имеет атрибута «декодировать»   -  person Yunter    schedule 21.02.2018
comment
Вы случайно не знаете, какое слово вызывает проблему?   -  person DYZ    schedule 21.02.2018
comment
Да, - и • (пункт) вызывает проблему. Другие юникоды работают нормально, например двоеточие:   -  person Yunter    schedule 21.02.2018


Ответы (1)


Проблема в том, что программа чтения корпусов NLTK предполагает, что ваши текстовые файлы были сохранены в кодировке UTF-8. Однако это предположение, по-видимому, неверно, так как файлы были закодированы другим кодеком. Я предполагаю, что использовался CP1252 (также известный как «Windows Latin-1»), потому что он довольно популярен и хорошо подходит под ваше описание: в этой кодировке длинное тире «–» кодируется байтом 0x96, который упоминается в сообщение об ошибке.

Вы можете указать кодировку входных файлов в конструкторе корпусного ридера:

mr = CategorizedPlaintextCorpusReader(
    'C:\mycorpus',
    r'(?!\.).*\.txt',
    cat_pattern=os.path.join(r'(neg|pos)', '.*',),
    encoding='cp1252')

Попробуйте это и проверьте, корректны ли символы, отличные от ASCII (длинное тире, маркеры), в выводе (и не заменены ли они моджибаке).

person lenz    schedule 21.02.2018