В википедии есть очень подробное объяснение разницы между точностью и точностью (см. 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
путем подсчета количества фрагментов (НЕ ЖЕТОНОВ!!!), которые были угаданы правильно
False Positives
путем подсчета количества фрагментов (НЕ ТОКЕНОВ!!!), которые были угаданы, но неверны.
True Negatives
путем подсчета количества фрагментов (НЕ ТОКЕНОВ!!!), которые не были угаданы системой.
А затем вычисляет точность и отзыв как таковой:
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()
person
alvas
schedule
02.12.2013