2014-08-31 4 views
8

Ciao Sto cercando di imparare NLTK. Sono nuovo anche a Python. Sto provando il seguente.NLTK 3 POS_TAG genera UnicodeDecodeError

>>import nltk 
>>nltk.pos_tag(nltk.word_tokenize("John lived in China")) 

ottengo il seguente messaggio di errore

Traceback (most recent call last): File "", line 1, in nltk.pos_tag(nltk.word_tokenize("John lived in California")) File "C:\Python34\lib\site-packages\nltk\tag__init__.py", line 100, in pos_tag tagger = load(_POS_TAGGER) File "C:\Python34\lib\site-packages\nltk\data.py", line 779, in load resource_val = pickle.load(opened_resource) UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0: ordinal not in range(128)

Ho scaricato tutti i modelli disponibili (compreso il maxent_treebank_pos_tagger)

La codifica di sistema predefinito è UTF-8

>>sys.getdefaultencoding() 

Ho aperto il file data.py e questo è il contenuto disponibile.

774# Load the resource. 
775 opened_resource = _open(resource_url) 
776if format == 'raw': 
777   resource_val = opened_resource.read() 
778  elif format == 'pickle': 
779   resource_val = pickle.load(opened_resource) 
780  elif format == 'json': 
781   import json 

Cosa sto facendo di sbagliato qui?

risposta

15

OK, ho trovato la soluzione. Sembra un problema nella fonte stessa. Check here

Aprii data.py e modificate linea 779 come sotto

resource_val = pickle.load(opened_resource) #old 
resource_val = pickle.load(opened_resource, encoding='iso-8859-1') #new 
+2

-1 L'hard-coding di una codifica legacy obsoleta non è certo la soluzione giusta. – tripleee

+1

Qualsiasi altra soluzione che puoi fornire? –

+0

@ tripleee qualcosa è meglio di niente! –

2

Il problema fondamentale è che NLTK 2.x non è supportato per Python 3, e NLTK 3 è un continuo sforzo rilascia una versione completamente compatibile con Python 3.

La soluzione semplice consiste nel scaricare l'ultimo NLTK 3.x e utilizzarlo.

Se si desidera partecipare alla finitura della porta in Python 3, è probabilmente necessario avere una conoscenza più approfondita di differences between Python 2 and Python 3; in particolare, per questo caso, come il tipo di stringa fondamentale in Python 3 è una stringa Unicode (u'...'), non una stringa di byte (Python 3 b'...') come in Python 2. Vedere anche http://nedbatchelder.com/text/unipain.html

FWIW, vedi anche https://github.com/nltk/nltk/issues/169#issuecomment-12778108 per una correzione identica alla tua. Il bug a cui ti sei collegato è già stato corretto in NLTK 3.0 (presumibilmente da una correzione ai file di dati effettivi, penso in 3.0a3).

0

Usare Python 3.4 e NLTK 3 è possibile risolvere questo facendo:

f = open('myClassifier_or_X_trained_model',mode='rb') 
whereIuseTheModel = pickle.load(f,encoding='UTF-8') 

Nota che il modo di aprire è rb e encoding='uft-8'. Questa soluzione non richiede di modificare data.py.

0

Ho provato tutte le risposte, ma niente ha funzionato, per cui ha seguito i seguenti 2 collegamenti e quindi

https://github.com/nltk/nltk/issues/169

https://github.com/nltk/nltk_data/tree/gh-pages/packages/taggers

  • scaricato il file maxent_treebank_pos_tagger.zip.
  • scompattato e copiato il file english.pickle e sostituito i file english.pickle già presenti nella mia cartella nltk_data tag -> C: \ nltk_data \ taggers \ maxent_treebank_pos_tagger con quello nuovo.
  • Ho anche sostituito quello nella cartella C: \ nltk_data \ taggers \ maxent_treebank_pos_tagger \ PY3 con quello nuovo.

PS: Non so cos'altro potrebbe essere interessato ma per ora sto bene.

+0

Se è possibile fornire ulteriori informazioni sui collegamenti forniti (come alcuni termini di ricerca), renderebbe la risposta più solida, nel caso in cui i collegamenti vengano modificati/eliminati. – ryanyuyu

2

Vengo a questo ritardo, ma nel caso in cui aiuta qualcun altro che si imbatte in questo, che cosa ha funzionato per me è stato quello di decodificare il testo prima di metterlo in word_tokenize, vale a dire:

raw_text = "John lived in China" 
to_tokenize = raw_text.decode('utf-8') 
tokenized = nltk.word_tokenize(to_tokenize) 
output = nltk.pos_tag(tokenized) 

Forse Lavorerò per qualcun altro!