Medical AI · Clinical NLP · Lesson 4 of 4
De-identifying clinical free text
Reviewed by Dr. Ram Kumar G, MBBS, MD (Internal Medicine), MPH (USA), on · Last updated
- Intermediate
- Technical focus
- About 30 minutes
- Includes exercise
Before this lesson: Privacy and de-identification: HIPAA, GDPR and India's DPDP Act, Working with clinical notes
In short
De-identifying clinical notes means finding and removing or replacing names, dates, record numbers, contact details, addresses and other identifiers in free text. Rule-based patterns catch structured identifiers such as phone numbers and dates, but miss names without titles, places and unusual details; machine-learning tools do better but are not perfect. Because a single missed identifier can expose a patient, measure recall carefully, combine methods, replace identifiers with realistic surrogates, and keep de-identified text under governance.
You will learn to
- List the kinds of identifiers found in clinical free text
- Build a rule-based identifier detector and measure its recall
- Replace identifiers with tags or consistent surrogates, including shifted dates
- Choose de-identification tools and safeguards for a project
Identifiers hide everywhere in text
Structured tables have a fixed column for a name or date of birth; notes can mention identifiers anywhere: 'seen with her son Ravi', 'works at the post office on Station Road', 'the retired school principal'. Shared evaluations such as the 2014 i2b2/UTHealth challenge showed that strong systems can find most identifiers, but rarely all of them.
A rule-based detector
import re
# Synthetic note: every name, number and place below is invented
note = ("Mrs Asha Verma (MRN 00482913), DOB 04/02/1958, seen on 12/03/2026 at Lakeside Clinic. "
"Accompanied by her son Ravi. Phone 98765 43210, email asha.verma@example.org. "
"Dr Lee reviewed her foot ulcer. Lives at 14 Hill Road, PIN 999999. Retired school principal.")
# The identifiers a careful human reviewer marked in this note
GOLD = ["Asha Verma", "00482913", "04/02/1958", "12/03/2026", "Lakeside Clinic", "Ravi",
"98765 43210", "asha.verma@example.org", "Lee", "14 Hill Road", "999999"]
PATTERNS = [
("NAME", r"\b(?:Mr|Mrs|Ms|Dr)\.?\s+((?:[A-Z][a-z]+)(?:\s+[A-Z][a-z]+)?)"),
("ID", r"\bMRN\s*(\d{6,})"),
("DATE", r"\b(\d{1,2}/\d{1,2}/\d{2,4})\b"),
("PHONE", r"\b(\d{5}\s?\d{5})\b"),
("EMAIL", r"\b([\w.+-]+@[\w-]+\.[\w.]+)\b"),
("POSTCODE", r"\bPIN\s*(\d{6})\b"),
]
def find_phi(text):
spans = []
for label, pattern in PATTERNS:
for m in re.finditer(pattern, text):
spans.append((m.start(1), m.end(1), label, m.group(1)))
return sorted(spans)
found = [s[3] for s in find_phi(note)]
missed = [g for g in GOLD if not any(g in f or f in g for f in found)]
print(f"Found {len(GOLD) - len(missed)} of {len(GOLD)} identifiers (recall {1 - len(missed) / len(GOLD):.0%})")
print("Missed:", missed)
# Found 8 of 11 identifiers (recall 73%)
# Missed: ['Lakeside Clinic', 'Ravi', '14 Hill Road']- Structured identifiers are caught. The clinic name, a first name without a title, and the street address are missed, exactly the kinds of identifier that make re-identification easy.
- 'Retired school principal' is not on the list but is a quasi-identifier: combined with age and area, it could point to one person.
Tools and safeguards
- Measure recall on a sample of your own notes, annotated by two people; aim for very high recall and inspect every miss.
- Add local patterns: national ID formats, local hospital and place names, local phone formats.
- Treat de-identified text as sensitive: keep it in controlled environments with data use agreements, because some identifiers will be missed.
- Never test de-identification by pasting real notes into public AI tools.
| Option | Notes |
|---|---|
| Rule-based tools (for example Philter, which combines rules and lists) | Transparent; tuned for high recall; may over-redact |
| Machine-learning and transformer models | Better at names and context; need validation on local notes |
| Open frameworks (for example Microsoft Presidio) | Combine patterns and models; configurable for local identifier formats |
| Ensembles of several methods | Higher recall; more over-redaction to review |
Exercise
Build, evaluate and improve a de-identifier on synthetic notes.
Data: Fifteen synthetic notes with marked identifiers, written for the notebook (Created for this course; no real patient data)
- Reproduce the detector on all fifteen notes and report recall by identifier type.
- Add patterns for addresses, untitled names after relationship words ('her son', 'his wife') and facility names ending in 'Clinic' or 'Hospital'; re-measure recall and count false positives.
- Replace tags with realistic surrogate names and check that names are replaced consistently across a patient's notes.
- Optional: run Microsoft Presidio on the same notes and compare.
- Write a short data-release checklist for sharing de-identified notes with a research partner.
Open the notebook in ColabView on GitHubWorked solution coming soon
Key takeaways
- Identifiers appear anywhere in clinical text, including names without titles and places.
- Rules catch structured identifiers; models and ensembles do better on names and context.
- Use consistent surrogates and per-patient date shifts to preserve meaning.
- No method is perfect: measure recall locally and keep de-identified text under governance.
Terms used: De-identification, PHI (protected health information), Pseudonymisation
Related: Privacy and de-identification, Guardrails: screening identifiers, Working with clinical notes
FAQ
Can clinical notes be fully de-identified automatically?
Not with certainty. Good tools find most identifiers, but some are always at risk of being missed, so de-identified notes still need governance and controlled access.
What is a surrogate in de-identification?
A realistic fake value, such as an invented name or shifted date, that replaces a real identifier. It keeps the text readable and makes missed identifiers harder to find.
Why shift dates instead of deleting them?
Time intervals matter clinically. Shifting all of a patient's dates by the same secret offset hides the real dates while keeping intervals and ages correct.
Does HIPAA Safe Harbor apply to free text?
Yes. Safe Harbor requires removing all 18 identifier types wherever they appear, including in notes, which is why free-text de-identification is demanding.
Which de-identification tool should I use?
Compare a few on an annotated sample of your own notes, choose for high recall, and add local patterns. Combining methods often works best.
Sources
- Stubbs A, Uzuner Ö. Annotating longitudinal clinical narratives for de-identification: the 2014 i2b2/UTHealth corpus. J Biomed Inform 2015;58(Suppl):S20–S29. doi:10.1016/j.jbi.2015.07.020
- Norgeot B, et al. Protected Health Information filter (Philter): accurately and securely de-identifying free-text clinical notes. npj Digital Medicine 2020;3:57. doi:10.1038/s41746-020-0258-y
- Carrell D, et al. Hiding in plain sight: use of realistic surrogates to reduce exposure of protected health information in clinical text. J Am Med Inform Assoc 2013;20(2):342–348. doi:10.1136/amiajnl-2012-001034
- Johnson AEW, Bulgarelli L, Pollard TJ. Deidentification of free-text medical records using pre-trained bidirectional transformers. ACM CHIL 2020. doi:10.1145/3368555.3384455
- Microsoft Presidio documentation
Educational content only. This material teaches methods; it is not clinical advice. Code, models and examples here are not validated medical devices and must not be used to make decisions about real patients without proper clinical validation, governance and any required regulatory approval. Examples use synthetic or openly licensed de-identified data only. Never paste identifiable patient information into public AI tools. Mentions of models, tools or vendors are for identification, not endorsement.