Agent Skillsmaziyarpanahi/openmed › benchmarking-clinical-ner

benchmarking-clinical-ner

GitHub

用于评估OpenMed临床或生物医学NER模型性能。支持严格与宽松匹配模式,提供实体级精确率、召回率、F1及按标签划分的错误分析,帮助调试模型漏检或误判问题。

skills/benchmarking-clinical-ner/SKILL.md maziyarpanahi/openmed

Trigger Scenarios

evaluate NER entity-level F1 seqeval precision recall F1 confusion matrix error analysis strict vs partial match score against gold

Install

npx skills add maziyarpanahi/openmed --skill benchmarking-clinical-ner -g -y
More Options

Use without installing

npx skills use maziyarpanahi/openmed@benchmarking-clinical-ner

指定 Agent (Claude Code)

npx skills add maziyarpanahi/openmed --skill benchmarking-clinical-ner -a claude-code -g -y

安装 repo 全部 skill

npx skills add maziyarpanahi/openmed --all -g -y

预览 repo 内 skill

npx skills add maziyarpanahi/openmed --list

SKILL.md

Frontmatter
{
    "name": "benchmarking-clinical-ner",
    "license": "Apache-2.0",
    "metadata": {
        "pairs": "adjacent",
        "project": "OpenMed",
        "version": "1.0",
        "category": "evaluation-quality"
    },
    "description": "Score an OpenMed clinical or biomedical NER model against a user-supplied gold corpus with entity-level precision, recall, and F1, then break errors down per label. Use when the user wants a seqeval-style scorecard, strict vs partial (relaxed) span matching, a per-label confusion matrix, false-negative \/ false-positive examples, or to debug why a model misses entities. Trigger on \"evaluate NER\", \"entity-level F1\", \"seqeval\", \"precision recall F1\", \"confusion matrix\", \"error analysis\", \"strict vs partial match\", or \"score against gold\" in an OpenMed context. The gold corpus is user-supplied; OpenMed bundles no i2b2\/n2c2\/MIMIC data."
}

Benchmarking Clinical NER

This skill produces an honest entity-level scorecard for an OpenMed NER model: precision / recall / F1 plus a per-label error breakdown. It scores spans, not tokens, because clinical entities are multi-token ("type 2 diabetes mellitus") and token-level accuracy hides boundary errors. Reported numbers are entity-level in the seqeval tradition (CoNLL-2000 / SemEval-2013 families).

When to use this skill

  • You have a gold-annotated clinical corpus and an OpenMed NER model to score.
  • You want strict (exact-boundary) and partial (relaxed-overlap) span F1.
  • You need per-label numbers, not one aggregate — DRUG recall ≠ DISEASE recall.
  • You need to explain the errors: what was missed, what was spurious, what was mislabeled.

For PHI de-id specifically, gate on leakage with evaluating-with-leakage-gates instead of (or in addition to) F1.

Match modes

Mode Counts a hit when… Use for
Strict / exact predicted span boundaries and label match gold exactly release scoring, boundary-sensitive tasks
Partial / relaxed predicted span overlaps gold with the right label recall-oriented triage, tokenizer-mismatch tolerance

OpenMed exposes both: compute_exact_span_f1 (strict) and compute_relaxed_span_f1 (partial), with the full bundle in compute_metrics_bundle.

Quick start

Run a model over a user-supplied gold fixtures file and print a scorecard:

from openmed.eval import run_suite, error_report

# Fixtures: JSON list of {"id", "text", "gold_spans": [{start, end, label}, ...]}
report = run_suite(
    "eval/gold/clinical_ner.json",        # YOUR gold corpus, not bundled
    suite="golden",
    model_name="OpenMed/Disease-Detection",
    device="cpu",
)

m = report.metrics
print("exact F1 :", m["exact_span_f1"]["f1"])      # strict
print("relaxed F1:", m["relaxed_span_f1"]["f1"])    # partial
print("recall by label:", m["recall_slices"]["by_label"])

# Per-label confusion matrix + capped, no-PHI error examples.
errors = error_report(
    "OpenMed/Disease-Detection",
    "eval/gold/clinical_ner.json",
    suite_name="clinical_ner",
    example_cap=5,
)
print(errors.to_markdown())                 # confusion matrix + FN/FP tables
errors.write_json("eval/out/error_analysis.json")

Need just the metrics on spans you already have? Call the metric functions directly:

from openmed.eval import compute_exact_span_f1, compute_relaxed_span_f1

strict = compute_exact_span_f1(gold_spans, predicted_spans)
partial = compute_relaxed_span_f1(gold_spans, predicted_spans)

