使用NLTK和Python 2.7进行令牌化后,utf8编码丢失

时间:2016-08-18 11:13:53

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

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

#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 serapasfâchédevoir que   儿子Manuscrit,qu'ilaintituléAbrégédel'Histoire Universelle   depuisCharlemagnejusqu'àCharles-Quint ,et qu'ilditêtreentreles   mains de trente Particuliers,soittombéentreles miennes。 Il sait   qu'il m'enavaitlattédèsl'année1742,àl'posrsdesonSiècle   de Louis XIV,auquel jenerenonçaien1750,que parce qu'il me dit   alorsàPostdam,oùj'étais,qu'il l'imprimait lui-mêmeàsespropres   实际上还要考虑。 Ainsi il ne s'agit ici que de dire commentcetAbrégém'est   tombéentreles mains,le voici。

     

Àmonretour de Paris,en Juin decetteanné1753,jem'arrêtaià   Bruxelles,oùj'eusl'honneur de voir une Personnedemérite,qui en   étantlepossesseur me le fit voir,et m'en fit aussi tout l'éloge   可以想象,demêmequel'histoire du Manuscrit,et de tout ce qui   s'étaitpasséàl'posrsd'un Avertissement qui setrouveinséré   丹斯勒   第二卷du mois de Juin 1752 du Mercure de France ,etrépétédansl'Épilogueurdu31 Juillet delamêmeannée,aveclaRéponse   如果你喜欢这样的话,可以去看看他们是不是真的很棒   Août-suivant :触摸选择inutilesàdeververici,mais qui m'ont   保险公司 - 加利福尼亚州的曼彻斯特公寓   Aprèsavoirétéoffertàl'Auteur,bienpersuadéd'ailleursqu'il   étaitadctmentde de Voltaire;儿子génie,儿子风格等   surtout son orthographe s'y trouvant partout。 Jaiaingécette   dernière,parce qu'il est notoire que le Public a toutes les peines du   mondeàs'yaccoutumer; et c'est ce que l'Auteurestpriédevouloir   bien excuser。[1]

     

Je dois encore faire remarquer que parladernièrepériodedece   Livre,ilparaîtqu'ellefaitlaclôturedecetAbrégé,quifinità    Charles VII Roi de France ,au lieu que l'Auteur la promet par sonTitrejusqu'àl' Empereur Charles-Quint 。 Ainsi ilestàprésumerque   ce qui devrait suivre,est cettepartiedifférented'Histoirequi   关注 les Arts ,qu'ilseraitàsouhaiterque Mr. de Voltaire   retrouvât,ou,pour mieux dire,qu'ilvoulûtbienrefaire,et la   pousser jusqu'au SiècledeLouis 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") 

1 个答案:

答案 0 :(得分:0)

首先,请参阅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())