python nlp nltk precision named-entity-recognition

nlp python



PrecisiĆ³n de IOB en NLTK nombrado reconocimiento de entidad (1)

Hay una explicación muy detallada de la diferencia entre precisión y precisión en wikipedia (ver https://en.wikipedia.org/wiki/Accuracy_and_precision ), en resumen:

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

De regreso a NLTK, hay una llamada al módulo ChunkScore que calcula la accuracy , precision y recall de su sistema. Y esta es la parte divertida de la forma en que NLTK calcula el tp,fp,tn,fn para accuracy y precision , lo hace en granularidad diferente.

Para mayor precisión , NLTK calcula el número total de tokens (¡ NO CHUNKS! ) Que se adivinan correctamente con las etiquetas POS y las etiquetas IOB, y luego se divide entre el número total de tokens en la oración dorada.

accuracy = num_tokens_correct / total_num_tokens_from_gold

Para precisión y recuperación , NLTK calcula:

  • True Positives al contar la cantidad de trozos (¡ NO TOKENS! ) Que se adivinan correctamente
  • False Positives contando la cantidad de trozos (¡ NO TOKENS! ) Que se adivinan pero están equivocados.
  • True Negatives contando la cantidad de fragmentos (¡ NO TOKENS! ) Que el sistema no adivina.

Y luego calcula la precisión y el recuerdo como tal:

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

Para probar los puntos anteriores, prueba este script:

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()

Estoy haciendo algunos trabajos en NLTK con reconocimiento de entidad nombrada y chunkers. nltk/chunk/named_entity.py un clasificador usando nltk/chunk/named_entity.py para eso y obtuve las siguientes medidas:

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

Pero no entiendo cuál es la diferencia exacta entre Precisión IOB y Precisión en este caso. En realidad, encontré en los documentos ( aquí ) lo siguiente para un ejemplo específico:

La precisión de la etiqueta IOB indica que más de un tercio de las palabras están etiquetadas con O, es decir, no en un fragmento NP. Sin embargo, dado que nuestro etiquetador no encontró ningún trozo, su precisión, recuperación y medida f son todos cero.

Entonces, si la precisión IOB es solo el número de etiquetas O, ¿cómo es que no tenemos fragmentos y la precisión IOB no es 100% al mismo tiempo, en ese ejemplo?

Gracias de antemano