84 votes

Créer un nouveau corpus avec NLTK

Je me suis dit que souvent la réponse à mon titre est d'aller lire les documentations, mais j'ai parcouru les Livre NLTK mais ça ne donne pas la réponse. Je suis un peu novice en Python.

J'ai un tas de .txt et je veux pouvoir utiliser les fonctions de corpus que NLTK fournit pour le corpus. nltk_data .

J'ai essayé PlaintextCorpusReader mais je n'ai pas pu aller plus loin que ça :

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

Comment puis-je segmenter le newcorpus des phrases utilisant le punkt ? J'ai essayé d'utiliser les fonctions punkt mais les fonctions punkt ne pouvaient pas lire PlaintextCorpusReader classe ?

Pouvez-vous également m'indiquer comment je peux écrire les données segmentées dans des fichiers texte ?

70voto

alvas Points 4333

Après avoir passé quelques années à comprendre comment cela fonctionne, voici le tutoriel mis à jour de

Comment créer un corpus NLTK avec un répertoire de fichiers textes ?

L'idée principale est d'utiliser le nltk.corpus.reader paquet. Dans le cas où vous avez un répertoire de fichiers textes dans le dossier Anglais il est préférable d'utiliser l'option PlaintextCorpusReader .

Si vous avez un répertoire qui ressemble à ceci :

newcorpus/
         file1.txt
         file2.txt
         ...

Il suffit d'utiliser ces lignes de code et vous pouvez obtenir un corpus :

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

corpusdir = 'newcorpus/' # Directory of corpus.

newcorpus = PlaintextCorpusReader(corpusdir, '.*')

NOTE : que le PlaintextCorpusReader utilisera l'option par défaut nltk.tokenize.sent_tokenize() et nltk.tokenize.word_tokenize() pour diviser vos textes en phrases et en mots et ces fonctions sont construites pour l'anglais, il peut PAS fonctionnent pour toutes les langues.

Voici le code complet avec la création des fichiers textes de test et comment créer un corpus avec NLTK et comment accéder au corpus à différents niveaux :

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

Enfin, pour lire un répertoire de textes et créer un corpus NLTK dans d'autres langues, il faut d'abord s'assurer que vous disposez d'un outil python-callable la tokénisation des mots et la tokenisation des phrases qui prend une entrée string/basestring et produit une telle sortie :

>>> 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', '.']

0 votes

Merci pour cette précision. De nombreuses langues sont cependant prises en charge par défaut.

1 votes

Si quelqu'un reçoit un AttributeError: __exit__ erreur. Utilisez open() au lieu de with()

41voto

Reiner Gerecke Points 5332

Je pense que le PlaintextCorpusReader segmente déjà l'entrée avec un tokenizer punkt, au moins si votre langue d'entrée est l'anglais.

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

Vous pouvez passer au lecteur un tokenizer de mots et de phrases, mais pour ce dernier, la valeur par défaut est déjà nltk.data.LazyLoader('tokenizers/punkt/english.pickle') .

Pour une chaîne unique, un tokenizer serait utilisé comme suit (expliqué ici (voir la section 5 pour le 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())

0 votes

Merci pour l'explication. Je l'ai compris. Mais comment puis-je sortir les phrases segmentées dans un fichier txt séparé ?

13voto

Krolique Points 378
 >>> 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')

0 votes

Il y a un problème pour la langue devnagari.

1voto

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

0voto

Jacob Points 2458

Il y a un tas d'exemples de corpus dans un extrait de mon livre sur les création de corpus personnalisés . Aucun d'entre eux ne concerne spécifiquement PlaintextCorpusReader, mais ils devraient vous mettre sur la voie. Je pense que vous êtes déjà assez proche en vous basant sur le code ci-dessus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X