Tworzenie nowego korpusu za pomocą NLTK

83

Wydawało mi się, że często odpowiedzią na mój tytuł jest przeczytanie dokumentacji, ale przejrzałem książkę NLTK, ale ona nie daje odpowiedzi. Jestem trochę nowy w Pythonie.

Mam kilka .txtplików i chcę móc korzystać z funkcji korpusu, które NLTK zapewnia dla korpusu nltk_data.

Próbowałem, PlaintextCorpusReaderale nie mogłem posunąć się dalej niż:

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

Jak posegmentować newcorpuszdania za pomocą punktu? Próbowałem użyć funkcji punktowych, ale funkcje punktowe nie mogą odczytać PlaintextCorpusReaderklasy?

Czy możesz mnie również wskazać, jak mogę zapisać posegmentowane dane w plikach tekstowych?

alvas
źródło

Odpowiedzi:

40

Myślę, że PlaintextCorpusReaderjuż segmentuje dane wejściowe za pomocą tokenizera punktowego, przynajmniej jeśli twoim językiem wprowadzania jest angielski.

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

Możesz przekazać czytelnikowi tokenizer słów i zdań, ale dla tego drugiego wartość domyślna już jest nltk.data.LazyLoader('tokenizers/punkt/english.pickle').

W przypadku pojedynczego ciągu znaków tokenizer zostanie użyty w następujący sposób (wyjaśniono tutaj , zobacz sekcję 5 o tokenizatorze punktowym).

>>> 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
źródło
Dziękuję za wyjaśnienie. Rozumiem. ale jak wyprowadzić podzielone na segmenty zdania do oddzielnego pliku txt?
alvas
68

Po kilku latach zastanawiania się, jak to działa, oto zaktualizowany samouczek

Jak stworzyć korpus NLTK z katalogiem plików tekstowych?

Głównym zamysłem jest wykorzystanie pakietu nltk.corpus.reader . W przypadku, gdy masz katalog plików tekstowych w języku angielskim , najlepiej użyć PlaintextCorpusReader .

Jeśli masz katalog, który wygląda tak:

newcorpus/
         file1.txt
         file2.txt
         ...

Po prostu użyj tych linii kodu, a otrzymasz korpus:

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

corpusdir = 'newcorpus/' # Directory of corpus.

newcorpus = PlaintextCorpusReader(corpusdir, '.*')

UWAGA: że PlaintextCorpusReaderbędzie używał wartości domyślnych nltk.tokenize.sent_tokenize()i nltk.tokenize.word_tokenize()do dzielenia tekstów na zdania i słowa, a te funkcje są zbudowane dla języka angielskiego, może NIE działać we wszystkich językach.

Oto pełny kod z tworzeniem testowych plików tekstowych i sposobem tworzenia korpusu za pomocą NLTK oraz jak uzyskać dostęp do korpusu na różnych poziomach:

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

Wreszcie, aby odczytać katalog tekstów i utworzyć korpus NLTK w innych językach, musisz najpierw upewnić się, że masz moduły tokenizacji słów i tokenizacji zdań wywoływane przez Pythona , które przyjmują dane wejściowe typu string / basestring i generują takie dane wyjściowe:

>>> 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
źródło
Dziękuję za wyjaśnienie. Jednak wiele języków jest obsługiwanych domyślnie.
Andrew Tobey
1
Jeśli ktoś otrzyma AttributeError: __exit__błąd. Użyj open()zamiastwith()
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
źródło
Występuje problem z językiem 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
źródło