¿Cómo generar trozos NLTK para archivar?

Tengo esta secuencia de comandos de Python en la que estoy utilizando la biblioteca nltk para analizar, tokenizar, etiquetar y fragmentar, algunos digamos texto aleatorio de la web.

Necesito formatear y escribir en un archivo la salida de chunked1 , chunked2 , chunked3 . Estos tienen class 'nltk.tree.Tree' tipo class 'nltk.tree.Tree'

Más específicamente, necesito escribir solo las líneas que coincidan con las expresiones regulares chunkGram1 , chunkGram2 , chunkGram3 .

¿Cómo puedo hacer eso?

 #! /usr/bin/python2.7 import nltk import re import codecs xstring = ["An electronic library (also referred to as digital library or digital repository) is a focused collection of digital objects that can include text, visual material, audio material, video material, stored as electronic media formats (as opposed to print, micro form, or other media), along with means for organizing, storing, and retrieving the files and media contained in the library collection. Digital libraries can vary immensely in size and scope, and can be maintained by individuals, organizations, or affiliated with established physical library buildings or institutions, or with academic institutions.[1] The electronic content may be stored locally, or accessed remotely via computer networks. An electronic library is a type of information retrieval system."] def processLanguage(): for item in xstring: tokenized = nltk.word_tokenize(item) tagged = nltk.pos_tag(tokenized) #print tokenized #print tagged chunkGram1 = r"""Chunk: {*}""" chunkGram2 = r"""Chunk: {*}""" chunkGram3 = r"""Chunk: {*}""" chunkParser1 = nltk.RegexpParser(chunkGram1) chunked1 = chunkParser1.parse(tagged) chunkParser2 = nltk.RegexpParser(chunkGram2) chunked2 = chunkParser2.parse(tagged) chunkParser3 = nltk.RegexpParser(chunkGram3) chunked3 = chunkParser2.parse(tagged) #print chunked1 #print chunked2 #print chunked3 # with codecs.open('path\to\file\output.txt', 'w', encoding='utf8') as outfile: # for i,line in enumerate(chunked1): # if "JJ" in line: # outfile.write(line) # elif "NNP" in line: # outfile.write(line) processLanguage() 

Por el momento, cuando bash ejecutarlo, obtengo un error:

 `Traceback (most recent call last): File "sentdex.py", line 47, in  processLanguage() File "sentdex.py", line 40, in processLanguage outfile.write(line) File "C:\Python27\lib\codecs.py", line 688, in write return self.writer.write(data) File "C:\Python27\lib\codecs.py", line 351, in write data, consumed = self.encode(object, self.errors) TypeError: coercing to Unicode: need string or buffer, tuple found` 

Edición: Después de la respuesta de @Alvas, logré hacer lo que quería. Sin embargo, ahora me gustaría saber cómo puedo eliminar todos los caracteres que no son ASCII de un cuerpo de texto. ejemplo:

 #store cleaned file into variable with open('path\to\file.txt', 'r') as infile: xstring = infile.readlines() infile.close def remove_non_ascii(line): return ''.join([i if ord(i) < 128 else ' ' for i in line]) for i, line in enumerate(xstring): line = remove_non_ascii(line) #tokenize and tag text def processLanguage(): for item in xstring: tokenized = nltk.word_tokenize(item) tagged = nltk.pos_tag(tokenized) print tokenized print tagged processLanguage() 

Esto arriba está tomado de otra respuesta aquí en S / O. Sin embargo, no parece funcionar. ¿Qué podría estar mal? El error que estoy recibiendo es:

 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position not in range(128) 

Su código tiene varios problemas, aunque el principal culpable es que su bucle for no modifica el contenido de xstring :

Abordaré todos los problemas en su código aquí:

no puede escribir rutas como esta con solo \ , ya que \t se interpretará como un tabulador, y \f como un carácter de salto de línea. Debes doblarlos. Sé que fue un ejemplo aquí, pero a menudo surgen tales confusiones:

 with open('path\\to\\file.txt', 'r') as infile: xstring = infile.readlines() 

La siguiente línea de infile.close es incorrecta . No llama al método de cierre, en realidad no hace nada. Además, su archivo ya estaba cerrado por la cláusula with si ve esta línea en cualquier respuesta en cualquier lugar, por favor simplemente descarte la respuesta con un comentario que diga que file.close es incorrecto, debe ser file.close() .

