Repository navigation
feat: close most of the measured NER recall gaps - #18
Merged
Merged
Conversation
… require a setting to measure it tests/fixtures/ner-dev.json holds 31 invented sentences for tuning the NER pass: lower case, sentence case, all capitals, records, acronyms, news and mixed case, some with no entity so that false positives show. It shares no sentence with ner-sample.json, whose figures stay the published ones, and the measurement must take NER_SAMPLE to run on it.
…lopment set, with NER_SAMPLE
…d one entity for touching name pieces A sentence with no capital letter, or written all in capitals, must be read again in title case from a copy that keeps every offset, with sentence-case and cased text left alone, since title-casing "the board approved" made "Board" an organisation. Pieces of one name that touch, or meet at a hyphen, full stop or apostrophe, must be joined before the threshold, so the initial of "A. Okonkwo" carries the surname the model was less sure of. The aggregation takes the text to see what lies between pieces, and a stub model drives the two passes without numpy.
…nsure piece cannot hide a sure one Measured on the development set, averaging the joined pieces dropped "Jean-Luc Moreau" and "M. A. Delacroix" below the threshold, so nothing of either was masked where a confident first piece had been before. A joined name must pass when any of its pieces does, with that piece's score.
… of one name before the threshold The NER model was trained on cased news and found almost no lower-case name. A sentence written all in lower case or all in capitals is now read a second time from a title-cased copy that keeps every offset; sentence-case and mixed-case sentences are left alone, because title-casing "the board approved" made "Board" an organisation. The text's own reading comes first, so it wins where both find a span. Pieces of one name that touch or meet at a hyphen, full stop or apostrophe are joined before the threshold and scored by their most confident piece, so the initial of "A. Okonkwo" carries the surname the model was less sure of, and an unsure piece never hides a confident one. The numpy step is now _probabilities, which the tests replace. On the development set at 0.85, exact recall rose from 0.18 to 0.64 in lower case, 0.00 to 0.33 in all capitals and 0.27 to 0.45 in records, with no new false positive in its sentences without entities.
For redaction the question is whether a name is hidden, and a name masked as an organisation is still hidden. The scorer must count, one to one, the gold spans overlapped by a model span of any label, and the per-label rows must keep counting only their own label.
…hat a redaction hides
… to be read again in title case
…asure each threshold with its own job The text read as written called "WIERZBICKI" a place at 0.71 and its title-cased copy called it a person at 0.998, and the merge kept whichever came first. Of two model candidates with the same extent the more confident must win, while a rule still outranks the model. A low threshold lets weaker spans into that merge, where they can displace stronger ones, so the measurement must ask for each threshold in its own job instead of filtering one low-threshold job.
…sure each threshold with its own job The merge now orders candidates of the same extent and source by score, so the title-cased reading of "WIERZBICKI, Tomasz" as a person at 0.998 replaces the as-written reading as a place at 0.71; a rule still outranks the model. The measurement asks for each threshold in its own job again, since a lower one lets weaker spans into the merge, where they can displace stronger ones. On the development set at 0.85, exact recall rose to 0.67 in all capitals and 0.64 in records, with no new false positive.
…ences, and the measurement to wait out 429 A cased sentence must be read once and the second reading must cover only the sentences it rewrote, so its spans cannot relabel a sentence that needed no help and a long text with one lower-case line costs one more window, not a second pass over everything. The measurement must wait out a full worker, which two thresholds and a development-set run inside five minutes reach, and stop cleanly if it stays full.
…ment wait out a full worker The second reading now covers each run of rewritten sentences alone, its spans shifted back to the text's offsets, so it cannot relabel a sentence that needed no help and a long text with one lower-case line costs a window or two rather than a second pass over everything. Both sets measure exactly as before. This commit's parent, 180ac82, also added the surname-first rule, which its message omits. The measurement waits out HTTP 429 for up to 400 s, since the worker holds finished jobs 300 s by default.
…t where clients and agents read The testing notes publish the model workflow's table for this pull request, run 36862817554 at 2d14a59: exact recall at 0.85 rose from 0.13 to 0.47 in informal messages and from 0.78 to 0.92 in records, news stayed at 1.00, and 0.63 and 0.97 of entities are masked. They say how the rules were chosen on a separate development set, what still leaks, and that a case-insensitive model is the deeper fix. The protocol describes the second reading, the joined score and the merge order, and the ONNX redact description now says lower-case and all-capitals sentences are read again.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR #17 measured the redact task's NER pass. It found every entity in news-style sentences, about four in five in terse records, and about one in eight in informal lower-case messages. It also found a surname left visible after an initial. This PR closes most of those gaps, measured the same way.
How the changes were chosen. Tuning on the published sample would overfit its figures. So the rules were chosen on a separate, invented development set,
tests/fixtures/ner-dev.json, with 31 sentences. Some of them hold no entity, and some are full of acronyms, so that false positives show. The published sample,tests/fixtures/ner-sample.json, stayed unseen until the final measurement.NER_SAMPLEpoints the measurement at either set.What changed in the worker (
worker/ai_bridge/tasks.py):WIERZBICKI, Tomasz, the records convention.A. Okonkwocarries the surname the model was less sure of. My first version averaged the pieces instead. On the development set that droppedJean-Luc Moreaubelow the threshold entirely, so it was changed.WIERZBICKIwas a place at 0.71; the title-cased one, a person at 0.998. A rule still outranks the model.What changed in the measurement (
scripts/ner_measure.py):Results
On the published sample, measured by the model workflow on GitHub's runner. The "before" column is PR #17's CI run on the same runner type. Threshold 0.85, exact boundaries:
At 0.5, informal masking reaches 0.87 and records 1.00. On the development set at 0.85, recall rose from 0.18 to 0.64 in lower case, from 0.00 to 0.67 in all capitals and from 0.27 to 0.64 in records. Its sentences with no entity stayed clean.
What still leaks:
Regards, olumide;@nadia;ines and pedro.A title-cased reading can also take a filler word into a name (
lol tomasz) or call a person an organisation, but the name stays hidden. The deeper fix is a case-insensitive NER model, which would need its own pinning and measurement. The plan records that.The ONNX redact description and the protocol now describe the second reading, and quote the masked figures.
docs/testing.mdpublishes the table and says how the rules were chosen.Review
A self-review at high effort produced 9 findings. Eight are fixed, tests first:
Skipped: the surname-first rule landed in 180ac82, whose message mentions only the merge change. The history is already pushed, so I recorded this in the next commit's message instead of rewriting it.
Verification
The tests were written first and observed failing at every step: the development-set setting, the second reading, the joining, the joining rule's change from mean to best piece, the surname rule, the merge tie-break, the per-threshold jobs, the masked column, the confinement and the capacity wait.
python-tests: 109 passed, up from 91.mcp-tests: 119 passed with the new description.php-testsandphp-integrationare unaffected; this changes only the ONNX path.6900249, run 36863750957, after the docs and the tool description changed.