【问题标题】:utf8 encoding lost after tokenising using NLTK and Python 2.7使用 NLTK 和 Python 2.7 进行标记化后,utf8 编码丢失
【发布时间】:2016-08-18 11:13:53
【问题描述】:

我在尝试使用 nltk(版本 3.1,python 2.7)标记法文文本时遇到了一个有趣的问题。这是我正在使用的代码 sn-p。

#python 2.7

from __future__ import division
import nltk, re, pprint

f= open('test.txt')

raw = f.read()
print "got it!"
print type(raw)

ucoderaw=raw.decode('utf-8')
print ucoderaw

tokens = nltk.word_tokenize(ucoderaw)
print type(tokens)
words = [w.lower() for w in tokens]
print type(words)
vocab = sorted(set(words))
print "Tokens"

该文档包含法文文本:

J'ai lieu de croire que Mr. de Voltaire ne sera pas fâché de voir que 儿子 Manuscrit, qu'il a intitulé Abrégé de l'Histoire Universelle depuis Charlemagne jusqu'à Charles-Quint, et qu'il dit être entre les mains de trente Particuliers, soit tombé entre les miennes。我说 qu'il m'en avait flatté dès l'année 1742, à l'occasion de son Siècle de Louis XIV, auquel je ne renonçai en 1750, que parce qu'il me dit alors à Postdam, où j'étais, qu'il l'imprimait lui-même à ses propres 取决于。 Ainsi il ne s'agit ici que de dire comment cet Abrégé m'est tombé entre les mains, le voici。

À mon retour de Paris, en Juin de cette annee 1753, je m'arrêtai à Bruxelles, où j'eus l'honneur de voir une Personne de mérite, qui en étant le holdereur me le fit voir, et m'en fit aussi tout l'éloge 想象的,de meme que l'histoire du Manuscrit, et de tout ce qui s'était passé à l'occasion d'un Ave​​rtissement qui se trouve inséré 丹斯勒 second Volume du mois de Juin 1752 du Mercure de France, et répété dans l'Épilogueur du 31 Juillet de la meme annee, avec la Réponse que l'on y a faite, et qui se trouve dans le meme Épilogueur du 7 Août suivant: toutes 选择 inutiles à relever ici, mais qui m'ont ensuite determiné à acheter des mains de ce Galant-Homme le Manuscrit après avoir été offert à l'Auteur, bien persuadé d'ailleurs qu'il était effectment de 伏尔泰先生;儿子精灵,儿子风格等 surtout son orthographe s'y trouvant partout。 J'ai changé cette dernière, parce qu'il est notoire que le Public a toutes les peines du monde à s'y accoutumer; et c'est ce que l'Auteur est prié de vouloir [1]

Je dois encore faire remarquer que par la dernière période de ce Livre, il paraît qu'elle fait la clôture de cet Abrégé, qui finit à Charles VII Roi de France, au lieu que l'Auteur la promet par son Titre jusqu'à l'Empereur Charles-Quint。 Ainsi il est à présumer que ce qui devrait suivre, est cette partie différente d'Histoire qui 关注 les Arts, qu'il serait à souhaiter que Mr. de Voltaire retrouvât, ou, pour mieux dire, qu'il voulût bien refaire, et la pousser jusqu'au Siècle de Louis XIV, afin de remplir son plan, et de nous donner ainsi une suite d'Histoire qui ferait grand plaisir au Public et aux Libraires。

当我尝试使用 tokens = nltk.word_tokenize(ucoderaw) 标记该文本时

然后随后使用sorted(set(words)) 打印出令牌

我得到了 utf-8 编码损坏的输出:

u'autant', u'author', u'autres', u'aux', u'available', u'avait', u'avant', u'avec', u'avertissement', u'avoir', u'avons', u'away', u'ayant', u'barbare', u'beaucoup', u'biblioth\xe8que', u'bien', u'bnf/gallica', u'bornais', u'bruxelles', u'but', u'by', u"c'est", u'capet', u'carri\xe8re', u'ce', u'cela', u'ces', u'cet', u'cette', u'ceux', u'chang\xe9', u'chaos', u'character', u'charger', u'charlemagne',u'charlequint',u'charles-quint_',u'chartes', u'chez', u'chine', u'choses', u'chronologie', u'chronologiques', u'chr\xe9tienne', u'cl\xf4ture'

正确的输出应包含重音符号,即 bibliothèque 而不是 biblioth\xe8que

我一直试图弄清楚如何解决这个问题,除了将输出保存到文件并编写另一个程序来用 è 替换 \xe8 等等。

有没有更简单的方法?

编辑:不是最干净的解决方案,但是我发现通过标记化然后将该输出保存到具有正确编码的文件中(主要是获得所需的输出):

#python 2.7

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

from __future__ import division
import nltk, re, pprint

f= open('test.txt')

raw = f.read()


print "got it!"

#print raw

print type(raw)

#encode as utf8 before moving on.
ucoderaw=raw.decode('utf-8')

tokens = nltk.word_tokenize(ucoderaw)

print type(tokens)

words = [w.lower() for w in tokens]

print type(words)

vocab = sorted(set(words))

print "encoded raw input is"
print ucoderaw


#                 GET TOKENS

print vocab
#write to file with correct encoding to "fix" the problem
output_file = open('output.txt', 'w')

print len(vocab)
for words in vocab:
    output_file.write(words.encode('utf-8') + "\n") 

【问题讨论】:

  • 简短答案:使用python3 =) 更长答案:不要使用open,使用io.open('filename.txt', 'r', encoding='utf8') 更好的答案:查看nedbatchelder.com/text/unipain.html,然后仍然使用python3

标签: python-2.7 utf-8 character-encoding nltk


【解决方案1】:

首先,见http://nedbatchelder.com/text/unipain.html

然后尝试使用Python3 代替Python2 进行文本处理,它让你的生活更轻松=)

最后,不管是 Py3 还是 Py2,使用 io.open 而不是 open 是一种很好的做法,这样您的代码就可以在 Py3 和 Py2 上运行:

import io
from collections import Counter
import nltk

# Try to open files within a context, see 
# https://www.python.org/dev/peps/pep-0343/ and 
# http://effbot.org/zone/python-with-statement.htm
with io.open('test.txt', 'r', encoding='utf8') as fin:
    word_counts = Counter(word_tokenize(fin.read()))
    # List of top most common words.
    print word_counts.most_common()
    # Sorted by counts
    print word_counts.most_common(len(word_counts))
    # Sorted alphabetically
    print sorted(word_counts.keys())

【讨论】:

    猜你喜欢
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多