2013-06-26 3 views
3

Я занимаюсь некоторыми работами над NLTK с названным распознаванием объектов и chunkers. Я переквалифицировался классификатор с помощью nltk/chunk/named_entity.py для этого, и я получил следующие Весы:Разница между точностью IOB и точностью

ChunkParse score: 
    IOB Accuracy: 96.5% 
    Precision:  78.0% 
    Recall:  91.9% 
    F-Measure:  84.4% 

Но я не понимаю, что это точная разница между IOB Точностью и точностью в этом случае. На самом деле, я нашел на документы (here) Следующие для конкретного примера:

Точность тега НОБ указывает на то, что более чем на треть из слов с меткой O, т.е. не в куске NP. Однако, поскольку наш теггер сделал , не находите никаких кусков, его точность, отзыв и f-меру - все ноль.

Итак, если точность IOB - это всего лишь количество меток O, почему у нас нет кусков, а точность IOB не равна 100% в этом примере?

Спасибо заранее

ответ

4

Существует очень подробное объяснение разницы между точностью и аккуратностью на википедии (см https://en.wikipedia.org/wiki/Accuracy_and_precision), вкратце:

accuracy = (tp + tn)/(tp + tn + fp + fn) 
precision = tp/tp + fp 

Вернуться к NLTK, есть модуль звоните ChunkScore, который вычисляет accuracy, precision и recall вашей системы. И вот смешная часть, как NLTK вычисляет tp,fp,tn,fn для accuracy и precision, это происходит с разной степенью детализации.

Для точности, NLTK вычисляет общее количество жетонов (НЕ Куски !!), которые угадали правильно с POS-теги и теги IOB, затем делится на общее количество жетонов в золотом предложении.

accuracy = num_tokens_correct/total_num_tokens_from_gold 

Для точности и отзыва, NLTK вычисляет:

  • True Positives путем подсчета количества кусков (НЕ TOKENS !!!), которые правильно угадали
  • False Positives подсчитав количество кусков (NOT TOKENS !!!), которые догадываются, но они ошибаются ,
  • True Negatives, подсчитывая количество кусков (NOT TOKENS !!!), которые не угадывают система.

А затем вычисляет точность и вспомнить, как например:

precision = tp/fp + tp 
recall = tp/fn + tp 

Для доказательства вышеуказанных пунктов, попробуйте этот скрипт:

from nltk.chunk import * 
from nltk.chunk.util import * 
from nltk.chunk.regexp import * 
from nltk import Tree 
from nltk.tag import pos_tag 

# Let's say we give it a rule that says anything with a [DT NN] is an NP 
chunk_rule = ChunkRule("<DT>?<NN.*>", "DT+NN* or NN* chunk") 
chunk_parser = RegexpChunkParser([chunk_rule], chunk_node='NP') 

# Let's say our test sentence is: 
# "The cat sat on the mat the big dog chewed." 
gold = tagstr2tree("[ The/DT cat/NN ] sat/VBD on/IN [ the/DT mat/NN ] [ the/DT big/JJ dog/NN ] chewed/VBD ./.") 

# We POS tag the sentence and then chunk with our rule-based chunker. 
test = pos_tag('The cat sat on the mat the big dog chewed .'.split()) 
chunked = chunk_parser.parse(test) 

# Then we calculate the score. 
chunkscore = ChunkScore() 
chunkscore.score(gold, chunked) 
chunkscore._updateMeasures() 

# Our rule-based chunker says these are chunks. 
chunkscore.guessed() 

# Total number of tokens from test sentence. i.e. 
# The/DT , cat/NN , on/IN , sat/VBD, the/DT , mat/NN , 
# the/DT , big/JJ , dog/NN , chewed/VBD , ./. 
total = chunkscore._tags_total 
# Number of tokens that are guessed correctly, i.e. 
# The/DT , cat/NN , on/IN , the/DT , mat/NN , chewed/VBD , ./. 
correct = chunkscore._tags_correct 
print "Is correct/total == accuracy ?", chunkscore.accuracy() == (correct/total) 
print correct, '/', total, '=', chunkscore.accuracy() 
print "##############" 

print "Correct chunk(s):" # i.e. True Positive. 
correct_chunks = set(chunkscore.correct()).intersection(set(chunkscore.guessed())) 
##print correct_chunks 
print "Number of correct chunks = tp = ", len(correct_chunks) 
assert len(correct_chunks) == chunkscore._tp_num 
print 

print "Missed chunk(s):" # i.e. False Negative. 
##print chunkscore.missed() 
print "Number of missed chunks = fn = ", len(chunkscore.missed()) 
assert len(chunkscore.missed()) == chunkscore._fn_num 
print 

print "Wrongly guessed chunk(s):" # i.e. False positive. 
wrong_chunks = set(chunkscore.guessed()).difference(set(chunkscore.correct())) 
##print wrong_chunks 
print "Number of wrong chunks = fp =", len(wrong_chunks) 
print chunkscore._fp_num 
assert len(wrong_chunks) == chunkscore._fp_num 
print 

print "Recall = ", "tp/fn+tp =", len(correct_chunks), '/', len(correct_chunks)+len(chunkscore.missed()),'=', chunkscore.recall() 

print "Precision =", "tp/fp+tp =", len(correct_chunks), '/', len(correct_chunks)+len(wrong_chunks), '=', chunkscore.precision() 
+0

Спасибо! Теперь это намного яснее.Я думаю, что это релевантная информация, которая должна присутствовать в документах NLTK, потому что эти цифры являются самым быстрым и прямым способом оценки классификатора, обученного NLTK, и если мы хотим использовать и представлять их, мы должны чувствовать себя комфортно с их использованием , – rafa

+0

ах это потому, что цель NLTK была не в том, чтобы делать НЛП, а демонстрировать и преподавать НЛП, поэтому иногда преподаватель задавал задачу просить студентов «почему точность отличается от точности?» или «какой счет следует использовать для оптимизации классификатора?». Я бы предложил изучить мастер-код, чтобы проверить некоторые «особенности» NLTK https://code.google.com/p/nltk/ – alvas