Criação de um novo corpus com NLTK

83

Achei que muitas vezes a resposta ao meu título é ir e ler a documentação, mas eu li o livro NLTK, mas não dá a resposta. Sou meio novo em Python.

Tenho .txtmuitos arquivos e quero poder usar as funções de corpus que o NLTK fornece para o corpus nltk_data.

Eu tentei, PlaintextCorpusReadermas não consegui ir além de:

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

Como faço para segmentar as newcorpusfrases usando punkt? Tentei usar as funções punkt, mas as funções punkt não conseguiam ler a PlaintextCorpusReaderaula?

Você também pode me mostrar como posso escrever os dados segmentados em arquivos de texto?

Alvas
fonte

Respostas:

40

Acho que o PlaintextCorpusReaderjá segmenta a entrada com um tokenizer punkt, pelo menos se o seu idioma de entrada for o inglês.

Construtor 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'):

Você pode passar ao leitor um tokenizer de palavra e frase, mas para o último o padrão já é nltk.data.LazyLoader('tokenizers/punkt/english.pickle').

Para uma única string, um tokenizer seria usado da seguinte maneira (explicado aqui , consulte a seção 5 para obter o tokenizer 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
fonte
obrigada pelo esclarecimento. Entendi. mas como faço para enviar as frases segmentadas em um arquivo txt separado?
alvas
67

Depois de alguns anos tentando descobrir como funciona, aqui está o tutorial atualizado de

Como criar um corpus NLTK com um diretório de arquivos de texto?

A idéia principal é fazer uso do pacote nltk.corpus.reader . No caso de você ter um diretório de arquivos de texto em inglês , é melhor usar o PlaintextCorpusReader .

Se você tiver um diretório parecido com este:

newcorpus/
         file1.txt
         file2.txt
         ...

Basta usar essas linhas de código e você pode obter um corpus:

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

corpusdir = 'newcorpus/' # Directory of corpus.

newcorpus = PlaintextCorpusReader(corpusdir, '.*')

NOTA: que o PlaintextCorpusReaderusará o padrão nltk.tokenize.sent_tokenize()e nltk.tokenize.word_tokenize()para dividir seus textos em frases e palavras e essas funções são construídas para o inglês, pode NÃO funcionar para todos os idiomas.

Aqui está o código completo com a criação de arquivos de texto de teste e como criar um corpus com NLTK e como acessar o corpus em diferentes níveis:

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])

Por fim, para ler um diretório de textos e criar um corpus NLTK em outras linguagens, primeiro você deve garantir que tem uma tokenização de palavras e módulos de tokenização de frases que podem ser chamados de Python que recebe entrada de string / basestring e produz essa saída:

>>> 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
fonte
Obrigado pelo esclarecimento. Muitos idiomas são suportados por padrão, no entanto.
Andrew Tobey
1
Se alguém obtiver um AttributeError: __exit__erro. Use em open()vez 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
fonte
Atira alguns problemas para a linguagem 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
fonte