Creando un nuevo corpus con NLTK

83

Calculé que a menudo la respuesta a mi título es ir y leer la documentación, pero revisé el libro NLTK pero no da la respuesta. Soy un poco nuevo en Python.

Tengo un montón de .txtarchivos y quiero poder usar las funciones de corpus que NLTK proporciona para el corpus nltk_data.

Lo intenté PlaintextCorpusReaderpero no pude ir más allá de:

>>>import nltk
>>>from nltk.corpus import PlaintextCorpusReader
>>>corpus_root = './'
>>>newcorpus = PlaintextCorpusReader(corpus_root, '.*')
>>>newcorpus.words()

¿Cómo segmento las newcorpusoraciones usando punkt? Intenté usar las funciones punkt pero las funciones punkt no pudieron leer la PlaintextCorpusReaderclase.

¿También puede explicarme cómo puedo escribir los datos segmentados en archivos de texto?

alvas
fuente

Respuestas:

40

Creo que PlaintextCorpusReaderya segmenta la entrada con un tokenizador punkt, al menos si su idioma de entrada es el inglés.

Constructor de PlainTextCorpusReader

def __init__(self, root, fileids,
             word_tokenizer=WordPunctTokenizer(),
             sent_tokenizer=nltk.data.LazyLoader(
                 'tokenizers/punkt/english.pickle'),
             para_block_reader=read_blankline_block,
             encoding='utf8'):

Puede pasar al lector un tokenizador de palabras y oraciones, pero para este último el valor predeterminado ya es nltk.data.LazyLoader('tokenizers/punkt/english.pickle').

Para una sola cadena, se utilizaría un tokenizador de la siguiente manera (se explica aquí , consulte la sección 5 para el tokenizador de punkt).

>>> import nltk.data
>>> text = """
... Punkt knows that the periods in Mr. Smith and Johann S. Bach
... do not mark sentence boundaries.  And sometimes sentences
... can start with non-capitalized words.  i is a good variable
... name.
... """
>>> tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
>>> tokenizer.tokenize(text.strip())
Reiner Gerecke
fuente
gracias por la explicación. Entendido. pero, ¿cómo puedo generar las oraciones segmentadas en un archivo txt separado?
alvas
67

Después de algunos años de averiguar cómo funciona, aquí está el tutorial actualizado de

¿Cómo crear un corpus NLTK con un directorio de archivos de texto?

La idea principal es hacer uso del paquete nltk.corpus.reader . En el caso de que tenga un directorio de archivos de texto en inglés , es mejor usar PlaintextCorpusReader .

Si tiene un directorio que se parece a esto:

newcorpus/
         file1.txt
         file2.txt
         ...

Simplemente use estas líneas de código y puede obtener un corpus:

import os
from nltk.corpus.reader.plaintext import PlaintextCorpusReader

corpusdir = 'newcorpus/' # Directory of corpus.

newcorpus = PlaintextCorpusReader(corpusdir, '.*')

NOTA: que PlaintextCorpusReaderusará el valor predeterminado nltk.tokenize.sent_tokenize()y nltk.tokenize.word_tokenize()dividirá sus textos en oraciones y palabras y estas funciones están diseñadas para inglés, es posible que NO funcione para todos los idiomas.

Aquí está el código completo con la creación de archivos de texto de prueba y cómo crear un corpus con NLTK y cómo acceder al corpus en diferentes niveles:

import os
from nltk.corpus.reader.plaintext import PlaintextCorpusReader

# Let's create a corpus with 2 texts in different textfile.
txt1 = """This is a foo bar sentence.\nAnd this is the first txtfile in the corpus."""
txt2 = """Are you a foo bar? Yes I am. Possibly, everyone is.\n"""
corpus = [txt1,txt2]

# Make new dir for the corpus.
corpusdir = 'newcorpus/'
if not os.path.isdir(corpusdir):
    os.mkdir(corpusdir)

# Output the files into the directory.
filename = 0
for text in corpus:
    filename+=1
    with open(corpusdir+str(filename)+'.txt','w') as fout:
        print>>fout, text

