4. 关联数据获取与清洗

疾病药物关联建模的第一步,是把散落在不同来源中的“疾病—药物”关系变成一张可计算、可追溯、可复现的数据表。这一步的质量直接决定后续特征工程与模型上限:如果原始关联中混入大量重复、错配或缺失,模型学到的往往是噪声而非医学规律。本节围绕四个关键环节展开——API 调用、爬虫策略、去重与缺失值处理,以及数据质量评估,并给出可落地的参数与判断依据。

一、API 调用:结构化关联的首选入口

公开数据库通常提供结构化接口,例如 OpenTargets、DrugBank、DisGeNET、PubChem、ChEMBL 等。以 OpenTargets GraphQL 为例,可按疾病 ID 查询关联药物及其证据评分。调用时需关注三类参数:查询标识(如 EFO_0000311 代表类风湿性关节炎)、分页参数(page index、size)和证据过滤条件(如仅保留 clinical 或 genetic 证据)。

query {
  disease(efoId: "EFO_0000311") {
    associatedDrugs(page: {index: 0, size: 50}) {
      rows { drug { id name } score }
    }
  }
}

工程上建议为每个 API 建立统一封装:设置超时(如 10 秒)、重试(最多 3 次,指数退避)、限速(如每秒不超过 5 次请求),并把原始响应按“来源_疾病ID_时间戳.json”落盘。这样即使后续解析逻辑变化,也能从原始数据重放,避免重复请求。返回结果需记录来源、版本、查询时间和证据类型,为后续质量评估保留溯源字段。

二、爬虫策略:补充非结构化来源

当关联只存在于网页表格、文献摘要或药品说明书中时,需要爬虫补充。策略上应遵循“先静态后动态、先列表后详情”的顺序:先抓取疾病或药物列表页,解析出详情页 URL,再逐条抓取详情页并抽取关联字段。对 JavaScript 渲染页面,可使用 Playwright 或 Selenium 等待目标节点出现后再解析;对静态页面,requests + BeautifulSoup 已足够。

关键控制点包括:遵守 robots.txt 与访问频率限制,设置 User-Agent 与请求间隔(如 1~2 秒),对失败 URL 记录状态码并单独重试。抽取时优先使用稳定的 DOM 选择器或结构化标记(如表格列名、JSON-LD),避免依赖易变的样式类名。每条记录应保留来源 URL、抓取时间和页面快照哈希,便于回溯。

疾病—药物关联数据获取与清洗链路 结构化 API 源 OpenTargets / DrugBank DisGeNET / ChEMBL 网页 / 文献源 药品说明书 / 关联表 PubMed 摘要 API 调用封装 超时 / 重试 / 限速 原始响应落盘 爬虫策略 列表→详情 / 动态渲染 robots / 间隔 / 快照 标准化与去重 ID 映射 / 名称归一 主键去重 / 证据合并 缺失值处理 删除 / 填充 / 标记 缺失模式分析 质量评估 完整性 一致性 唯一性 时效性 可追溯性 阈值判定 标准化关联表 disease_id | drug_id | relation | evidence | source | confidence 质量不达标 → 回补 / 重抓 / 人工复核

三、去重:从“同名不同源”到唯一关联

多源合并后最常见的冗余有三类:同一疾病—药物对来自不同数据库;同一药物因名称写法不同(如“阿司匹林”与“Aspirin”“acetylsalicylic acid”)被当成两条;同一来源内因分页或重试产生重复行。处理顺序建议为:先做标识归一,再做主键去重,最后做证据合并。

标识归一的核心是建立映射表:疾病统一到 EFO 或 OMIM ID,药物统一到 DrugBank ID 或 ChEMBL ID。对无法直接映射的名称,可用大小写归一、去空格、去盐型后缀(如“盐酸”“钠”)后匹配。主键可定义为 (disease_id, drug_id),去重时保留证据最完整或评分最高的一条,并把其他来源的证据类型合并到 evidence_sources 字段。例如同一对关联在 OpenTargets 中为 genetic,在 DrugBank 中为 clinical,合并后应同时保留两类证据,而不是简单丢弃。

四、缺失值处理:先判断缺失机制

关联表常见缺失字段包括药物靶点、证据评分、文献来源、关联方向(治疗/副作用/禁忌)。处理前应先统计缺失率与缺失模式:若某字段缺失率超过 60%,通常不适合作为核心特征;若缺失与来源强相关(如某数据库不提供评分),则应按来源分层处理,而不是全局填充。

处理策略分三档:一是删除,仅适用于缺失率低且删除后不破坏类别平衡的字段;二是填充,数值型可用中位数或按来源分组中位数,类别型可用“unknown”单独成类,避免用众数掩盖真实分布;三是标记,对关键字段保留 is_missing 指示列,让模型自行学习缺失模式。需要强调的是,关联方向缺失时不应默认填“治疗”,而应标记为未知,否则会引入系统性偏差。

五、数据质量评估:用指标决定是否可用

清洗完成后,需要用一组可计算的指标判断数据是否达到建模门槛。建议至少覆盖以下维度:

维度指标示例阈值不达标处理
完整性关键字段缺失率≤ 5%回补来源或标记缺失
唯一性重复关联占比≤ 1%重新执行去重规则
一致性ID 映射成功率≥ 95%补充映射表或人工复核
时效性数据最新日期距今≤ 12 个月重新抓取或调用 API
可追溯性含来源与时间的记录占比100%补齐溯源字段

这些阈值是示例性工程约定,实际项目应根据疾病领域和数据规模调整。评估结果应形成一份质量报告,记录每项指标的计算口径、当前值和是否通过。只有通过评估的数据才进入下一阶段建模;未通过的部分应回到对应环节修复,而不是带着已知缺陷继续训练。

实践建议:把“获取—清洗—评估”写成可重复执行的脚本或流水线,每次运行输出数据版本号与质量报告。这样当模型效果波动时,可以快速定位是数据源变化、清洗规则调整还是模型本身的问题。

总体来看,关联数据获取与清洗不是一次性的预处理,而是贯穿建模全过程的工程能力。API 与爬虫决定数据广度,去重与缺失值处理决定数据纯度,质量评估决定数据是否可信。三者共同构成疾病药物关联建模的数据底座。