In primo luogo, leggere attentamente queste risposte, che contengono parti delle risposte necessarie e anche brevemente spiega cosa il classificatore fa e come funziona in NLTK:
test classificatore su dati annotati
Ora per rispondere alla tua domanda. Partiamo dal presupposto che la tua domanda è un follow-up di questa domanda: Using my own corpus instead of movie_reviews corpus for Classification in NLTK
Se il testo di prova è strutturata allo stesso modo come il movie_review
corpus, allora si può semplicemente leggere i dati di test come si farebbe per i dati di formazione:
Solo nel caso in cui la spiegazione del codice non è chiaro, ecco una guida:
traindir = '/home/alvas/my_movie_reviews'
mr = CategorizedPlaintextCorpusReader(traindir, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
le due linee di cui sopra è quello di leggere una directory my_movie_reviews
con una tale struttura:
\my_movie_reviews
\pos
123.txt
234.txt
\neg
456.txt
789.txt
README
Quindi la riga successiva estrae i documenti con il tag pos/neg
che fa parte della struttura di directory.
documents = [([w for w in mr.words(i) if w.lower() not in stop and w not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]
Ecco la spiegazione per la linea di cui sopra:
# This extracts the pos/neg tag
labels = [i for i.split('/')[0]) for i in mr.fileids()]
# Reads the words from the corpus through the CategorizedPlaintextCorpusReader object
words = [w for w in mr.words(i)]
# Removes the stopwords
words = [w for w in mr.words(i) if w.lower() not in stop]
# Removes the punctuation
words = [w for w in mr.words(i) w not in string.punctuation]
# Removes the stopwords and punctuations
words = [w for w in mr.words(i) if w.lower() not in stop and w not in string.punctuation]
# Removes the stopwords and punctuations and put them in a tuple with the pos/neg labels
documents = [([w for w in mr.words(i) if w.lower() not in stop and w not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]
Il processo stesso dovrebbe essere applicata quando si leggono i dati di prova !!!
Ora al trattamento funzione:
le seguenti righe primi 100 funzioni extra per il classificatore:
# Extract the words features and put them into FreqDist
# object which records the no. of times each unique word occurs
word_features = FreqDist(chain(*[i for i,j in documents]))
# Cuts the FreqDist to the top 100 words in terms of their counts.
word_features = word_features.keys()[:100]
Accanto alla elaborazione dei documenti in formato classificare-grado:
# Splits the training data into training size and testing size
numtrain = int(len(documents) * 90/100)
# Process the documents for training data
train_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in documents[:numtrain]]
# Process the documents for testing data
test_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in documents[numtrain:]]
Ora per spiegare quella lunga lista di comprensione per train_set
e `test_set:
# Take the first `numtrain` no. of documents
# as training documents
train_docs = documents[:numtrain]
# Takes the rest of the documents as test documents.
test_docs = documents[numtrain:]
# These extract the feature sets for the classifier
# please look at the full explanation on https://stackoverflow.com/questions/20827741/nltk-naivebayesclassifier-training-for-sentiment-analysis/
train_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in train_docs]
È necessario elaborare i documenti come sopra anche per le funzioni di estrazione nei documenti di prova anche !!!
Quindi, ecco come si può leggere i dati del test:
stop = stopwords.words('english')
# Reads the training data.
traindir = '/home/alvas/my_movie_reviews'
mr = CategorizedPlaintextCorpusReader(traindir, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
# Converts training data into tuples of [(words,label), ...]
documents = [([w for w in mr.words(i) if w.lower() not in stop and w not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]
# Now do the same for the testing data.
testdir = '/home/alvas/test_reviews'
mr_test = CategorizedPlaintextCorpusReader(testdir, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
# Converts testing data into tuples of [(words,label), ...]
test_documents = [([w for w in mr_test.words(i) if w.lower() not in stop and w not in string.punctuation], i.split('/')[0]) for i in mr_test.fileids()]
quindi continuare con le fasi di lavorazione di cui sopra, e semplicemente fare questo per ottenere l'etichetta per il documento di prova come @yvespeirsman rispose:
#### FOR TRAINING DATA ####
stop = stopwords.words('english')
# Reads the training data.
traindir = '/home/alvas/my_movie_reviews'
mr = CategorizedPlaintextCorpusReader(traindir, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
# Converts training data into tuples of [(words,label), ...]
documents = [([w for w in mr.words(i) if w.lower() not in stop and w not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]
# Extract training features.
word_features = FreqDist(chain(*[i for i,j in documents]))
word_features = word_features.keys()[:100]
# Assuming that you're using full data set
# since your test set is different.
train_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in documents]
#### TRAINS THE TAGGER ####
# Train the tagger
classifier = NaiveBayesClassifier.train(train_set)
#### FOR TESTING DATA ####
# Now do the same reading and processing for the testing data.
testdir = '/home/alvas/test_reviews'
mr_test = CategorizedPlaintextCorpusReader(testdir, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
# Converts testing data into tuples of [(words,label), ...]
test_documents = [([w for w in mr_test.words(i) if w.lower() not in stop and w not in string.punctuation], i.split('/')[0]) for i in mr_test.fileids()]
# Reads test data into features:
test_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in test_documents]
#### Evaluate the classifier ####
for doc, gold_label in test_set:
tagged_label = classifier.classify(doc)
if tagged_label == gold_label:
print("Woohoo, correct")
else:
print("Boohoo, wrong")
Se il codice di cui sopra e la spiegazione non ha senso per voi, allora si DOVETE leggere questo tutorial prima di procedere: http://www.nltk.org/howto/classify.html
012.
Ora diciamo che non avete annotazioni nei tuoi dati di test, vale a dire la vostra test.txt
non è nella struttura di directory come la movie_review
e solo un file di testo semplice:
\test_movie_reviews
\1.txt
\2.txt
Poi c'è alcun senso leggerlo in un corpus classificato, si può semplicemente fare leggere e contrassegnare i documenti, vale a dire:
for infile in os.listdir(`test_movie_reviews):
for line in open(infile, 'r'):
tagged_label = classifier.classify(doc)
MA si non può valutare i risultati senza l'annotazione, quindi non è possibile controllare il tag se il if-else
, anche è necessario tokenizzare il testo se non si utilizza CategorizedPlaintextCorpusReader.
Se si desidera solo per contrassegnare un file di testo in chiaro test.txt
:
import string
from itertools import chain
from nltk.corpus import stopwords
from nltk.probability import FreqDist
from nltk.classify import NaiveBayesClassifier
from nltk.corpus import movie_reviews
from nltk import word_tokenize
stop = stopwords.words('english')
# Extracts the documents.
documents = [([w for w in movie_reviews.words(i) if w.lower() not in stop and w.lower() not in string.punctuation], i.split('/')[0]) for i in movie_reviews.fileids()]
# Extract the features.
word_features = FreqDist(chain(*[i for i,j in documents]))
word_features = word_features.keys()[:100]
# Converts documents to features.
train_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in documents]
# Train the classifier.
classifier = NaiveBayesClassifier.train(train_set)
# Tag the test file.
with open('test.txt', 'r') as fin:
for test_sentence in fin:
# Tokenize the line.
doc = word_tokenize(test_sentence.lower())
featurized_doc = {i:(i in doc) for i in word_features}
tagged_label = classifier.classify(featurized_doc)
print(tagged_label)
Ancora una volta, per favore non basta copiare e incollare la soluzione e cercare di capire perché e come funziona.
Grazie per la spiegazione completa e cerco di capirli. Ma spesso incontro risultati sbagliati. Voglio dire che dovrebbe essere 'pos' ma il programma mostra' neg'. E non conosco la ragione. – ZaM
Ci sono molte ragioni e non è perfetto, forse (i) i dati sono insufficienti, (ii) le caratteristiche non sono abbastanza buone, (iii) la scelta del classificatore, ecc. Prendi questo corso https://www.coursera.org/ corso/ml per maggiori informazioni. E se puoi, ti incoraggio fortemente a frequentare http://lxmls.it.pt/2015/ – alvas
Sono confuso. Per prima cosa ottengo un file da 'nltk/movie_reviews/neg/cv081.txt'. Poi decido di ** testare ** il file dal tuo programma che fornisce 'Woohoo, correct'or'wrong'. Ho messo il file in '/home/neg/cv081.txt'per test e poi ho ottenuto l'output di' Boohoo, wrong'as! Poi metto il file in "/ home/pos/cv081.txt" e poi ho ottenuto "Woohoo, corretto" come output! Poi provo lo stesso file sul programma 'print (tagged_label)' mi danno molti 'neg's. E sul programma che 'print (tagged_label)'. Non so esattamente come funziona. Mi dà molti 'neg' anche per file' pos' !!. Come posso valutare questi output di 'neg's e' pos's. – ZaM