# Check that our corpus do exist and the files are correct.
assert os.path.isdir(corpusdir)
for infile, text in zip(sorted(os.listdir(corpusdir)),corpus):
    assert open(corpusdir+infile,'r').read().strip() == text.strip()


# Create a new corpus by specifying the parameters
# (1) directory of the new corpus
# (2) the fileids of the corpus
# NOTE: in this case the fileids are simply the filenames.
newcorpus = PlaintextCorpusReader('newcorpus/', '.*')

# Access each file in the corpus.
for infile in sorted(newcorpus.fileids()):
    print infile # The fileids of each file.
    with newcorpus.open(infile) as fin: # Opens the file.
        print fin.read().strip() # Prints the content of the file
print

# Access the plaintext; outputs pure string/basestring.
print newcorpus.raw().strip()
print 

# Access paragraphs in the corpus. (list of list of list of strings)
# NOTE: NLTK automatically calls nltk.tokenize.sent_tokenize and 
#       nltk.tokenize.word_tokenize.
#
# Each element in the outermost list is a paragraph, and
# Each paragraph contains sentence(s), and
# Each sentence contains token(s)
print newcorpus.paras()
print

# To access pargraphs of a specific fileid.
print newcorpus.paras(newcorpus.fileids()[0])

# Access sentences in the corpus. (list of list of strings)
# NOTE: That the texts are flattened into sentences that contains tokens.
print newcorpus.sents()
print

# To access sentences of a specific fileid.
print newcorpus.sents(newcorpus.fileids()[0])

# Access just tokens/words in the corpus. (list of strings)
print newcorpus.words()

# To access tokens of a specific fileid.
print newcorpus.words(newcorpus.fileids()[0])

Finalmente, para leer un directorio de textos y crear un corpus NLTK en otros idiomas, primero debe asegurarse de tener módulos de tokenización de palabras y de oraciones que se puedan llamar en Python y que tomen la entrada de cadena / cadena base y produzcan dicha salida:

>>> from nltk.tokenize import sent_tokenize, word_tokenize
>>> txt1 = """This is a foo bar sentence.\nAnd this is the first txtfile in the corpus."""
>>> sent_tokenize(txt1)
['This is a foo bar sentence.', 'And this is the first txtfile in the corpus.']
>>> word_tokenize(sent_tokenize(txt1)[0])
['This', 'is', 'a', 'foo', 'bar', 'sentence', '.']
alvas
fuente
Gracias por la aclaración. Sin embargo, muchos idiomas son compatibles de forma predeterminada.
Andrew Tobey
1
Si alguien recibe un AttributeError: __exit__error. Usar en open()lugar dewith()
Tasdik Rahman
12
 >>> import nltk
 >>> from nltk.corpus import PlaintextCorpusReader
 >>> corpus_root = './'
 >>> newcorpus = PlaintextCorpusReader(corpus_root, '.*')
 """
 if the ./ dir contains the file my_corpus.txt, then you 
 can view say all the words it by doing this 
 """
 >>> newcorpus.words('my_corpus.txt')
Krolique
fuente
Dispara algún problema para el idioma devnagari.
ashim888
0
from nltk.corpus.reader.plaintext import PlaintextCorpusReader


filecontent1 = "This is a cow"
filecontent2 = "This is a Dog"

corpusdir = 'nltk_data/'
with open(corpusdir + 'content1.txt', 'w') as text_file:
    text_file.write(filecontent1)
with open(corpusdir + 'content2.txt', 'w') as text_file:
    text_file.write(filecontent2)

text_corpus = PlaintextCorpusReader(corpusdir, ["content1.txt", "content2.txt"])

no_of_words_corpus1 = len(text_corpus.words("content1.txt"))
print(no_of_words_corpus1)
no_of_unique_words_corpus1 = len(set(text_corpus.words("content1.txt")))

no_of_words_corpus2 = len(text_corpus.words("content2.txt"))
no_of_unique_words_corpus2 = len(set(text_corpus.words("content2.txt")))

enter code here
Pranab Bijoypuri
fuente