Lo siguiente debería funcionar, pero debe tener en cuenta que reemplazando a todos los personajes que no sean ascii con ' ' romperá palabras como ingenuo y café

 def remove_non_ascii(line): return ''.join([i if ord(i) < 128 else ' ' for i in line]) 

Pero aquí está la razón por la que su código falla con una excepción de Unicode: no está modificando los elementos de xstring en absoluto, es decir, está calculando la línea con caracteres ASCII eliminados, sí, pero ese es un nuevo valor, que nunca es almacenado en la lista:

 for i, line in enumerate(xstring): line = remove_non_ascii(line) 

En su lugar debería ser:

 for i, line in enumerate(xstring): xstring[i] = remove_non_ascii(line) 

o mi preferido muy pythonico:

 xstring = [ remove_non_ascii(line) for line in xstring ] 

Aunque estos errores de Unicode se producen principalmente solo porque está usando Python 2.7 para manejar el texto puro de Unicode, algo por lo que las versiones recientes de Python 3 están muy por delante, por lo tanto, le recomiendo que, si está comenzando con una tarea que actualizaría a Python 3.4+ pronto.

En primer lugar, vea este video: https://www.youtube.com/watch?v=0Ef9GudbxXY

introduzca la descripción de la imagen aquí

Ahora para la respuesta correcta:

 import re import io from nltk import pos_tag, word_tokenize, sent_tokenize, RegexpParser xstring = u"An electronic library (also referred to as digital library or digital repository) is a focused collection of digital objects that can include text, visual material, audio material, video material, stored as electronic media formats (as opposed to print, micro form, or other media), along with means for organizing, storing, and retrieving the files and media contained in the library collection. Digital libraries can vary immensely in size and scope, and can be maintained by individuals, organizations, or affiliated with established physical library buildings or institutions, or with academic institutions.[1] The electronic content may be stored locally, or accessed remotely via computer networks. An electronic library is a type of information retrieval system." chunkGram1 = r"""Chunk: {*}""" chunkParser1 = RegexpParser(chunkGram1) chunked = [chunkParser1.parse(pos_tag(word_tokenize(sent))) for sent in sent_tokenize(xstring)] with io.open('outfile', 'w', encoding='utf8') as fout: for chunk in chunked: fout.write(str(chunk)+'\n\n') 

[afuera]:

 alvas@ubi:~$ python test2.py Traceback (most recent call last): File "test2.py", line 18, in  fout.write(str(chunk)+'\n\n') TypeError: must be unicode, not str alvas@ubi:~$ python3 test2.py alvas@ubi:~$ head outfile (S An/DT (Chunk electronic/JJ library/NN) (/: also/RB referred/VBD to/TO as/IN (Chunk digital/JJ library/NN) or/CC 

Si tienes que apegarte a python2.7:

 with io.open('outfile', 'w', encoding='utf8') as fout: for chunk in chunked: fout.write(unicode(chunk)+'\n\n') 

[afuera]:

 alvas@ubi:~$ python test2.py alvas@ubi:~$ head outfile (S An/DT (Chunk electronic/JJ library/NN) (/: also/RB referred/VBD to/TO as/IN (Chunk digital/JJ library/NN) or/CC alvas@ubi:~$ python3 test2.py Traceback (most recent call last): File "test2.py", line 18, in  fout.write(unicode(chunk)+'\n\n') NameError: name 'unicode' is not defined 

Y muy recomendable si debes seguir con py2.7:

 from six import text_type with io.open('outfile', 'w', encoding='utf8') as fout: for chunk in chunked: fout.write(text_type(chunk)+'\n\n') 

[afuera]:

 alvas@ubi:~$ python test2.py alvas@ubi:~$ head outfile (S An/DT (Chunk electronic/JJ library/NN) (/: also/RB referred/VBD to/TO as/IN (Chunk digital/JJ library/NN) or/CC alvas@ubi:~$ python3 test2.py alvas@ubi:~$ head outfile (S An/DT (Chunk electronic/JJ library/NN) (/: also/RB referred/VBD to/TO as/IN (Chunk digital/JJ library/NN) or/CC