NLTK - 在自定义语料库中解码 Unicode
NLTK - Decoding Unicode in custom corpus
我使用 nltk 的 CategorizedPlaintextCorpusReader
创建了自定义语料库。
我的语料库的 .txt 文件中有我无法解码的 unicode 字符。我认为这是 "plaintext" reader 的事实,但仍然需要对其进行解码。
代码:
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)
这将以标记化格式打印不包含 unicode 的文件的单词,然后抛出以下错误:
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.
问题在于 NLTK 的语料库 reader 假定您的 plain-text 文件是使用 UTF-8 编码保存的。
然而,这个假设显然是错误的,因为文件是用另一个编解码器编码的。
我的猜测是使用了 CP1252(又名 "Windows Latin-1"),因为它非常流行并且很符合您的描述:在该编码中,破折号“–”使用字节 0x96
进行编码,即错误信息中提到。
您可以在语料库的构造函数中指定输入文件的编码reader:
mr = CategorizedPlaintextCorpusReader(
'C:\mycorpus',
r'(?!\.).*\.txt',
cat_pattern=os.path.join(r'(neg|pos)', '.*',),
encoding='cp1252')
试试这个,并检查 non-ASCII 个字符(em dash,bullet)在输出中是否仍然正确(并且没有被 mojibake 替换)。
我使用 nltk 的 CategorizedPlaintextCorpusReader
创建了自定义语料库。
我的语料库的 .txt 文件中有我无法解码的 unicode 字符。我认为这是 "plaintext" reader 的事实,但仍然需要对其进行解码。
代码:
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)
这将以标记化格式打印不包含 unicode 的文件的单词,然后抛出以下错误:
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.
问题在于 NLTK 的语料库 reader 假定您的 plain-text 文件是使用 UTF-8 编码保存的。
然而,这个假设显然是错误的,因为文件是用另一个编解码器编码的。
我的猜测是使用了 CP1252(又名 "Windows Latin-1"),因为它非常流行并且很符合您的描述:在该编码中,破折号“–”使用字节 0x96
进行编码,即错误信息中提到。
您可以在语料库的构造函数中指定输入文件的编码reader:
mr = CategorizedPlaintextCorpusReader(
'C:\mycorpus',
r'(?!\.).*\.txt',
cat_pattern=os.path.join(r'(neg|pos)', '.*',),
encoding='cp1252')
试试这个,并检查 non-ASCII 个字符(em dash,bullet)在输出中是否仍然正确(并且没有被 mojibake 替换)。