| Crates.io | patient-matching |
| lib.rs | patient-matching |
| version | 0.1.0 |
| created_at | 2025-11-25 14:35:11.188656+00 |
| updated_at | 2025-11-25 14:35:11.188656+00 |
| description | Patient matching algorithms for healthcare information exchange |
| homepage | |
| repository | https://github.com/GIG-Cymru-NHS-Wales/patient-matching/ |
| max_upload_size | |
| id | 1949877 |
| size | 61,815 |
A comprehensive Rust library for matching patient records in healthcare information exchanges, developed for NHS Wales.
This crate implements both deterministic and probabilistic patient matching algorithms based on research from:
Add to your Cargo.toml:
[dependencies]
patient-matching = "0.1.0"
use patient_matching::{Patient, MatchingEngine, MatchConfig};
use chrono::NaiveDate;
fn main() {
// Create two patient records
let patient1 = Patient::builder()
.given_name("John")
.family_name("Smith")
.date_of_birth(NaiveDate::from_ymd_opt(1980, 5, 15).unwrap())
.nhs_number("1234567890")
.build();
let patient2 = Patient::builder()
.given_name("Jon") // Typo
.family_name("Smith")
.date_of_birth(NaiveDate::from_ymd_opt(1980, 5, 15).unwrap())
.nhs_number("1234567890")
.build();
// Create matching engine with default config
let engine = MatchingEngine::default_config();
// Match patients
let result = engine.match_patients(&patient1, &patient2);
println!("Match score: {:.2}", result.score);
println!("Is match: {}", result.is_match);
println!("Confidence: {:?}", result.confidence);
}
use patient_matching::{MatchConfig, MatchingEngine};
// Strict matching (exact matches required)
let strict_engine = MatchingEngine::new(MatchConfig::strict());
// Lenient matching (more forgiving for typos)
let lenient_engine = MatchingEngine::new(MatchConfig::lenient());
// Custom configuration
let custom_config = MatchConfig {
match_threshold: 0.90,
nhs_number_weight: 0.40, // Increase NHS number importance
given_name_weight: 0.15,
family_name_weight: 0.20,
date_of_birth_weight: 0.15,
use_phonetic_matching: true,
..Default::default()
};
let engine = MatchingEngine::new(custom_config);
// Check for exact matches only
let is_deterministic_match = engine.deterministic_match(&patient1, &patient2);
if is_deterministic_match {
println!("Exact match on NHS number or all key demographics");
}
let result = engine.match_patients(&patient1, &patient2);
println!("Overall score: {:.2}", result.score);
println!("NHS number score: {:?}", result.breakdown.nhs_number_score);
println!("Given name score: {:?}", result.breakdown.given_name_score);
println!("Family name score: {:?}", result.breakdown.family_name_score);
println!("Date of birth score: {:?}", result.breakdown.date_of_birth_score);
println!("Address score: {:?}", result.breakdown.address_score);
println!("Phonetic name score: {:?}", result.breakdown.phonetic_name_score);
The Patient struct supports:
The matching engine uses a weighted scoring system:
| Field | Default Weight | Purpose |
|---|---|---|
| NHS Number | 30% | Strongest identifier when available |
| Family Name | 20% | Critical demographic |
| Date of Birth | 20% | Age verification |
| Given Name | 15% | Important but subject to nicknames |
| Address | 5% | Supporting evidence |
| Gender | 5% | Supporting evidence |
| Phone | 5% | Supporting evidence |
Phonetic Matching provides bonus points when names sound similar (e.g., "Stephen" vs "Steven").
No 100% Accuracy: Research shows even the best algorithms achieve 90-98% accuracy. This crate aims for transparency with confidence scores.
Standardization Critical: All inputs are normalized:
Multi-Factor Approach: Following research recommendations, matching uses multiple demographic fields rather than relying on a single identifier.
Weighted Probabilistic Matching: Combines multiple weak identifiers into a strong match signal, following best practices from health information exchanges.
Run the test suite:
# Unit tests
cargo test
# Integration tests
cargo test --test integration_tests
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_fuzzy_name_match
cargo run
This runs example scenarios including:
MIT OR Apache-2.0
Contributions welcome! Please ensure:
cargo test)cargo fmt)cargo clippy)For NHS Wales specific queries, contact the Digital Health and Care (DHCW) team.