Extracts social determinants of health (SDOH) — housing instability, food insecurity, unemployment, transportation barriers, social isolation, financial strain — from clinical narrative and maps the spans to ICD-10-CM Z-codes (Z55–Z65). Use after running OpenMed NER when the user wants SDOH surfacing, Z-code suggestion, health-equity analytics, or to recover SDOH that is documented in free text but not coded. Pairs with OpenMed analyze_text output. Standards: ICD-10-CM Z55–Z65, Gravity Project value sets, n2c2 2022 SDOH track. Trigger keywords: SDOH, social determinants, Z-codes, housing, food insecurity, health equity, Gravity Project.
75
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Social determinants of health (SDOH) — the conditions in which people live, work, and age — drive an estimated 80% of health outcomes, yet they live almost entirely in free-text narrative. Multiple chart-review studies find SDOH documented in notes but coded with a Z-code under ~2% of the time. The information is there; the structured signal is not. This skill recovers it: run OpenMed NER over de-identified notes, then map the resulting spans to the ICD-10-CM Z55–Z65 family.
This is a decision-support step. It proposes Z-codes; a human assigns them. SDOH coding is sensitive — never expose individual SDOH inferences outside the care/coding workflow, and never feed them to coverage or pricing decisions.
De-identify first, run NER, then map spans to Z-codes:
import openmed
from sdoh_zcode_map import SDOH_ZCODES # see references/sdoh_zcode_map.md
note = (
"62F with CHF. Reports she lost her apartment last month and is "
"staying in a shelter. Often runs out of food before month-end. "
"No car; misses appointments because the bus does not run to clinic."
)
# 1) Strip PHI before any downstream processing or storage.
deid = openmed.deidentify(note, method="replace", policy="hipaa_safe_harbor")
# 2) Run clinical NER. Use an SDOH/clinical model from the registry; discover
# available keys with openmed.get_models_by_category(...).
result = openmed.analyze_text(deid.text, output_format="dict")
# 3) Map each entity span to a candidate Z-code.
for ent in result["entities"]:
code = SDOH_ZCODES.get(ent["label"].lower())
if code:
print(f"{ent['text']!r:40} {ent['label']:18} -> {code}")analyze_text returns entities shaped as
{"text", "label", "confidence", "start", "end", "metadata"}. The start/end
offsets index into the text you passed in, so you can anchor every suggested
Z-code back to its exact source span for human review.
openmed.deidentify (HIPAA Safe Harbor or a
stricter policy). SDOH text is dense with PHI (addresses, employer names).openmed.analyze_text. Pick a model whose label
set covers social concepts; if your model only emits clinical findings, run a
second pass with a zero-shot model (openmed zero) using SDOH labels such as
housing_instability, food_insecurity, unemployment,
transportation_barrier, social_isolation, financial_strain.references/sdoh_zcode_map.md). Keep the span offsets and the model
confidence on every suggestion.(span, label, suggested_code, confidence)
tuples for a coder or the Gravity Project pipeline to accept or reject. Do not
auto-bill a Z-code from an inference alone.Condition, Observation,
Goal) and USCDI v3 SDOH elements.| Domain | Range | Example |
|---|---|---|
| Education / literacy | Z55 | Z55.0 illiteracy |
| Employment | Z56 | Z56.0 unemployment |
| Occupational exposure | Z57 | — |
| Housing / economic | Z59 | Z59.0 homelessness, Z59.41 food insecurity, Z59.82 transportation insecurity |
| Social environment | Z60 | Z60.2 living alone, Z60.4 social exclusion |
| Upbringing | Z62 | — |
| Family / support circumstances | Z63 | Z63.4 disappearance/death of family member |
| Psychosocial circumstances | Z64–Z65 | Z65.1 imprisonment |
The full curated label→code table lives in references/sdoh_zcode_map.md.
openmed.analyze_text(...) output
(PredictionResult dict). Each entity["start"]/["end"] anchors a Z-code
suggestion to source text.openmed.deidentify upstream so no raw PHI reaches
the SDOH store, logs, or coder queue.Condition/Observation with the
Z-code as code.coding (system http://hl7.org/fhir/sid/icd-10-cm). OpenMed's
openmed.clinical.exporters.fhir helpers (to_bundle, to_operation_outcome)
assemble the envelope; ICD-10-CM itself is public-domain in the US release.openmed.clinical, resolving-clinical-context) before mapping.80da98c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.