4. 不良事件报告数据库构建实战
信号检测的质量上限,往往在数据进入分析库的那一刻就已经被决定了。无论后续使用比例失衡分析(如PRR、ROR)、贝叶斯方法(如BCPNN、MGPS),还是时序关联方法,如果源数据中的药品名称、事件术语、报告版本、去重标识没有经过规范化处理,算法输出的“信号”很可能只是数据噪声。本节围绕一个可落地的ETL(Extract-Transform-Load)流程,说明如何把来自不同渠道的原始不良事件报告,转化为可用于信号检测的分析库,并讨论工具选型的关键判断依据。
一、先明确目标数据模型,再谈抽取
ETL的起点不是写脚本,而是确定目标库的结构。面向信号检测的分析库,通常需要围绕“报告—药品—事件—患者”四个核心实体建模,并保留可追溯的源标识。一个最小可用的关系模型可以包含:
- 报告主表(case):报告ID、源系统、源报告号、首次接收日期、最新版本日期、报告类型(自发/文献/研究)、严重性、国家/地区、去重键。
- 药品表(drug):报告ID、药品角色(可疑/合并/相互作用)、通用名、商品名、活性成分、ATC编码、剂型、给药途径、剂量、起止日期、适应证。
- 事件表(event):报告ID、事件术语原文、MedDRA PT、MedDRA SOC、严重性、起病日期、转归、因果关系评价。
- 患者表(patient):报告ID、年龄、年龄组、性别、体重、妊娠状态、相关病史。
其中“去重键”和“版本管理”是信号检测库区别于普通报表库的关键。同一病例可能因随访产生多个版本,若不去重,会人为放大某药品—事件组合的报告数,直接抬高PRR值。常见做法是以“源系统+源报告号”作为业务主键,保留最新版本,同时把历史版本写入审计表。
二、抽取:面对异构源头的现实处理
实际项目中,原始数据很少是整齐的CSV。常见来源包括:国家药品不良反应监测系统导出的XML/Excel、企业安全数据库(如Argus、ARISg)的定期导出、文献检索结果、以及临床试验的SAE清单。抽取阶段要解决三件事:
- 格式解析:XML按节点映射到字段;Excel需处理合并单元格与多行表头;PDF文献则通常需要人工或半自动录入,不建议直接作为自动化抽取对象。
- 增量识别:用“最新版本日期”或自增序列号作为水位线,只抽取上次ETL之后新增或更新的报告,避免全量重跑。
- 原始层留存:把抽取到的原始记录原样写入staging层(如raw_case、raw_drug),不做任何清洗。这样一旦下游转换规则出错,可以回溯重跑,而不必重新向源系统申请数据。
etl_batch_id、extract_time、source_file。它们不参与业务分析,但在排障和审计时非常关键。三、转换:信号检测库最核心的清洗与规范化
转换阶段决定了数据能否被算法正确使用。以下按处理顺序说明关键操作,并给出示例参数。
1. 去重与版本合并。以业务主键分组,按版本日期降序取第一条作为当前版本。示例:同一报告号CN-2023-0451存在两个版本,版本日期分别为2023-06-01和2023-07-15,则保留后者,前者进入历史表。
2. 药品名称规范化。原始数据中“阿司匹林”“阿斯匹林”“Aspirin”“乙酰水杨酸”可能指向同一活性成分。做法是建立药品字典映射表,将通用名、商品名、别名统一映射到标准活性成分编码(如ATC或内部drug_id)。无法匹配的记录进入待审队列,由药学人员人工确认,而不是直接丢弃。
3. 事件术语编码。将事件原文映射到MedDRA PT。例如“皮疹”“皮肤红疹”“全身皮疹”可能都映射到PT“Rash”。这一步直接影响信号检测的粒度:映射过粗会掩盖真实信号,映射过细会稀释报告数。通常信号检测在PT层级进行,同时保留SOC层级用于汇总展示。
4. 日期与数值清洗。统一日期格式为ISO 8601;对缺失起病日期但存在接收日期的记录,可标记为“日期不完整”,在时序分析中单独处理。年龄统一换算为岁,婴儿按月龄换算并标注。
5. 派生字段计算。为信号检测准备常用派生列,例如:drug_event_pair(药品ID+事件PT)、report_year、is_serious、age_group。这些字段能显著减少后续查询的复杂度。
四、加载:让分析库可查、可复现
加载阶段建议采用“全量重建+增量追加”的混合策略。对于药品字典、MedDRA映射表等变化不频繁的维表,可以全量重建;对于报告事实表,按etl_batch_id增量追加,并保留批次日志。加载完成后,至少运行三类校验:
- 完整性校验:报告数、药品记录数、事件记录数是否与staging层一致,差异率超过阈值(如0.5%)则告警。
- 唯一性校验:业务主键是否唯一,是否存在重复报告。
- 分布校验:Top 20药品和Top 20事件的报告数是否出现异常跳变,用于发现映射错误或源数据突变。
五、工具选型:没有最优,只有匹配
工具选型应围绕四个维度判断:数据量级、更新频率、团队技能、审计要求。若数据量在百万条以内、更新频率为月度、团队以统计和药学背景为主,Python + pandas + PostgreSQL 的组合足以支撑,开发周期短、调试直观。若数据来源超过五个、需要每日增量、且要求完整的任务依赖与失败重试,则Airflow或Kettle这类调度平台更合适。若企业已有数据仓库,dbt可以把转换逻辑SQL化、版本化,便于评审和复用。
需要强调的是,工具本身不解决数据质量问题。无论选择哪种方案,以下三条工程约束都应写入设计:转换规则必须版本化(每次变更记录规则ID和生效日期);ETL必须可重跑(同一批次重复执行结果一致);关键映射必须可追溯(每条标准化记录能回溯到原始值)。做到这三点,分析库才具备支撑信号检测的可信度。
六、一个可参考的最小ETL批次记录表
| 字段 | 示例值 | 用途 |
|---|---|---|
| etl_batch_id | 20240615_001 | 标识本次ETL批次 |
| source_system | NMPA_ADR | 记录数据来源系统 |
| extract_start / end | 2024-06-01 / 2024-06-14 | 增量抽取水位线 |
| raw_count / loaded_count | 12,480 / 12,463 | 校验抽取与加载差异 |
| unmatched_drug_count | 37 | 进入待审队列的药品记录数 |
| rule_version | transform_v2.3 | 转换规则版本,支持回溯 |
| status | SUCCESS / WARN / FAIL | 批次执行结果 |
这张表看似简单,却是ETL可运维的基础。当某天信号检测结果出现异常时,可以快速定位是源数据变化、映射规则变更,还是加载环节遗漏,而不是在多个脚本和临时文件中反复排查。数据工程的价值,最终体现在这种可定位、可复现的能力上。