Erstellen eines neuen Korpus mit NLTK

83

Ich rechnete damit, dass die Antwort auf meinen Titel oft darin besteht, die Dokumentationen zu lesen, aber ich habe das NLTK-Buch durchgesehen aber es gibt keine Antwort. Ich bin ein bisschen neu in Python.

Ich habe eine Reihe von .txtDateien und möchte die Korpusfunktionen verwenden können, die NLTK für den Korpus bereitstelltnltk_data .

Ich habe es versucht, PlaintextCorpusReaderaber ich konnte nicht weiter kommen als:

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

Wie segmentiere ich die newcorpusSätze mit punkt? Ich habe versucht, die Punkt-Funktionen zu verwenden, aber die Punkt-Funktionen konnten nicht lesenPlaintextCorpusReader Klasse .

Können Sie mich auch dazu führen, wie ich die segmentierten Daten in Textdateien schreiben kann?

Alvas
quelle

Antworten:

40

Ich denke, das PlaintextCorpusReadersegmentiert die Eingabe bereits mit einem Punkt-Tokenizer, zumindest wenn Ihre Eingabesprache Englisch ist.

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

Sie können dem Leser einen Tokenizer für Wörter und Sätze übergeben, für letzteren ist die Standardeinstellung jedoch bereits nltk.data.LazyLoader('tokenizers/punkt/english.pickle').

Für eine einzelne Zeichenfolge wird ein Tokenizer wie folgt verwendet ( hier erläutert , siehe Abschnitt 5 für den Punkt-Tokenizer).

>>> 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
quelle
Danke für die Erklärung. Verstanden. aber wie gebe ich die segmentierten sätze in eine getrennte txt-datei aus?
Alvas
66

Nachdem Sie einige Jahre lang herausgefunden haben, wie es funktioniert, finden Sie hier das aktualisierte Tutorial von

Wie erstelle ich einen NLTK-Korpus mit einem Verzeichnis von Textdateien?

Die Hauptidee besteht darin, das Paket nltk.corpus.reader zu verwenden . Wenn Sie ein Verzeichnis mit Textdateien in englischer Sprache haben , verwenden Sie am besten den PlaintextCorpusReader .

Wenn Sie ein Verzeichnis haben, das so aussieht:

newcorpus/
         file1.txt
         file2.txt
         ...

Verwenden Sie einfach diese Codezeilen und Sie erhalten einen Korpus:

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

corpusdir = 'newcorpus/' # Directory of corpus.

newcorpus = PlaintextCorpusReader(corpusdir, '.*')

Hinweis: dass das PlaintextCorpusReaderden Standard verwenden nltk.tokenize.sent_tokenize()und nltk.tokenize.word_tokenize()Ihre Texte in Sätze und Wörter zu spalten und diese Funktionen sind Build für Englisch, kann es nicht Arbeit für alle Sprachen.

Hier ist der vollständige Code zum Erstellen von Testtextdateien und zum Erstellen eines Korpus mit NLTK und zum Zugreifen auf den Korpus auf verschiedenen Ebenen:

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

Um ein Textverzeichnis zu lesen und einen NLTK-Korpus in einer anderen Sprache zu erstellen, müssen Sie zunächst sicherstellen, dass Sie über ein Python-aufrufbares Wort-Tokenisierungs- und Satz-Tokenisierungsmodul verfügen, das String- / Basestring-Eingaben verwendet und solche Ausgaben erzeugt:

>>> 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
quelle
Danke für die Klarstellung. Viele Sprachen werden jedoch standardmäßig unterstützt.
Andrew Tobey
1
Wenn jemand einen AttributeError: __exit__Fehler bekommt . Verwenden Sie open()anstelle vonwith()
Tasdik Rahman
11
 >>> 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
quelle
Schießt ein Problem für die Devnagari-Sprache.
ashim888