Conversation
…hbrief#87) Expand closed-set clinical abbreviations in source headers before the exact/fuzzy/embedding matching cascade, so surface variants like AGE_AT_DX or OS_MONTHS resolve to their standard field. Each name-based matcher double-matches on both the raw and abbreviation-expanded header (header_variants), keeping the best score per field with the raw form winning ties — so an exact match (e.g. gene symbols like HER2) is never lost to a mis-expansion, and the closed dictionary degrades to a no-op with a WARNING (never silently) if the bundled CSV is unavailable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
Adds query-side (source header) abbreviation expansion to improve schema mapping accuracy for clinical/oncology datasets by generating normalized header variants (raw + expanded) and double-matching across exact, fuzzy, and embedding matchers, while bundling a closed abbreviation dictionary into the package.
Changes:
- Introduces
expand_abbreviations()andheader_variants()with a lazily loaded, cached abbreviation dictionary. - Updates stage-1 (exact/fuzzy) and stage-3 (embedding) matchers to evaluate both raw and expanded header variants and keep best-per-field scores (raw-first tie behavior).
- Adds unit tests for expansion/variants + matcher invariants, and bundles the abbreviation CSV via package data.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_header_normalizer.py | New tests covering abbreviation expansion, header variants behavior, loader degradation, and double-match invariants. |
| src/metaharmonizer/utils/schema_mapper_utils.py | Adds abbreviation loader + expansion + header variant generation utilities. |
| src/metaharmonizer/models/schema_mapper/matchers/stage1_matchers.py | Double-matching for exact/fuzzy name-based matchers using header_variants(). |
| src/metaharmonizer/models/schema_mapper/matchers/stage3_matchers.py | Double-matching for embedding matchers using header_variants() and best-per-field merging. |
| src/metaharmonizer/models/schema_mapper/config.py | Resolves optional bundled abbreviation CSV path with safe fallback to None. |
| src/metaharmonizer/_bundled_data/schema/clinical_abbreviations_gpt-5-codex.csv | Adds bundled closed-set clinical abbreviation dictionary. |
| scripts/clinical_abbreviations_prompt.py | Adds the prompt used to generate the abbreviation CSV. |
| pyproject.toml | Includes the new abbreviation CSV in wheel package data. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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
AGE_AT_DX→age at diagnosis,OS_MONTHS→overall survival months) before the exact/fuzzy/embedding matching cascade, so surface-form abbreviations resolve to the correct standard field.stage1_matchers,stage3_matchers) tries both the raw normalized header and its abbreviation-expanded form (schema_mapper_utils.header_variants), keeping the best score per field with the raw form winning ties. This guarantees an exact raw match (e.g. gene symbols likeHER2) is never displaced by a bad expansion — expansion can only help, never regress an already-correct match.Design notes
s(stripping is error-prone), and a true plural that misses exact/fuzzy is still caught by the stage-3 embedding matcher, which is largely number-insensitive.token_sort_ratio, which is word-order-insensitive; extending that to exact/embedding matching would require sorting both the query and the candidate index, which is a larger change for low marginal value given real header word-order mismatches are rare.Test plan
pytest tests/— full suite passes (389 passed), including newtests/test_header_normalizer.pycoveringheader_variants/expand_abbreviationsand the double-match invariants (raw exact match never dropped, expansion can recover a miss, raw wins ties)._load_abbrev_mapdegrades to{}with aWARNING(not a crash) whenCLINICAL_ABBREV_PATHisNone.🤖 Generated with Claude Code