本项目是专为医院信息科主数据管理员设计的患者主索引(Master Patient Index, MPI)匹配策略验证工具。它不介入真实生产环境,也不执行任何数据库写操作,而是以测试数据为输入,在本地完成多维相似度计算、阈值敏感性扫描、规则驱动动作决策与冲突归因分析,核心形态是一个命令行驱动(CLI)的离线模拟系统。我们用编辑距离+拼音相似度+行政区划+出生日期构建复合评分模型;用参数化阈值扫描生成「阈值-匹配数」曲线辅助决策;用可读性强的 JSON 规则 DSL 定义 merge/review/new 三类动作触发逻辑;最终输出结构化 CSV 结果与自然语言 TXT 冲突报告,供人工复核确认最优参数组合。技术栈基于 Python 3.10+,依赖 rapidfuzz 做高效字符串比对,pydantic 保障输入数据合规,click 提供稳定 CLI 接口。
定位与能力边界
这不是一个上线即用的 MPI 合并引擎,也不是替代现有主数据平台的中间件。它的存在意义非常明确:在收到跨院区患者合并申请后、正式执行前,为信息科提供一次零风险的参数沙盘推演。所有操作均在本地完成,不连接任何 HRP、EMR 或区域健康平台数据库;所有输入必须是脱敏后的模拟数据(如data/mock_patients.csv),不接受真实身份证号或手机号直接入参;所有输出仅用于人工研判,不自动触发下游流程。
我们刻意划清三条线:
- 不处理实时流数据,只接受静态 CSV 文件输入;
- 不修改任何源系统记录,所有“合并建议”仅存在于输出文件中;
- 不封装 Web 界面或 API 服务,全部能力通过终端命令显式调用。
这种克制不是功能缺失,而是责任前置,主数据治理的关键环节必须由人审慎把关,系统只负责把“不同阈值会带来多少匹配、哪些记录会冲突、按当前规则该怎么做”这件事,算得清楚、列得明白、报得及时。
核心功能详解
本项目围绕“参数可信度验证”这一主线,提供四个环环相扣的能力模块:
功能模块 | 输入方式 | 输出内容 | 关键价值 |
|---|---|---|---|
多维相似度匹配 | 单条患者记录对(name/id_card/phone/region) | similarity_score(0.0–1.0)、suggested_action(merge/review/new)、conflict_flag(True/False) | 融合拼音、编辑距离、行政区划编码、出生日期差值,避免单一维度误判(如仅靠姓名拼音可能将“张三丰”与“张三峰”高分误配) |
阈值参数化扫描 | 指定单个阈值(如 0.85) | output/scan_*.csv,含每对记录的评分与建议动作 | 快速验证某组参数在当前数据集上的表现,用于小范围快速试错 |
阈值-匹配数曲线生成 | 全量测试数据 | output/threshold_curve.csv(含 threshold、match_count、review_count、new_count)及对应图表脚本 | 直观呈现阈值微调带来的匹配数量跃变点,识别敏感区间(例如从 0.82→0.83 匹配数激增 40%,提示此处需重点审查) |
冲突报告生成 | 已有的扫描结果 CSV | output/report_*.txt,按冲突类型分组列出典型记录对、相似度、差异字段与规则依据 | 将机器判定转化为人类可读归因,例如:“record_a.id_card 末四位为 1234,record_b 为 1235,但 name 拼音完全一致且 region 同属浦东新区,建议 review” |
所有功能均服务于同一目标:让信息科同事在点击“正式执行合并”按钮前,能确切知道,这个 0.85 是怎么来的?它会让多少人被合进错误档案?哪些关键字段不一致却仍被建议 merge?有没有漏掉本该合并的双胞胎患者?
使用与配置流程
整个使用过程分为三步:准备数据 → 扫描验证 → 报告研判。无安装依赖外的额外步骤。
首先确保你有一份符合要求的模拟患者数据 CSV,字段必须包含name,id_card,phone,region(四者缺一不可)。region字段应为国家统计局标准的六位行政区划代码(如310115代表上海市浦东新区),非文字描述。示例数据已内置在data/mock_patients.csv中。
接着根据验证目标选择命令:
python -m src.cli scan --input data/mock_patients.csv --threshold 0.85该命令运行后,会在output/下生成类似scan_20240615_0.85.csv的文件,其中每行是一对可能匹配的患者记录,并附带评分与动作建议。
若需全面评估参数影响,运行:
python -m src.cli threshold-curve --input data/mock_patients.csv默认在 0.60–0.95 区间以 0.01 步长扫描,输出threshold_curve_20240615.csv,可用 Excel 或 Python pandas 快速绘图观察拐点。
最后,将任一扫描结果传给 report 命令生成可读报告:
python -m src.cli report --input-scan-result-csv output/scan_20240615_0.85.csv报告文本会按conflict_flag=True和suggested_action=review分类汇总,并标注每组记录的关键差异字段,便于信息科集中核查。
全部规则逻辑定义在rules/sample_match_rules.json中,采用简洁 JSON 格式,支持对similarity_score、id_card_match、phone_match、region_match、birth_date_diff_days等变量做布尔组合判断。修改后无需重启或重编译,下次扫描即生效。
数据字段与语义说明
输入字段虽仅四列,但每一列都承担明确语义角色,不可随意替换或省略:
字段名 | 是否必填 | 说明 | 示例值 |
|---|---|---|---|
name | 是 | 患者中文姓名,用于拼音转换与编辑距离计算 | 张三丰 |
id_card | 是 | 18 位身份证号,用于精确比对与末位校验 | 310115199003071234 |
phone | 是 | 11 位手机号,用于格式标准化后比对 | 13800138000 |
region | 是 | 六位行政区划代码,用于地理层级归并控制 | 310115 |
输出字段共五项,全部在 CSV 中明确定义:
record_a,
record_b:原始 CSV 中的行索引(从 0 开始),标识哪两条记录参与比对;similarity_score:0.0–1.0 浮点数,综合得分越高表示越可能为同一人;
suggested_action:字符串,取值为
merge(自动合并)、review(需人工确认)、new(确认为新患者);conflict_flag:布尔值,
True表示存在关键字段矛盾(如 id_card 完全不同但 name 拼音高度相似),需优先关注。
注意:similarity_score不是概率值,也不代表置信度百分比,而是归一化后的相对可比分数。其绝对数值无业务意义,真正有价值的是同一数据集下不同阈值间的排序关系与分布形态。
工程结构与可扩展性
项目采用清晰分层结构,便于理解与二次开发:
目录/文件 | 职责说明 |
|---|---|
src/cli.py | 统一入口,定义 scan / threshold-curve / report 三条命令及其参数解析 |
src/matcher.py | 核心匹配引擎,封装 rapidfuzz 调用、拼音转换、行政区划校验、日期差计算等逻辑 |
src/rule_engine.py | 规则 DSL 解析器,将 JSON 规则编译为可执行条件函数 |
rules/sample_match_rules.json | 默认规则模板,开箱即用,支持按院区、科室、年龄段定制分支逻辑 |
data/mock_patients.csv | 内置测试数据,含常见歧义场景(同音不同字、身份证升位、手机号运营商变更等) |
output/ | 所有输出文件默认落目录,含 CSV 与 TXT,命名含时间戳防覆盖 |
如需扩展新的相似度维度(如住址街道级模糊匹配),只需在src/matcher.py中新增计算函数,并在评分聚合处加入权重系数;如需对接其他主数据标准(如 HL7 FHIR Patient Resource),可在输入适配层增加 parser 模块,不侵入核心匹配逻辑。
环境与运行要求
本项目对运行环境要求极简,仅需标准 Python 运行时与基础依赖:
依赖项 | 版本要求 | 用途说明 |
|---|---|---|
Python | 3.10 或更高 | 运行时基础,利用类型提示与结构化异常处理提升健壮性 |
rapidfuzz | ≥ 3.0.0 | 提供高性能编辑距离与拼音相似度计算(内置 pypinyin) |
pydantic | ≥ 2.0.0 | 对输入 CSV 行做字段校验与类型强制转换,防止空值/非法格式中断流程 |
click | ≥ 8.0.0 | 构建可发现、可嵌套、带自动 help 的命令行接口 |
安装只需一行命令,无编译环节,Windows/macOS/Linux 全平台一致:
pip install -r requirements.txt首次运行建议先用内置数据走通全流程:
python -m src.cli threshold-curve --input data/mock_patients.csv若遇到ModuleNotFoundError,请确认是否在项目根目录执行(即src/与data/目录同级);若提示pypinyin缺失,请检查 rapidfuzz 安装是否完整(部分镜像源需手动指定--no-deps后单独装)。
项目地址:
https://github.com/nexorin9/mpi-matching-simulator