Разница между точностью IOB и точностью

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

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

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

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

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

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


person rafa    schedule 26.06.2013    source источник


Ответы (1)


В википедии есть очень подробное объяснение разницы между точностью и точностью (см. 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
comment
Благодарю вас! Теперь намного яснее. Я думаю, что это актуальная информация, которая должна присутствовать в документах NLTK, потому что эти числа являются самым быстрым и прямым способом оценки классификатора, обученного с помощью NLTK, и если мы хотим использовать и представлять их, мы должны чувствовать себя комфортно при их использовании. . - person rafa; 04.12.2013
comment
ах, это потому, что целью NLTK на самом деле было не заниматься НЛП, а демонстрировать и обучать НЛП, поэтому иногда наставник давал задание спросить студентов, почему точность отличается от точности? или какую оценку следует использовать для оптимизации классификатора? Я бы посоветовал изучить мастер-код, чтобы проверить некоторые особенности NLTK code.google.com/p/ нлтк - person alvas; 04.12.2013