Тестирование классификатора NLTK на конкретном файле
следующий код наивный Байес фильм обзор классификатор. Код генерирует список наиболее информативных функций.
Примечание:
2 ответов
во-первых, внимательно прочитайте эти ответы, они содержат части ответов, которые вам нужны, а также кратко объясняют, что делает классификатор и как он работает в NLTK:
- nltk NaiveBayesClassifier обучение для анализа настроений
- используя свой собственный корпус, а не рецензии корпус для классификации в В nltk
- http://www.nltk.org/book/ch06.html
тестирование классификатора на размеченных данных
чтобы ответить на ваш вопрос. Мы предполагаем, что ваш вопрос является продолжением этого вопроса: используя свой собственный корпус вместо рецензии корпус для классификации в nltkесли ваш тестовый текст структурирован так же, как movie_review
корпус, то вы можете просто прочитать тестовые данные, как и для данных обучения:
на всякий случай, если объяснение кода неясно, вот пошаговое руководство:
traindir = '/home/alvas/my_movie_reviews'
mr = CategorizedPlaintextCorpusReader(traindir, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
две строки выше, чтобы прочитать каталог my_movie_reviews
С такой структурой:
\my_movie_reviews
\pos
123.txt
234.txt
\neg
456.txt
789.txt
README
затем следующая строка извлекает документы с его pos/neg
тег, который является частью структуры каталогов.
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()]
вот объяснение приведенной выше строки:
# 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()]
то же процесс должен применяться, когда вы читаете тестовые данные!!!
теперь к обработке функций:
следующие строки дополнительные 100 лучших функций для классификатора:
# 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]
рядом с обработкой документов в формат классификации:
# 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:]]
теперь, чтобы объяснить, что длинный список понимания для train_set
и 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]
вам нужно обработать документы, как указано выше, для извлечения функций в тестовых документах тоже!!!
вот как вы можете прочитать тестовые данные:
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()]
затем продолжите описанные выше шаги обработки и просто сделайте это, чтобы получить метку для тестового документа, поскольку @yvespeirsman ответил:
#### 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")
если приведенный выше код и объяснение не имеют для вас смысла, то вы должны читать этот учебник, прежде чем продолжить: http://www.nltk.org/howto/classify.html
теперь предположим, что у вас нет аннотации на тестовых данных, т. е. test.txt
не в структуре каталогов, как movie_review
и просто текстовый файл:
\test_movie_reviews
.txt
.txt
тогда нет смысла читать его в категоризированный корпус, вы можете просто прочитать и пометить документы, т. е.:
for infile in os.listdir(`test_movie_reviews):
for line in open(infile, 'r'):
tagged_label = classifier.classify(doc)
но вы не можете оценить результаты без аннотации, так что вы не удается проверить тег, если if-else
, и вам нужно токенизировать свой текст если вы не используете CategorizedPlaintextCorpusReader.
если вы просто хотите пометить текстовый файл 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)
еще раз, пожалуйста, не просто скопировать и вставить решение и попытаться понять, почему и как это работает.
вы можете протестировать один файл с помощью классификатора.классифицировать.)( Этот метод принимает в качестве входных данных словарь с объектами в качестве ключей и True или False в качестве их значений, в зависимости от того, происходит ли объект в документе или нет. Он выводит наиболее вероятную метку для файла, согласно классификатору. Затем вы можете сравнить эту метку с правильной меткой для файла, чтобы увидеть, правильна ли классификация.
в ваших учебных и тестовых наборах словари объектов всегда являются первым элементом в кортежах, метки являются вторым элементом в кортежах.
таким образом, вы можете классифицировать первый документ в тестовом наборе следующим образом:
(my_document, my_label) = test_set[0]
if classifier.classify(my_document) == my_label:
print "correct!"
else:
print "incorrect!"