Workflow

  1. Align the corpus to OpenMed fixtures. Convert CoNLL/BIO or BRAT standoff into the fixture shape: text + gold_spans of {start, end, label} character offsets. (CoNLL → offsets; BRAT .ann is already character offsets.)
  2. Normalize labels to OpenMed's canonical set so DRUG/MEDICATION variants don't count as label confusion. Mislabeled-but-overlapping spans show up in the confusion matrix, not as misses.
  3. Run run_suite / run_benchmark to get a BenchmarkReport.
  4. Read both F1s. A large strict↓ / relaxed↑ gap means boundary errors, not detection failures — often tokenizer or whitespace issues.
  5. Run error_report for the per-label confusion matrix and capped examples. MISSED = false negatives (recall problem); SPURIOUS = false positives (precision problem); off-diagonal = label confusion.
  6. Triage per label. Fix the worst-recall label first; in clinical NER a few labels usually dominate the error budget.

Hand-off to / from OpenMed

  • From extracting-clinical-entities (openmed.analyze_text): the model and predictions you score here come from the NER pipeline.
  • To evaluating-with-leakage-gates: for de-id models, F1 is necessary but not sufficient — pass the same fixtures through the release gates.
  • To authoring-model-cards: drop error_report confusion matrices and per-label F1 straight into the model card's quantitative-analysis section.
  • Pairs with building-gold-corpus (supplies the fixtures) and auditing-subgroup-fairness (slices the same run by demographic group).

Edge cases & gotchas

  • Token F1 lies; report span F1. Always use the span metrics (compute_exact_span_f1 / compute_relaxed_span_f1), not token accuracy.
  • Overlapping/nested gold spans need a documented matching rule. OpenMed's matcher picks the best single overlapping prediction per gold span; nested schemes (e.g. DISEASE inside ANATOMY) should be flattened or scored per layer.
  • Class imbalance hides failures. A macro view per label surfaces a rare-but- critical entity (e.g. ALLERGY) that micro-F1 buries.
  • Error examples are no-PHI by design. ErrorSpanExample stores offsets, context windows, and sha256: text hashes — never plaintext. Keep it that way.
  • Gold quality caps your ceiling. If inter-annotator agreement is low, a "low-F1" model may be right and the gold wrong. Spot-check disagreements before blaming the model.
  • No restricted corpora in the repo. i2b2/n2c2/MIMIC are DUA-gated: load them from the user's licensed copy at eval time; never commit them.

Standards & references

Version History

  • f213557 Current 2026-07-23 00:43

Same Skill Collection

skills/building-with-openmed/SKILL.md
skills/loading-openmed-models/SKILL.md
skills/annotating-variants/SKILL.md
skills/assembling-fhir-bundles/SKILL.md
skills/auditing-deid-leakage/SKILL.md
skills/auditing-deidentification-runs/SKILL.md
skills/auditing-part11-trails/SKILL.md
skills/auditing-safe-harbor-checklist/SKILL.md
skills/auditing-subgroup-fairness/SKILL.md
skills/authoring-model-cards/SKILL.md
skills/batch-processing-clinical-text/SKILL.md
skills/bridging-presidio-and-spacy/SKILL.md
skills/building-gold-corpus/SKILL.md
skills/building-patient-timelines/SKILL.md
skills/checking-hipaa-compliance/SKILL.md
skills/choosing-openmed-models/SKILL.md
skills/coding-hcc-risk-adjustment/SKILL.md
skills/coding-icd10/SKILL.md
skills/computing-ecqms/SKILL.md
skills/configuring-privacy-policies/SKILL.md
skills/defining-cohort-phenotypes/SKILL.md
skills/deidentifying-clinical-text/SKILL.md
skills/deidentifying-multilingual-text/SKILL.md
skills/deploying-openmed-mcp/SKILL.md
skills/detecting-pv-signals/SKILL.md
skills/enforcing-nophi-logging/SKILL.md
skills/etl-to-omop-cdm/SKILL.md
skills/evaluating-with-leakage-gates/SKILL.md
skills/exporting-bulk-fhir/SKILL.md
skills/exporting-to-fhir/SKILL.md
skills/extracting-clinical-entities/SKILL.md
skills/extracting-dicom-metadata/SKILL.md
skills/extracting-lab-tables/SKILL.md
skills/extracting-pii-entities/SKILL.md
skills/extracting-sdoh/SKILL.md
skills/fetching-fhir-resources/SKILL.md
skills/gating-deid-leakage/SKILL.md
skills/generating-synthea-data/SKILL.md
skills/generating-synthetic-surrogates/SKILL.md
skills/ingesting-clinical-documents/SKILL.md
skills/linking-umls-concepts/SKILL.md
skills/mapping-loinc/SKILL.md
skills/mapping-to-snomed/SKILL.md
skills/mining-pubmed-literature/SKILL.md
skills/normalizing-rxnorm/SKILL.md
skills/parsing-ccda-documents/SKILL.md
skills/parsing-hl7v2-messages/SKILL.md
skills/parsing-lab-values/SKILL.md
skills/parsing-trial-eligibility/SKILL.md

Metadata

Files
0
Version
f213557
Hash
3b009e05
Indexed
2026-07-23 00:43

ホーム - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-29 13:12
浙ICP备14020137号-1 $お客様$