TWOSIDES — 药物相互作用副作用权威数据集 AI-Ready Wikipedia | 千方病案医数集

645 药物 × 63,473 药物对,465 万药物对-副作用关联

来源 Tatonetti Lab(斯坦福大学,后哥伦比亚大学,现 Cedars-Sinai) url: http://tatonettilab.org/resources/tatonetti-stm.html发布时间: 2026-09-09最后更新: 2026-09-09 阅读 2

信息速览

数据集名称TWOSIDES — 药物相互作用副作用权威数据集 AI-Ready Wikipedia | 千方病案医数集
数据类型4,651,131 药物对-副作用关联,63,473 个药物组合,645 种药物,1,301 种 MedDRA 副作用,CSV 开放下载
规模不适用(FAERS 自发报告聚合数据;覆盖 645 种药物)
接入方式Tatonetti Lab(斯坦福大学,后哥伦比亚大学,现 Cedars-Sinai) url: http://tatonettilab.org/resources/tatonetti-stm.html
AI 就绪度

数据集封面

TWOSIDES — 药物相互作用副作用权威数据集 AI-Ready Wikipedia

INFOBOX

字段 内容
数据集名称 TWOSIDES 药物相互作用副作用数据集
英文全称 TWoside Observation of Standard drug pair Side EffeCTS(TWOSIDES)
别名/简称 TWOSIDES、TwoSIDES、NSIDES-TWOSIDES
疾病分类 不适用单一 ICD-11 编码:标签为 1,301 种 MedDRA 首选术语(PT)形式的不良反应,跨 ICD-11 多个章节(详见 §2.1)
SNOMED CT 数据库附 MedDRA 码与 SNOMED CT 映射列(condition_snomed_id),映射不完美、存在 NULL(详见 §4.5)
数据模态 药物对-副作用关联(药物警戒信号检测统计表,含四格表计数与 PRR)
AI 任务类型 多标签链路预测(药物对 → 副作用集合);多标签分类;图神经网络节点/边表示学习
样本总数 4,651,131 条药物对-副作用关联(868,221 显著关联 + 3,782,910 增强关联);645 种药物;63,473 个药物对
数据大小 2012 原版数据库约数十 MB;NSIDES v0.1 平铺文件 TWOSIDES.csv.xz 约数十 MB(xz 压缩)
数据格式 CSV(xz/gz 压缩);MySQL 数据库导出(effect_nsides);Decagon 版四列 TSV
许可证 免费开放学术使用(Tatonetti Lab 官方声明"free and open for academic use",须引用原始论文)
访问级别 开放(无需注册,直接下载)
DUO 标签 NRES(无限制研究使用,官方仅要求学术引用)
语言 英文(药物名为 RxNorm 标准名,副作用为 MedDRA 英文术语)
首发日期 2012-03-14(随 Sci Transl Med 论文发布)
最后更新 2019-11(NSIDES v0.1,FAERS 报告更新至 2014 年)
发布机构 Tatonetti Lab(研究完成于斯坦福大学;后迁哥伦比亚大学,现 Cedars-Sinai 医学中心)
官方主页 tatonettilab.org/resources/tatonetti-stm.html
下载地址 2012 原版 / NSIDES v0.1
DOI 10.1126/scitranslmed.3003377(原始论文)
引用次数 911+(Semantic Scholar,截至 2026-09)
AI 就绪度评分 ⭐⭐⭐⭐(4/5)— 纯 CSV 开放获取、结构清晰、社区有成熟基准协议(Decagon 划分),但无官方训练/测试划分脚本、无负例、需自行负采样与构建多标签矩阵(扣分项)
页面状态 published

§0 医学与技术审核声明

医疗免责声明:本页面提供的医学信息仅供研究和教育目的,不构成医疗建议、诊断或治疗方案。数据集的医学描述基于公开发表的文献,未经逐一临床验证。任何基于该数据集训练的 AI 模型在应用于临床决策前,必须经过独立的临床验证和监管审批。

技术免责声明:本页面的代码示例、预处理建议和基准性能数据基于公开资料整理,不保证在特定环境下的准确性和适用性。使用者应自行验证代码安全性和数据预处理流程的正确性。千方病案医数集不对因使用本页面信息而导致的任何直接或间接损失承担责任。

数据使用合规:使用本页面描述的数据集前,请务必阅读并遵守数据集原始许可协议。TWOSIDES 由 Tatonetti Lab 以"free and open for academic use"形式发布,官方要求使用时引用 Tatonetti et al. 2012(Sci Transl Med)原始论文。TWOSIDES 为聚合统计数据库,不含患者级数据;将其用于临床决策支持前须完成前瞻性临床验证。DUO 标签仅供参考,具体使用限制以数据集官方协议为准。

  • 医学审核:千方病案医学编辑部交叉审核:§2 医学背景(药物相互作用药理学、QT 延长案例)、§7 质量评估(药物警戒偏倚分析)。审核日期:2026-09-05。
  • 数据工程审核:[千方病案医学编辑部交叉审核] 医疗 AI 数据工程师,审核范围:§4 DAIMS 数据字典、§5 数据划分策略、§6 预处理 Pipeline 和坑点。审核日期:2026-09-05。

§1 数据集概览

§1.0 📌 30 秒速览

这是什么? TWOSIDES 回答一个此前无人系统性回答的问题:两种药一起吃,会引发哪种单药都不会引发的副作用? 它由斯坦福大学 Tatonetti Lab 从 FDA 不良事件报告系统(AERS/FAERS)的数百万份自发报告中挖掘而来,覆盖 645 种药物、63,473 个药物组合与 1,301 种不良反应,共 4,651,131 条药物对-副作用关联。它是历史上第一个此类规模的"药物组合副作用"数据库。

为什么重要? 临床试验只验证单药或极少数组合,数百万种日常并用药组合处于"黑暗空间"。TWOSIDES 用倾向性评分匹配控制了 44 个混杂协变量,并用 SCRUB 算法剔除"降糖药↔高血糖"式的虚假关联;论文中 47 个预测出的药物类相互作用在独立电子病历队列中获得验证(P < 0.0001),包括后来被临床证实的"SSRI 抗抑郁药 + 噻嗪类利尿剂 → QT 间期延长"风险。

我能用它做什么? 训练多标签链路预测模型(给定两个药物,预测它们会共同引发哪些副作用)——这正是图神经网络里程碑 Decagon 及其后继 SOTA(SumGNN、SkipGNN、DCSE)的官方训练数据;也可用于药物安全信号发现、候选药安全性预警、药物警戒方法学研究。本 Wiki 提供 DAIMS 数据字典、负采样/划分策略与 8 个真实坑点。

§1.1 技术摘要

TWOSIDES 的构建流程是"自发报告数据 → 因果推断式信号检测"的教科书式范例(Tatonetti et al., Sci Transl Med, 2012)。团队首先用 SCRUB 算法消除 AERS 中的合成关联(synthetic associations)——适应症混淆(降糖药因处方于糖尿病人而被报告为"高血糖")、合并用药混淆、性别与年龄报告偏倚;随后对每个(药物、事件)对执行倾向性评分匹配:以 10 次 bootstrap 迭代的逻辑回归预测药物暴露,按倾向得分分为 6 个箱([0, 0.2, 0.4, 0.6, 0.8, 1]),在每个箱内按 1:10 采样对照,构成四格表计数 A/B/C/D;再计算比例报告比 PRR = (A/(A+B))/(C/(C+D)) 及其误差。对药物对,分别计算"药物对联合"与"两单药各自"的 PRR:868,221 条关联的信号无法归因于任一单药(真正的组合特异性信号),另 3,782,910 条关联的药物对 PRR 高于两单药(增强型信号),合计 4,651,131 条,覆盖 63,473 个药物对与 1,301 种 MedDRA 副作用。姐妹库 OFFSIDES(438,801 条 off-label 单药副作用)是其单药对照版本。2019 年 NSIDES v0.1 将 FAERS 报告更新至 2014 年并统一为 13 列平铺 CSV + MySQL 导出。

§1.2 战略价值

维度一:从"是否存在相互作用"到"是什么相互作用"的范式跃迁。 在 TWOSIDES 之前,DrugBank 等 DDI 数据库只提供二元的"相互作用存在与否 + 文本描述",而 TWOSIDES 把标签空间细化为 1,301 种具体 MedDRA 副作用,使"预测相互作用的临床表型"成为可监督学习的任务。这一标签粒度直接催生了 Decagon(Zitnik et al., Bioinformatics, 2018)的多关系图卷积范式——将 964 种副作用作为图中 964 种边类型建模,将 AUROC 从 DeepWalk 的 0.748 推到 0.872。

维度二:真实世界证据(RWE)方法论的可复用资产。 TWOSIDES 公开了完整的信号检测统计量(四格表 A/B/C/D、PRR、PRR_error),意味着使用者不仅能拿到"关联成立与否",还能重构置信度、做证据加权学习、或把 PRR 显著性当作软标签。NSIDES 家族(OnSIDES/KidSIDES/AwareDX/ManySIDES)延续了同一套方法学,使其成为药物警戒 NLP 与信号检测研究的参考实现。对药企与监管科技团队,它是低成本预筛选高风险药物组合的第一道过滤器;对学术界,它是检验图学习、知识图谱、因果推断新方法的公共竞技场。

维度三:纯正例学习(PU learning)的公共教学场。 大多数医疗数据集教程围绕"标注是否准确"展开,而 TWOSIDES 把更根本的问题摆上台面:未观测 ≠ 真负例。63,473 个有信号的药物对之外还有 144,217 个零关联组合,它们既非正例也非可信负例。这使得 TWOSIDES 成为负采样策略、PU learning、标签噪声学习等方法论文的天然试验台——任何在这份数据上发布的 AUROC 都隐含着一个负采样假设,能否把它说清楚即是方法学素养的试金石(详见 §5.3 与坑点 1)。

§1.3 同类数据集横向对比

数据集 药物数 关联规模 标签粒度 标注来源 与 TWOSIDES 的差异化
TWOSIDES(2012 原版) 645 4,651,131 药物对-副作用关联 1,301 MedDRA PT 多标签 FAERS/AERS 信号检测(PRR) 唯一覆盖"组合特异性"副作用的大规模库
OFFSIDES(姊妹库) 1,332 438,801 单药 off-label 副作用 10,097 不良事件 FAERS/AERS 信号检测 TWOSIDES 的单药对照,二者联合可做归因分解
DrugBank DDI v5.1.4 1,706 191,808 DDI 对 86 种机制/事件类型 人工文献策展 有机制注释但规模小 24 倍、副作用粒度粗
SIDER 4.1 1,430 139,756 药-事件对 5,868 副作用(MedDRA) 说明书文本挖掘 单药标签,常用作 TWOSIDES 的银标准/特征源
BIOSNAP 1,332 41,520 标注 DDI 二元 说明书与文献 小规模二元基准,来自 Stanford SNAP
Decagon 版 TWOSIDES 645 4,576,785 正例三元组 964 种副作用(≥500 对出现) 过滤后子集 社区事实标准划分所用的版本

规模数字来源:Tatonetti Lab 官方资源页DDI 预测综述(Brief Bioinform, 2023)Decagon 论文数据页

§1.4 版本时间轴

时间 版本/事件 说明
2012-03-14 TWOSIDES 1.0 随论文发布 AERS 挖掘;868,221 显著 + 3,782,910 增强关联;645 药物、63,473 药物对、1,301 副作用(官方资源页
2018-06 Decagon 采用并派生 964 类子集 副作用出现于 ≥500 药物对者入选;4,576,785 正例;成为社区基准划分(Zitnik et al. 2018
2019-11-15 NSIDES v0.1 FAERS 更新至 2014;TWOSIDES.csv.xz 13 列格式 + MySQL dump;显著三元组 5,729,992(未按 OFFSIDES 过滤)(nsides-release
2020 至今 NSIDES 家族扩展 OnSIDES(2022 说明书标签)、KidSIDES、AwareDX、ManySIDES;TWOSIDES 官方计划季度更新(KG Hub 收录页

§1.5 典型应用场景

  1. 多标签 DDI 副作用预测基准:输入两个药物的分子结构/靶点/图嵌入,输出 964 或 1,301 维副作用概率向量——Decagon、DeepDDI、SumGNN、SkipGNN、DCSE 等全部以此数据训练评测。
  2. 药物安全信号预警:对新药组合候选(如复方制剂、联合疗法)生成高置信度副作用假设清单,供药物警戒团队优先核查——Decagon 的 top-10 新预测中 5 个获后续文献支持。
  3. 药物-靶点网络的机制假设生成:将 TWOSIDES 边叠加到 PPI 网络上,检验"两药靶点在网络邻近 → 组合副作用"假说(Decagon 的核心发现之一)。
  4. 药物警戒方法学试验台:四格表计数完整公开,可用于研究负采样、标签噪声学习、PU learning(正例-未标注学习)与偏倚校正算法。
  5. 药物重定位与适应症发现:论文展示了用 TWOSIDES 反向预测药物适应症与药物靶点的用法(副作用与适应症共享同一信号检测框架)。

场景与技术路径对照:

场景 核心技术路径 产出形态 成熟度参照
多标签 DDI 预测 指纹/图编码器 + 多标签头 1,301 维概率向量 Decagon 起完整基准谱系
安全信号预警 模型 top-k + PRR 置信下限过滤 高置信假设清单 Decagon 5/10 文献证实
机制假设生成 TWOSIDES 边叠加 PPI 网络 靶点/通路解释 Decagon 副作用嵌入按生理系统聚类
方法学研究 PU learning / 负采样消融 协议与评估论文 DCSE/DDINet 2025-2026
重定位与适应症 信号反向传播至药物-适应症 适应症假设 原论文展示用法

§2 医学背景

§2.1 标签术语体系与 ICD-11 / SNOMED CT 映射

TWOSIDES 的标签体系是 MedDRA(监管活动医学词典)首选术语(PT),而非 ICD-11 或 SNOMED CT。NSIDES 数据库的 CONDITION_CONCEPT 表同时提供 condition_meddra_idcondition_snomed_id 两列,但官方明确说明 MedDRA → SNOMED CT 映射不完美、存在 NULL 值(nsides-release v0.1 说明)。由于 1,301 种副作用 PT 跨越全身器官系统,数据集不对应任何单一 ICD-11 编码。下表给出高频标签的示例映射(示例性质,非完整映射;使用前请以 MedDRA 官方词典与 WHO ICD-11 浏览器复核):

副作用标签(MedDRA PT 示例) ICD-11 相关编码 SNOMED CT 术语说明
Epileptic seizures(癫痫发作) 8A61(癫痫) 20695008(癫痫发作) 神经系统组合副作用典型标签
Acute kidney injury(急性肾损伤) GB60(急性肾损伤) 59613009(急性肾衰) 肾脏系统高危标签,常由肾毒性药物对引发
Hyperglycaemia(高血糖) 5A11(2 型糖尿病)相关章节 80394007(高血糖) 亦是原文论文"合成关联"的经典例子:降糖药被混淆性报告为高血糖
Nausea(恶心) 消化系统症状章节 422587007(恶心) 高频轻度标签,报告偏倚研究常用
Diarrhoea(腹泻) 消化系统症状章节 62315008(腹泻) 高频胃肠道标签
Prolonged QT interval / 心律失常类 心律失常章节(BC65-BC67 区段) 698252002(心律失常) 论文核心验证案例:SSRI + 噻嗪类 → QT 延长

映射缺口警示:直接以 condition_snomed_id 做跨库 join 会因 NULL 与一对多映射产生静默错配;涉及 ICD-11 的分析建议经由 SNOMED CT 中转或使用 OMOP CDM 概念表(NSIDES 数据库自带 condition_concept_id,见 §4.1)。

§2.2 医学简介:多药物联用与不良药物事件

不良药物事件(Adverse Drug Event, ADE)是全球致病与致死的重要诱因之一;许多 ADE 在药物获批前的临床试验中无法被检出,因为试验样本量、时长与入组人群天然排除了罕见的、慢发的与组合特异的事件(Tatonetti et al., 2012)。多药物联用(polypharmacy)是肿瘤、HIV 与心血管疾病管理的常态:两种药物各自单用时安全,但联合使用时可能通过抑制同一代谢酶(如 CYP3A4)、作用于相邻蛋白靶点或叠加生理通路,引发任何单药都不会引发的副作用。此类"组合特异性"事件在传统药物说明书(如 SIDER 收录的说明书信息)中几乎完全缺位——SIDER 收录的是单药标签副作用,药品组合空间根本无法通过临床试验逐一覆盖。

流行病学视角下,ADE 负担的"可见部分"与"实际部分"存在巨大落差:平均一个药品说明书收录 69 个 on-label 不良事件,而 OFFSIDES 从同一批报告数据中平均为每个药物挖掘出 329 个高置信的 off-label(说明书未收录)不良事件——可见部分仅为实际信号的两成(Tatonetti Lab 官方资源页)。临床决策支持系统的覆盖缺口同样惊人:一项比利时通用肿瘤病房的研究显示,60% 的患者正在服用至少一组未被 Lexi-Interact(主流相互作用知识库)收录的药物组合(Debruyne et al. 2012,转引自 Stanford CS229 报告)。FDA 的自发报告系统(AERS,2004-2012;其后继 FAERS)收集上市后全人群的不良事件报告,是唯一在规模上足以支撑组合副作用统计挖掘的数据源,但其样本存在上报偏倚与混杂因子缺失(协变量未知)的先天缺陷——TWOSIDES 的方法学贡献正是针对后者的矫正。

§2.3 临床任务定义

本数据集支撑的计算任务对应药物警戒中的 信号检测(signal detection)组合风险评估 两类临床任务:

任务 输入 输出 对应临床场景
组合副作用预测(多标签) 药物对(分子结构、靶点、嵌入) 964/1,301 维副作用概率 处方审核系统在医生开具组合处方时预警
信号验证与优先级排序 药物对-事件三元组 + PRR 统计 证据强度/置信度 药物警戒团队决定哪些信号值得专案调查
相互作用机制归因 药物对 + 蛋白网络 靶点/通路解释 临床药理学家设计缓解方案(换药、监测)
单药-组合归因分解 TWOSIDES + OFFSIDES 组合特异性 vs 单药叠加 区分"叠加毒性"与"真相互作用"

需要强调:TWOSIDES 的关联是统计学信号而非确诊的因果关系,其临床角色是"假设生成 + 优先级排序",处于筛查与预警层级,远早于诊断与治疗决策层级。

§2.4 报告人群(数据来源人群)

TWOSIDES 源于自发报告的聚合统计,不包含患者级数据,因此不适用"患者人群表"的年龄/性别/种族描述。下表描述其报告来源结构:

维度 描述
数据来源 FDA Adverse Event Reporting System(AERS;NSIDES v0.1 更新使用其继任者 FAERS 至 2014 年)
报告主体 医疗专业人员、制药企业(法定上报义务)、消费者
人群构成 服用相关药物并发生不良事件的报告者,经倾向性评分匹配构造"暴露组/对照组"(1:10,分 6 个倾向得分箱)
人口学字段 REPORT 表的 person_age、person_sex 全部置 NULL(脱敏处理),无法做亚组分析
地理范围 美国 FDA 汇总库,含美国本土及经 FDA 转报的国际报告
时间范围 2012 原版:AERS 至 2012 年初;NSIDES v0.1:FAERS 至 2014 年底

§2.5 临床价值

TWOSIDES 的临床价值链是"假设生成 → 回溯验证 → 前瞻监测"。论文作者用独立电子病历(EMR)队列验证了 47 个药物类相互作用(P < 0.0001):最著名的是选择性血清素再摄取抑制剂(SSRI)与噻嗪类利尿剂合用增加 QT 间期延长风险——932 名合用患者中 87 人(9.3%)出现 QT 延长,显著高于噻嗪单用的 588/9,008(6.5%)与 SSRI 单用的 684/14,218(4.8%);Cox 比例风险模型显示合用者相对噻嗪单用风险比 HR 1.5(95% CI 1.2–1.9,P = 4.46×10⁻⁴)(Tatonetti et al., 2012)。QT 延长与室性心律失常、心源性猝死相关,这一发现后来进入了临床药物安全讨论。对于 AI 模型,Decagon 沿用同样的验证思路:其预测的 Atorvastatin + Amlodipine 肌肉炎症组合在模型训练数据之后发表的文献中找到支持证据,top-10 新预测中 5 个获文献证实。这些案例表明:大规模统计信号 + 图先验可以产出真正可被临床追踪的假设。按使用深度,其临床价值可分为四级:

价值层级 用法 证据要求
L1 假设生成 浏览高 PRR 信号,形成研究问题 无(数据集原生能力)
L2 优先级排序 模型/PRR 联合打分,排序药物警戒专案 内部回溯验证
L3 假设复核 top-k 预测的文献回溯或 EMR 队列复核 Decagon 5/10、论文 47 类先例
L4 前瞻监测 前瞻性登记研究/处方系统预警试点 监管级验证(本数据集自身不提供)

§2.6 金标准与验证参照

TWOSIDES 没有人工逐条标注的金标准——它的"标签"本身就是统计挖掘产物。其质量验证依赖以下参照系:

参照标准 划分 标注方式 标注者 性质
SIDER 4.1(说明书副作用) 单药层面 说明书文本挖掘 无人工标注(文本抽取) 银标准:OFFSIDES 恢复其中 38.8%(18,842 药-事件对)
AERS 时序切分 下载日后新增报告 自发报告 无(自发) 银标准:模拟"前瞻"信号验证
加拿大 MedEffect 独立报告体系 自发报告 无(自发) 银标准:跨国泛化检验
Stanford EMR 队列 药物类层面 临床判断(QT 客观测量) 临床研究团队 外部验证金标准:47 类相互作用 P < 0.0001
Decagon 文献回溯 top-k 新预测 文献检索证实 作者 + 领域文献 案例级验证:5/10 获文献支持

§3 数据集规格

§3.0 版本抉择矩阵

TWOSIDES 有两个主要发行形态与一个派生基准版本,选错版本是社区最常见的起点错误:

你的需求 推荐版本 大小/格式 理由
复现 Decagon/SumGNN 等 SOTA 基准 Decagon 版(964 类,snap.stanford.edu/decagon) 四列 TSV,约数百 MB 与全部公开排行榜的划分协议对齐,可直接对比
最新统计量/最长 FAERS 覆盖 NSIDES v0.1(2019-11) TWOSIDES.csv.xz + MySQL dump FAERS 至 2014;13 列含完整四格表与 PRR;但显著三元组口径与 2012 原版不同(未按 OFFSIDES 过滤)
单药副作用对照/归因分解 OFFSIDES(与 TWOSIDES 同源) OFFSIDES.csv.xz 438,801 off-label 关联;把 TWOSIDES 关联分解为"单药可解释"与"组合特异"
历史引用/方法学溯源 2012 原版(tatonetti-stm 页) 数据库导出 与论文数字(868,221/3,782,910)严格对应

§3.1 数据模态详情

TWOSIDES 是单模态关系型表格数据集,但每个记录背后编码了三层信息:

  1. 关联层:药物对 → MedDRA 副作用的统计显著关联(研究的核心对象)。
  2. 证据层:每条关联携带完整四格表计数 A/B/C/D、PRR、PRR_error、mean_reporting_frequency,支持置信度加权与证据校准学习。
  3. 实体层:药物以 RxNorm CUI + 概念名标识(NSIDES 数据库内还有 DrugBank/ChEBI 映射列),副作用以 MedDRA 码 + 概念名标识。分子结构、靶点等外延模态需自行从 DrugBank/PubChem/STITCH 合并(Decagon 即如此构建多模态图:PPI 网络 19,085 蛋白、715,612 条相互作用,Zitnik et al. 2018)。

§3.2 按子集的样本数

子集 数量 说明
显著组合关联(不能归因任一单药) 868,221 覆盖 59,220 个药物对 × 1,301 副作用
增强关联(药物对 PRR 高于两单药) 3,782,910 含于同一发行文件
药物对总数 63,473 有至少一条关联的药物组合
药物数 645 2012 原版口径
副作用(MedDRA PT) 1,301(原版)/ 1,318(Decagon 语境)/ 964(Decagon 过滤版) 不同论文口径略有差异,均已注明来源
Decagon 正例三元组 4,576,785 964 类副作用,出现于 ≥500 药物对
可能关联全空间 83,657,414 63,473 对 × 1,318 副作用;正例占 5.56%
NSIDES v0.1 显著三元组 5,729,992 FAERS 至 2014;未按 OFFSIDES 过滤
NSIDES v0.1 全部三元组 222,155,888 A > 0 的全部药物对-事件组合

来源:Tatonetti Lab 官方资源页nsides-release v0.1DCSE 2025 预印本

§3.3 数据格式

形态 格式 说明
NSIDES v0.1 平铺文件 TWOSIDES.csv.xz(13 列) 推荐:pandas 读 xz 直接可用
NSIDES v0.1 数据库 MySQL dump(effect_nsides-2019-11-13.sql.gz) 7 张表:REPORT/CONDITION_CONCEPT/CONDITION_OCCURRENCE/DRUG_CONCEPT/DRUG_EXPOSURE/OFFSIDES/TWOSIDES
2012 原版 数据库导出文件 与论文数字严格对应
Decagon 基准版 四列 TSV(drug1 CID, drug2 CID, side-effect concept ID, side-effect name) 基准复现专用(数据页
R 生态 dbparser::parseTWOSIDES() 解析为标准 R 对象(文档

§3.4 存储大小

发行物均为压缩文本,存储需求在"笔记本可全量训练"的量级:

形态 压缩体积 展开后估算 说明
TWOSIDES.csv.xz(NSIDES v0.1) 数十 MB 数百 MB-GB 级 13 列平铺,pandas 直接读 xz
OFFSIDES.csv.xz(NSIDES v0.1) 数 MB 数十 MB 10 列单药版
effect_nsides-2019-11-13.sql.gz 数十 MB GB 级(含 2.2 亿行三元组表) 建索引后建议 8 GB 内存机器
2012 原版数据库导出 数十 MB 数百 MB 与论文数字严格对应
Decagon 四文件包 数百 MB 约 1 GB 含 PPI/药-靶/相似性多模态图

全部资源本地存储与索引预留 5 GB 即绰绰有余;相比动辄数 TB 的影像数据集,这是真正的轻量级数据集。2012 原版数据库导出为数十 MB。

§3.5 标注方式

标注 = 统计信号检测,非人工标注。 每条"标签"(药物对-副作用关联)由以下自动化流水线产生:SCRUB 偏倚校正 → 倾向性评分匹配(10 次 bootstrap 逻辑回归预测药物暴露,6 个倾向得分箱,1:10 对照采样)→ 四格表计数 → PRR 计算 → 显著性判定(LOG(PRR) − 1.96 × PRR_error > LOG(2),即 PRR 下置信限 > 2)。因此标签性质是"弱监督/统计监督":有信号强度与置信区间,无真值保证。这是它与人工策展型数据集(DrugBank、BIOSNAP)的本质区别,也直接决定了 §6.5 的多个坑点。

§3.6 标注者资质与一致性

无人工标注者,故无标注者间一致性指标(kappa 等)可言。替代性质量证据链为:三个独立银标准(SIDER、AERS 时序切分、加拿大 MedEffect)的 ROC 曲线对比显示加入 SCRUB 校正后预测能力显著提升;47 个药物类相互作用在 Stanford EMR 队列获得外部验证(P < 0.0001);OFFSIDES 恢复 SIDER 38.8% 的关联(恢复率受"说明书仅覆盖上市早期事件"影响,属预期内)。使用者应把这一证据链理解为"方法学验证"而非"标签准确率"。

§3.7 采集周期

2012 原版基于 AERS 自发布至 2012 年初的全部报告;NSIDES v0.1 更新至 2014 年底(官方明确说明"adverse events reported to the FDA through FAERS up to and including 2014")。官方在 KG Hub 收录页注明 TWOSIDES 正在推进 2022+ 数据更新并计划季度更新(截至 2026-09 信息)。自发报告本身是持续流式产生的,任何静态快照都代表一个时间切面。时间维度的完整结构如下:

时间切面 覆盖 可获得性
2012 原版 AERS 至 2012 年初 官方资源页下载
NSIDES v0.1 FAERS 至 2014 年底 GitHub Release 下载
2015-2021 报告 未包含于任何官方发行 需自 FDA FAERS 原始文件重建
2022+ 报告 官方推进季度更新计划 尚未随 TWOSIDES 发行(截至 2026-09 信息)

§3.8 地域覆盖

以美国 FDA 汇总报告为主。FDA 数据库亦接受并汇入境外报告(如企业全球安全性汇总上报),但报告文化、用药结构以美国市场为主,模型迁移到其他用药人群时需警惕 §7.1 所列的报告偏倚。跨体系对照的现成选项是加拿大 MedEffect(原论文银标准之一);欧盟 EMA 的 EudraVigilance 与 WHO 的 VigiBase 因访问政策不同,需单独申请。

§3.9 设备规格

不适用。数据集不含任何设备采集信号(无影像/波形/传感器数据),全部为报告事件的聚合计数。

§3.10 深度溯源链

  • 原始报告:FDA AERS/FAERS(自发报告 XML/ASCII 分发文件)。
  • 处理代码:NSIDES 项目的 notebooks 与脚本公开于 github.com/tatonetti-lab/nsides-release(含信号检测与建库全流程)。
  • 方法学论文Tatonetti et al., Sci Transl Med 2012(SCRUB + 倾向匹配 + PRR 的完整描述与三银标准评估)。
  • 外部验证:Stanford EMR 队列(论文 §验证部分);Decagon 文献回溯(Zitnik et al. 2018)。
  • 发布机构:斯坦福大学(2012)→ Tatonetti Lab(哥伦比亚大学,后迁 Cedars-Sinai),资源页持续维护(Cedars-Sinai 资源页)。

§4 数据结构

§4.0 目录树

以 NSIDES v0.1 发行包解压后的典型布局为例:

nsides-release-v0.1/
├── TWOSIDES.csv.xz              # 13 列主文件:药物对-事件关联 + 四格表 + PRR
├── OFFSIDES.csv.xz              # 10 列单药版本(无 drug_2 列)
├── effect_nsides-2019-11-13.sql.gz  # MySQL 全库 dump
├── nb/                          # 官方处理 notebooks
│   └── 4.insert_tables/         # 建库与灌表脚本
└── scripts/                     # 信号检测与过滤脚本

Decagon 基准版(自 snap.stanford.edu/decagon 获取后)的典型布局:

decagon/
├── decagon_ddi.csv              # 4 列:drug1 CID, drug2 CID, side-effect ID, side-effect name
├── decagon_ppi.csv              # PPI 网络(19,085 蛋白 / 715,612 边)
├── decagon_targets.csv          # 药-靶关联(STITCH)
└── decagon_drug_sim.csv         # 药物副作用相似性特征(SIDER+OFFSIDES 派生)

§4.1 DAIMS 数据字典(NSIDES v0.1 TWOSIDES.csv)

字段名 类型 说明 示例值 AI 用途 观测误差 信息性缺失编码 取值范围
drug_1_rxnorm_id Integer 第一个药的 RxNorm CUI 4493 实体主键;join DrugBank/PubChem RxNorm 归一化错误罕见但存在 无 NULL 正整数
drug_1_concept_name Text 第一个药的 RxNorm 标准名 Rosuvastatin 可读性展示;NLP 特征 同义词已归一 无 NULL 字符串
drug_2_rxnorm_id Integer 第二个药的 RxNorm CUI 6910 同上 同上 无 NULL 正整数
drug_2_concept_name Text 第二个药的 RxNorm 标准名 Furosemide 同上 同上 无 NULL 字符串
condition_meddra_id Integer 副作用的 MedDRA 码 10013573 标签空间主键 MedDRA 版本漂移 无 NULL 正整数
condition_concept_name Text 副作用 MedDRA PT 名称 Myopathy 多标签分类标签 术语层级(PT/HLT)需自查 无 NULL 字符串
A Integer 联合暴露组中报告该事件的数量 42 证据权重;PU 置信度 上报漏报偏倚 行被过滤(A=0 不出现于平铺文件) ≥1
B Integer 联合暴露组中未报告该事件的数量 5,110 四格表分母 同上 无 NULL ≥0
C Integer 匹配对照组中报告该事件的数量 317 PRR 分子 同上 A=C=0 的三元组整行被剔除 ≥0
D Integer 匹配对照组中未报告该事件的数量 9,880 四格表分母 同上 无 NULL ≥0
PRR Float 比例报告比 = (A/(A+B))/(C/(C+D)) 2.87 标签强度;连续监督 极端计数下不稳定(NaN/Inf,见坑点 3) 无 NULL(已过滤行外) (0, +Inf)
PRR_error Float PRR 误差估计 0.35 置信下限 = LOG(PRR) − 1.96×PRR_error 同上 无 NULL >0
mean_reporting_frequency Float A/(A+B) 0.0082 基线报告率特征 同上 无 NULL [0,1]

来源:nsides-release v0.1 字段说明。注意官方文件列名拼写为 drug_1_rxnorn_id(R 包 dbparser 文档亦沿用该拼写),实际解析时建议按位置或宽容匹配处理列名。

§4.2 标签分布

标签空间高度长尾:1,301 种副作用 PT 中,头部事件(恶心、腹泻、疲乏、头痛等高报类)覆盖海量药物对,而 Decagon 建基准时将标签空间裁剪为"出现于 ≥500 个药物对"的 964 类,尾部 337 类因样本过稀被排除。全空间 83,657,414 个(药物对 × 副作用)组合中,已知正例 4,651,131 条占 5.56%,未知/负例占 94.44%(DCSE 2025)。以单药对视角看:645 种药物理论上有 207,690 个两两组合,其中 144,217 个组合完全没有任何已知副作用关联——它们既可能是真无关联,也可能是从未被同用或从未被上报(PU learning 的核心难题)。

文献中常见的三个标签空间口径容易混淆,使用前务必对齐:

口径 副作用类数 来源语境 典型用途
1,301 2012 原版发行文件 Tatonetti Lab 官方资源页 数据集本身的完整标签空间
1,318 Decagon 语境全空间(63,473 对 × 1,318 = 83,657,414) DCSE 2025 计算正例率、全空间枚举
964 出现于 ≥500 药物对的过滤子集 Zitnik et al. 2018 排行榜基准;复现 SOTA 必用

§4.3 关键统计

统计项 数值 含义
显著性判据 LOG(PRR) − 1.96 × PRR_error > LOG(2) PRR 的 95% 置信下限超过 2 倍基线
对照构造 1:10 采样,6 个倾向得分箱(箱宽 0.2) 倾向评分来自 10 次 bootstrap 逻辑回归的平均
报告规模(NSIDES v0.1) 3,394 药物(≥1 次暴露) FAERS 至 2014 全库口径
事件类型(NSIDES v0.1) 17,552 种(≥1 次出现) 同上
药-事件对(NSIDES v0.1) 9,505,200(显著 125,647) 单药层
药-药-事件三元组(NSIDES v0.1) 222,155,888(显著 5,729,992) 未按 OFFSIDES 过滤口径
关联两档语义 868,221 vs 3,782,910 组合特异 vs 增强型(见坑点 4)
全空间正例率 5.56%(4,651,131 / 83,657,414) 2012 原版口径,DCSE 2025
零关联药物对 144,217 / 207,690 645 药两两组合中完全无已知关联者

来源:nsides-release v0.1Tatonetti Lab 官方资源页

§4.4 数据层级

TWOSIDES 无患者-检查-序列-切片式的影像层级,其层级为:报告(REPORT,已聚合)→ 事件概念(CONDITION_CONCEPT)→ 统计四格表(A/B/C/D)→ 关联记录(TWOSIDES 行)。患者级报告在数据库中虽以 REPORT 表存在(report_id、report_year),但 age/sex 已 NULL 化,且对外发行以聚合统计为准。理解这一点对设计数据加载器很重要:不存在"按患者划分"的选项,划分单位只能是药物对或三元组。

层级 载体 粒度 划分可用性
报告层 REPORT 表(内部) 单份报告(report_id) 不可用:人口学全 NULL,发行以聚合为准
事件层 CONDITION_CONCEPT MedDRA/OMOP 概念 标签空间定义,非划分单位
统计层 A/B/C/D 四格表 药物(对)× 事件 证据权重来源
关联层 TWOSIDES 行 (drug_1, drug_2, meddra) 划分单位:按药物对或三元组

§4.5 缺失值与信息性缺失

字段/情形 缺失形态 信息性含义 建议处理
condition_snomed_id(MySQL 表) NULL MedDRA→SNOMED 映射不完美 经 OMOP concept_id 中转或按名匹配,勿强 join
drugbank_concept_id / chebi_concept_id NULL 药物术语映射缺口 多源回退(RxNorm → DrugBank API → PubChem CID)
REPORT.person_age / person_sex 全 NULL 脱敏处理,非自然缺失 放弃亚组建模;勿以此列做插补实验
A=C=0 的三元组 整行不存在 无事件或无报告(未观测) 视为 unknown 而非 negative(PU learning)
PRR 极端值 NaN / Inf 四格表退化(见坑点 3) 按规则显式处理,勿静默丢弃

§5 数据划分与使用建议

§5.1 官方划分

TWOSIDES 没有官方训练/验证/测试划分。 发行物只是关联清单;划分协议由基准论文各自定义。社区事实标准是 Decagon 协议:对每个副作用类型,随机保留 10% 的正例三元组做测试,剩余 90% 训练,验证从训练中再切分;负例通过随机替换药物对并确认全图不存在该边来采样(Zitnik et al. 2018)。

两点官方层面的"准划分"信息值得注意:其一,官方数据本身已经内置一层筛选——A=0 的行被剔除、平铺文件要求 PRR > 0.1,这意味着数据集到手时已经是"信号宇宙"的一个子集,任何以"A=0 行是负例"为假设的实验设计都不成立;其二,NSIDES v0.1 的显著判定未按 OFFSIDES 过滤(官方 release notes 明确注释),因此同一三元组在 2012 原版(组合特异口径)与 v0.1(全口径)中的标签归属可能不同——跨版本划分实验必须固定单一版本。

§5.2 社区惯例划分

  • Decagon 随机划分(最常用):按三元组随机 90/10,配均衡负采样;优点是可与全部公开排行榜对比,缺点是随机划分允许同一药物对出现在训练与测试(不同副作用),且忽略时间。
  • 按药物对划分(cold-start):以药物对为单位切分,测试集中的药物对从未在训练出现;DDINet 等近期工作采用 S1(随机)/S2(seen-unseen 药物)/S3(unseen-unseen 药物)三档设定(DDINet, Knows Syst 2026)。
  • 按时间划分:以报告年代切分模拟前瞻部署;因发行文件无时间戳,需自行回溯原始 FAERS 或使用 NSIDES 建库代码重建,成本高但最接近真实。

§5.3 泄漏风险(重点)

  1. 同药物对跨集泄漏:Decagon 随机划分下,药物对 (a,b) 的副作用 z₁ 在训练集、z₂ 在测试集,模型可通过记忆药物对嵌入"作弊";报告的 AUROC 因此系统性偏高。
  2. 特征侧泄漏:用 SIDER/OFFSIDES 构造药物特征时,若其中混入测试集药物的关联信息,属于间接标签泄漏。
  3. 负采样泄漏:负例若从"全空间"均匀采样,会大量命中 144,217 个"零关联药物对"这类平凡负例,虚高指标(DCSE 2025)。
  4. 多模态合并泄漏:从 PubChem/DrugBank 拉取分子特征时拉入了与测试标签相关的注释(如已知相互作用注释),需审计特征来源。

§5.4 交叉验证建议

药物对数(63,473)与三元组规模(数百万级)允许大 k 折,但建议按药物对分组的 5 折交叉验证(GroupKFold on drug pair)而非逐三元组随机折,保证同一药物对的所有副作用标签同折;若研究 cold-start 泛化,则按药物分组(测试集药物在训练集完全未见)。重复 3 个随机种子并报告均值±标准差是 2023 年后综述的通行要求(Brief Bioinform 2023 评估)。

§5.5 外部验证建议

优先级从高到低:(1) 时序外推——用 2014 年前的数据训练、2015 年后的 FAERS 自建标签验证;(2) 跨体系——以加拿大 MedEffect 或 VigiBase 派生信号做独立验证集;(3) 临床回顾——对模型 top-k 新预测做文献检索回溯(Decagon 范式,5/10 获证实);(4) EMR 队列——模仿原论文的 Stanford 验证,用真实处方与客观测量(如 QT)复核高置信预测。任何单一外部验证都不足以支撑临床声明,建议至少覆盖 (1)(3) 两类。

§5.6 划分决策速查表

你的目标 划分方式 负采样 可比对象 注意事项
复现 Decagon 论文 随机 10% held-out(按三元组) 1:1 均衡,全空间随机替换 表中全部基线 记忆泄漏高估泛化;只用于排行榜对比
方法论文(2023 后投稿) S1 随机 / S2 / S3 三档 + ≥3 种子 均衡 + 不均衡双协议 SumGNN、DCSE、DDINet 必须报均值±标准差与 DeLong 检验
工业部署前评估 按药物对 GroupKFold 5 折 限制负例在"有已知关联的对"内部 自建基线 更接近"新组合进入处方系统"的真实场景
药物警戒前瞻验证 时序划分(自建 FAERS 年份标签) 真实不均衡 无直接可比 最诚实但成本最高;需回溯原始报告
cold-start 研究 按药物分组(测试药完全未见) 同 S3 SkipGNN 谱系 谨防坑点 5 的实体重复污染划分

§6 AI 就绪指南 ⭐

§6.0 云端快速启动

数据集体积小(压缩后数十 MB),Colab/Kaggle 免费 CPU 实例即可完成全流程;若训练图神经网络(Decagon 类),单张 16 GB 显存 GPU 足以运行 645 节点的多关系 GCN。无需特殊云配置或大数据服务。

环境 最低配置 适用任务 启动命令要点
本地笔记本 8 GB 内存,无 GPU §6.1 读数据、§6.3 预处理、XGBoost 基线 pip install pandas numpy scikit-learn
Colab 免费 CPU 12 GB 内存 全流程含 §6.4 DataLoader 冒烟 wget 数据再跑代码块
Colab T4 / Kaggle GPU 16 GB 显存 Decagon 类多关系 GCN 标签矩阵与图先预构建再上卡
服务器(全库分析) 8 GB+ 内存 MySQL 2.2 亿行三元组查询 建索引或改用 DuckDB 直读 CSV

§6.1 快速上手

以下代码假设目录结构为 data/twosides/TWOSIDES.csv.xz(即 §4.0 目录树解压后),DATA_ROOT 指向存放解压产物的目录;最小可用子集是"药物对 × 副作用"三元组三列,先跑通再引入四格表统计量。

# 依赖: pandas >= 1.5 (xz 支持内建), pyarrow (可选)
import pandas as pd
from pathlib import Path

DATA_ROOT = Path("data/twosides")            # 解压 nsides-release-v0.1 后的目录
csv_path = DATA_ROOT / "TWOSIDES.csv.xz"     # xz 压缩可直接读,无需手动解压

df = pd.read_csv(csv_path)
print(df.shape)          # NSIDES v0.1: ~百万级行 × 13 列(2012 原版为 4,651,131 行 × 8-13 列)
print(df.head())

# 最小可用子集:三元组 + PRR
triplets = df[["drug_1_rxnorm_id", "drug_2_rxnorm_id",
               "condition_meddra_id", "condition_concept_name", "PRR"]]
print(f"药物对数: {triplets[['drug_1_rxnorm_id', 'drug_2_rxnorm_id']].drop_duplicates().shape[0]}")
print(f"副作用种类: {triplets['condition_meddra_id'].nunique()}")

§6.2 数据获取

渠道 内容 获取流程 大小
2012 原版 TWOSIDES + OFFSIDES + 副作用相似度评分 网页直接点击下载,无注册 数十 MB
NSIDES v0.1 TWOSIDES.csv.xz / OFFSIDES.csv.xz / MySQL dump / 代码 GitHub Release 直接下载 数十 MB/文件
Decagon 基准版 decagon_ddi.csv 等四个文件 直接下载 数百 MB
R 用户 dbparser 包解析 install.packages("dbparser")
# 一键获取 NSIDES v0.1 平铺文件(Linux/macOS)
mkdir -p data/twosides && cd data/twosides
wget -c https://github.com/tatonetti-lab/nsides-release/releases/download/v0.1/TWOSIDES.csv.xz
wget -c https://github.com/tatonetti-lab/nsides-release/releases/download/v0.1/OFFSIDES.csv.xz

# 可选:加载 MySQL 全库
# gunzip < effect_nsides-2019-11-13.sql.gz | mysql effect_nsides

Python 用户的等价获取方式(含完整性自校验):

# 依赖: requests, tqdm
import hashlib, pathlib, requests

URL = "https://github.com/tatonetti-lab/nsides-release/releases/download/v0.1/TWOSIDES.csv.xz"
dest = pathlib.Path("data/twosides/TWOSIDES.csv.xz")
dest.parent.mkdir(parents=True, exist_ok=True)

if not dest.exists():
    with requests.get(URL, stream=True, timeout=60) as r:
        r.raise_for_status()
        with open(dest, "wb") as f:
            for chunk in r.iter_content(chunk_size=1 << 20):
                f.write(chunk)

sha = hashlib.sha256(dest.read_bytes()).hexdigest()
print(dest, dest.stat().st_size, "bytes, sha256:", sha[:16], "...")
# 把 sha256 写入实验配置(见 §6.10 数据版本化)

无申请门槛:不需要注册、凭证化或签署协议,这是它与 MIMIC 类临床库最大的获取差异。唯二义务是引用论文与遵守学术使用声明。

§6.3 预处理全流程

目标:把平铺关联表转换为"药物对 → 多标签向量 + 特征"的训练矩阵,含负采样与 cold-start 划分。

# 预处理三步:构建标签矩阵 → 负采样 → 按药物对划分
import numpy as np
import pandas as pd
from pathlib import Path

DATA_ROOT = Path("data/twosides")
df = pd.read_csv(DATA_ROOT / "TWOSIDES.csv.xz")

# ---- 步骤 1: 实体索引化(按出现频率过滤,对齐 Decagon 的 ≥500 对口径可自行调整)----
pair_count = df.groupby(["drug_1_rxnorm_id", "drug_2_rxnorm_id"]).size()
effect_count = df["condition_meddra_id"].value_counts()

MIN_PAIRS_PER_EFFECT = 500          # Decagon 口径:副作用至少出现于 500 个药物对
keep_effects = effect_count[effect_count >= MIN_PAIRS_PER_EFFECT].index
d = df[df["condition_meddra_id"].isin(keep_effects)].copy()

drugs = sorted(set(d["drug_1_rxnorm_id"]) | set(d["drug_2_rxnorm_id"]))
effects = sorted(keep_effects)
drug2id = {x: i for i, x in enumerate(drugs)}
eff2id = {x: i for i, x in enumerate(effects)}
n_drugs, n_eff = len(drugs), len(effects)

# 药物对字典: pair_id -> (drug_a, drug_b);注意药物对无序(见坑点 6)
d["pair_key"] = d.apply(lambda r: tuple(sorted((r.drug_1_rxnorm_id, r.drug_2_rxnorm_id))), axis=1)
pairs = sorted(d["pair_key"].unique())
pair2id = {p: i for i, p in enumerate(pairs)}

# 多标签指示矩阵 Y[pair, effect] ∈ {0,1}
Y = np.zeros((len(pairs), n_eff), dtype=np.float32)
for (p, e) in d[["pair_key", "condition_meddra_id"]].drop_duplicates().itertuples(index=False):
    Y[pair2id[p], eff2id[e]] = 1.0
print(Y.shape, "密度: %.4f%%" % (100 * Y.mean()))

# ---- 步骤 2: 负采样(见坑点 1:负例策略决定指标可信度)----
rng = np.random.default_rng(42)
def sample_negatives(Y, n_neg_per_pair=50):
    """在 Y==0 的位置随机采样;进阶版应按药物对难度分层(有/无已知关联)"""
    N = Y.shape[0]
    neg_rows, neg_cols = [], []
    for i in range(N):
        zeros = np.flatnonzero(Y[i] == 0)
        pick = rng.choice(zeros, size=min(n_neg_per_pair, len(zeros)), replace=False)
        neg_rows.extend([i] * len(pick)); neg_cols.extend(pick.tolist())
    return np.array(neg_rows), np.array(neg_cols)

# ---- 步骤 3: 按药物对分组划分(防泄漏,见坑点 7)----
from sklearn.model_selection import GroupKFold
pair_drug_group = np.array([p[0] for p in pairs])   # 按主药分组;更严格可按 unordered pair 的哈希
gkf = GroupKFold(n_splits=5)
train_idx, test_idx = next(gkf.split(np.zeros(len(pairs)), groups=pair_drug_group))

特征工程分支:基准复现直接用 Decagon 版四列文件 + 其发布的多模态图(PPI + 药-靶);自建特征则用 PubChem CID 或 DrugBank ID 合并 Morgan 指纹(rdkit.Chem.AllChem.GetMorganFingerprintAsBitVect),注意 §4.5 的标识符映射缺口。

分子特征构建的完整参考实现(药物侧静态特征,一次构建、全实验复用):

# 依赖: rdkit >= 2023.03 (pip install rdkit)
# 输入: drugs.csv 含两列 [rxnorm_id, smiles];SMILES 需自 PubChem/DrugBank 按 §4.5 的映射链获取
# 输出: fingerprints.npy,形状 (n_drugs, 2048),行序与药物索引对齐后供 §6.4 Dataset 使用
import numpy as np
import pandas as pd
from rdkit import Chem
from rdkit.Chem import AllChem

def build_morgan_fingerprints(drugs_csv: str, radius: int = 2, n_bits: int = 2048):
    df = pd.read_csv(drugs_csv)                       # 列: rxnorm_id, smiles
    rows, kept = [], []
    for rxnorm, smi in zip(df["rxnorm_id"], df["smiles"]):
        mol = Chem.MolFromSmiles(str(smi))
        if mol is None:                               # 无效/缺失 SMILES:记录而非静默跳过
            rows.append(np.zeros(n_bits, dtype=np.uint8))
            continue
        fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=radius, nBits=n_bits)
        rows.append(np.asarray(fp, dtype=np.uint8))
        kept.append(rxnorm)
    return np.stack(rows), kept

# fps, kept = build_morgan_fingerprints("data/twosides/drugs.csv")
# np.save("data/twosides/fingerprints.npy", fps)
# 建议同场保存 kept 列表与映射率日志(见坑点 5),纳入版本控制

§6.4 PyTorch DataLoader(完整可运行)

# 依赖: torch >= 2.0, scikit-learn
# 目录预期: data/twosides/TWOSIDES.csv.xz(NSIDES v0.1)
# 产出: 多标签 DDI 数据集 —— 每个样本 = (药物对嵌入索引, 副作用标签向量)
import numpy as np
import pandas as pd
import torch
from torch.utils.data import Dataset, DataLoader
from pathlib import Path

DATA_ROOT = Path("data/twosides")

class TwoSidesDataset(Dataset):
    """药物对多标签副作用数据集。
    返回: (drug1_idx, drug2_idx, label_vector[float32, n_effects])
    特征建议外挂 Morgan 指纹矩阵 (n_drugs, 1024),此处用可学习嵌入索引保持最小依赖。
    """
    def __init__(self, csv_path: Path, min_pairs_per_effect: int = 500,
                 indices: np.ndarray | None = None, n_neg: int = 0, seed: int = 42):
        d = pd.read_csv(csv_path)
        eff_count = d["condition_meddra_id"].value_counts()
        keep = eff_count[eff_count >= min_pairs_per_effect].index
        d = d[d["condition_meddra_id"].isin(keep)].copy()

        d["pair_key"] = [tuple(sorted((a, b))) for a, b in
                         zip(d["drug_1_rxnorm_id"], d["drug_2_rxnorm_id"])]
        self.pairs = sorted(d["pair_key"].unique())
        self.effects = sorted(keep)
        p2i = {p: i for i, p in enumerate(self.pairs)}
        e2i = {e: i for i, e in enumerate(self.effects)}
        n, m = len(self.pairs), len(self.effects)

        self.Y = np.zeros((n, m), dtype=np.float32)
        for (p, e) in d[["pair_key", "condition_meddra_id"]].drop_duplicates().itertuples(index=False):
            self.Y[p2i[p], e2i[e]] = 1.0

        self.drug1 = np.array([p[0] for p in self.pairs], dtype=np.int64)
        self.drug2 = np.array([p[1] for p in self.pairs], dtype=np.int64)
        # 稀疏药物索引:把 RxNorm 压缩为连续 id
        uniq = sorted(set(self.drug1.tolist()) | set(self.drug2.tolist()))
        u2i = {u: i for i, u in enumerate(uniq)}
        self.drug1 = np.array([u2i[x] for x in self.drug1])
        self.drug2 = np.array([u2i[x] for x in self.drug2])

        # 负例增强:把 (pair, effect=0) 摊平为二分类流(n_neg>0 时启用)
        self.indices = indices if indices is not None else np.arange(n)
        self.n_neg = n_neg
        self.rng = np.random.default_rng(seed)

    def __len__(self):
        return len(self.indices)

    def __getitem__(self, k):
        i = self.indices[k]
        return (self.drug1[i], self.drug2[i], self.Y[i])

    def sample_negatives_for_epoch(self):
        """每 epoch 调用一次:为每个 pair 采样 n_neg 个负标签位置,
        返回 (pair_rows, effect_cols) 供二分类损失使用(见坑点 1 的策略讨论)。"""
        rows, cols = [], []
        for i in self.indices:
            zeros = np.flatnonzero(self.Y[i] == 0)
            pick = self.rng.choice(zeros, size=min(self.n_neg, len(zeros)), replace=False)
            rows.extend([i] * len(pick)); cols.extend(pick.tolist())
        return np.asarray(rows, dtype=np.int64), np.asarray(cols, dtype=np.int64)


# ---- 实例化 ----
from sklearn.model_selection import GroupKFold
tmp = TwoSidesDataset(DATA_ROOT / "TWOSIDES.csv.xz")
gkf = GroupKFold(n_splits=5)
tr, te = next(gkf.split(np.zeros(len(tmp.pairs)), groups=tmp.drug1))

train_ds = TwoSidesDataset(DATA_ROOT / "TWOSIDES.csv.xz", indices=tr, n_neg=50, seed=0)
test_ds  = TwoSidesDataset(DATA_ROOT / "TWOSIDES.csv.xz", indices=te)

train_loader = DataLoader(train_ds, batch_size=256, shuffle=True,  num_workers=2, pin_memory=True)
test_loader  = DataLoader(test_ds,  batch_size=512, shuffle=False, num_workers=2)

# 冒烟测试
for d1, d2, y in train_loader:
    print(d1.shape, d2.shape, y.shape, y.dtype)   # (B,) (B,) (B, n_effects) float32
    break

配套的最小可运行模型与训练循环(双塔嵌入 + 多标签 Sigmoid 输出,可作为一切复杂模型的行为基线):

import torch
import torch.nn as nn

class PairMLP(nn.Module):
    """药物对 -> 多标签副作用。药物用可学习嵌入;生产环境可替换为 Morgan 指纹/图编码器。"""
    def __init__(self, n_drugs: int, n_effects: int, emb_dim: int = 128):
        super().__init__()
        self.drug_emb = nn.Embedding(n_drugs, emb_dim)
        self.mlp = nn.Sequential(
            nn.Linear(emb_dim * 2, 512), nn.ReLU(), nn.Dropout(0.3),
            nn.Linear(512, 512), nn.ReLU(), nn.Dropout(0.3),
            nn.Linear(512, n_effects),
        )

    def forward(self, d1, d2):
        h = torch.cat([self.drug_emb(d1), self.drug_emb(d2)], dim=-1)
        return self.mlp(h)                     # logits,形状 (B, n_effects)

n_drugs = int(max(train_ds.drug1.max(), train_ds.drug2.max())) + 1
model = PairMLP(n_drugs=n_drugs, n_effects=len(train_ds.effects))
opt = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-5)
crit = nn.BCEWithLogitsLoss()

for epoch in range(3):
    model.train()
    for d1, d2, y in train_loader:
        d1, d2, y = d1.long(), d2.long(), y.float()
        loss = crit(model(d1, d2), y)
        opt.zero_grad(); loss.backward(); opt.step()
    print(f"epoch {epoch}: loss={loss.item():.4f}")
# 评估用 §6.9 的 macro AUROC/AUPRC + p@50,并披露划分协议与负采样率

§6.5 坑点(8 个,全部来自本数据集真实特有失败模式)

⚠️ 坑点 1:纯正例数据集——负采样策略决定你的指标是否可信(分类:评估误用)

问题:TWOSIDES 只包含统计显著的正例关联(4,651,131 条),83,657,414 个可能组合中 94.44% 是"未知"而非"已知为负"(DCSE 2025)。若负例均匀采样自全空间,大量负例来自 144,217 个"零关联药物对"——它们作用于完全不同生物学通路、极易识别,模型靠排除平凡负例即可拿到虚高 AUROC。
症状:AUROC 轻松 0.95+,但 top-k 命中的都是"每个副作用榜单上重复出现的同一批药对";换个难负例采样法指标暴跌 10+ 点。
解决

  1. 简单方法:限制负例采样自"至少有一条已知关联的药物对"(63,473 对内部),避免零关联平凡负例主导测试集。
  2. 进阶方法:按 PRR 接近 1(信号弱但已观测)的位置构造难负例,或用 PU learning 把全部未观测位置视为未标注、以非对称风险训练(loss = w_pos * BCE(y) + w_unlabeled * BCE(1-y) * γ,γ∈(0,1) 惩罚未标注位被预测为正的置信度)。
  3. SOTA 方法:遵循 DCSE 的双协议——常规均衡设定 + 不均衡前瞻设定(负例按真实 94.44% 分布采样),同时报告两组指标;冷启动场景另报 S2/S3(unseen drug)设定(DDINet 2026)。
    参考DCSE 预印本(bioRxiv 2025)Decagon 论文负采样协议

⚠️ 坑点 2:合成关联(synthetic associations)——降糖药"导致"高血糖(分类:偏倚陷阱)

问题:自发报告中存在系统性混淆:降糖药更多被处方给糖尿病人,于是被"合乎逻辑地"报告为高血糖;合并用药、性别(妊娠类药物与女性专属事件)、年龄同样制造合成关联。TWOSIDES 论文用 SCRUB 算法在信号检测阶段校正了这些偏倚,但校正依赖的适应症/人口学代理变量并不完整。
症状:模型高置信输出"XX 降糖药 + XX → 高血糖"这类医学上荒谬的"预测";或副作用标签与适应症高度互锁,嵌入空间按适应症而非毒性聚类。
解决

  1. 简单方法:构建适应症黑名单(从 DrugBank indication 或 SIDER treatment 关系获取),评估时剔除"副作用 = 某药适应症"的药物对-事件三元组。
  2. 进阶方法:复用论文银标准协议——把"适应症共现率"作为每条标签的置信度折扣因子,训练时按 LOG(PRR)−1.96×PRR_error 加权损失。
  3. SOTA 方法:训练前对标签矩阵跑共指消解式的偏倚回归(用药物-适应症矩阵回归标签矩阵、取残差作为去混淆标签),即 SCRUB 思想在标签侧的二次实现;或在图模型中把适应症作为显式节点类型分离信息通路。
    参考Tatonetti et al. 2012, Fig.1

⚠️ 坑点 3:PRR 的 NaN 与 Inf——四格表退化值会毒化训练(分类:预处理陷阱)

问题:官方 release notes 明确列出三种退化:A=C=0 时 PRR 为 NaN;C=0 且 A>0 时为 Inf;A=0 且 C>0 时为 0。平铺文件过滤了 A=0 的行,但 MySQL 全库与自行重算的场景仍会遭遇。
症状df["PRR"].max() 返回 inf,标准化后整个特征列污染;log(PRR) 产生 -inf;训练损失出现 NaN 后全网络权重坏死。
解决

  1. 简单方法:读入后显式处理:df.replace([np.inf, -np.inf], np.nan, inplace=True),再按 LOG(PRR) - 1.96*PRR_error > LOG(2) 的显著性布尔列替代连续 PRR 做标签。
  2. 进阶方法:对连续使用场景做平滑——用 Haldane-Anscombe 校正(每格 +0.5)重算 PRR,保留序数信息且消除除零:PRR_sm = ((A+0.5)/(A+B+1)) / ((C+0.5)/(C+D+1))
  3. SOTA 方法:不直接用 PRR,改用其显著性证据下限 LOG(PRR) − 1.96×PRR_error 作为连续监督信号(官方 NSIDES 管线同款判据),自然有界且与显著性定义单调一致。
    参考nsides-release release notes 信号检测方法节

⚠️ 坑点 4:868,221 与 3,782,910 两档关联语义不同——"相互作用"被高估(分类:标签理解)

问题:TWOSIDES 总量 4,651,131 中只有 868,221 条是"无法归因于任一单药"的组合特异性信号;另外 3,782,910 条仅满足"药物对 PRR 高于两单药",其中包含单药本身信号就很强的叠加毒性。直接用全量训练,模型会把"两药各自都有肝毒性"学成"相互作用"。
症状:把预测结果与药品说明书相互作用章节比对时假阳性极高;OFFSIDES 过滤后模型性能骤降而无法解释。
解决

  1. 简单方法:2012 原版文件中两档信息可用"是否被 OFFSIDES 单药信号解释"重建:下载 OFFSIDES,凡是 (drug_i, event) 出现在 OFFSIDES 显著列表的组合关联标记为"单药可解释"。
  2. 进阶方法:构造两通道标签(组合特异 / 增强型),训练多头输出分别评估;至少在测试协议中只报告组合特异通道的指标。
  3. SOTA 方法:按 PRR 差值(pair PRR − max(单药 PRR))做连续加权,让损失函数显式区分"叠加"与"超加和(synergistic)"信号。
    参考Tatonetti Lab 官方资源页两档定义nsides-release 注释

⚠️ 坑点 5:标识符映射缺口——RxNorm/MedDRA/DrugBank/CID 四套术语对不齐(分类:工程陷阱)

问题:TWOSIDES 原生用 RxNorm(药)与 MedDRA(事件);NSIDES 数据库的 DrugBank/ChEBI/SNOMED 映射列都有 NULL;Decagon 版用 PubChem CID。合并分子特征或外部标签时,任何一跳映射失败都产生静默样本丢失。
症状:合并特征后行数比预期少 5-15% 且无报错;同一药物在训练集和测试集被当成两个实体(重复节点),cold-start 评估被污染。
解决

  1. 简单方法:以 RxNorm 名称为桥接键做规范化匹配(大小写/盐型剥离),统计匹配率并显式报告丢弃比例。
  2. 进阶方法:用 UMLS/RxNorm API 与 UNII 做多源回退映射:RxNorm → UNII → DrugBank;MedDRA → SNOMED 走 OMOP CDM concept 表(NSIDES 自带 condition_concept_id)。
  3. SOTA 方法:直接采用 Decagon 版做基准(其已完成药物侧 CID 映射),把自定义分析的映射错误隔离在增补特征一侧;对映射表做快照并入库版本控制。
    参考nsides-release v0.1 字段注释Decagon 数据页

⚠️ 坑点 6:药物对无序化——(a,b) 与 (b,a) 的幽灵重复(分类:数据泄漏)

问题:官方文件保证"每个药物对只出现一次",顺序由数据库内部 OMOP CDM ID 决定、无语义。但用户自行合并多个版本(2012 原版 + NSIDES v0.1 + Decagon 版)时,同一药物对可能以相反顺序出现两次;groupby 疏漏会让划分函数把同对异序样本分进训练与测试。
症状drop_duplicates() 前后行数差 >0 但肉眼看不出重复;cold-start 划分后测试指标反而高于随机划分(泄漏的典型倒挂)。
解决

  1. 简单方法:全部管道统一用 pair_key = tuple(sorted((id1, id2))) 规范化后再去重(本 Wiki §6.3/§6.4 代码已内置)。
  2. 进阶方法:在数据库层面建 UNIQUE(lower(drug1), lower(drug2)) 前先做 sorted 规范化列;版本合并时以 (rxnorm_id 对, meddra_id) 为复合主键做 upsert 并保留来源列。
  3. SOTA 方法:训练对称化——模型对 (a,b) 与 (b,a) 强制共享表示(交换等变网络或对特征排序),从结构上消除顺序敏感性,同时天然扩充对称数据。
    参考nsides-release v0.1 “Each drug pair … occur each only once” 注释

⚠️ 坑点 7:随机划分的时间泄漏——排行榜数字不可比的第一原因(分类:数据泄漏)

问题:FAERS 报告跨多年累积,但发行文件无时间戳、无官方划分。Decagon 式随机划分会让"测试集里预测某个已被训练集强烈暗示的信号"成为可能(同一药物对相邻副作用、同一时代报告冗余),而各篇论文划分协议不一(随机 10% / 三折 / S1-S3 cold start),AUROC 从 0.65 到 0.93 的差异很大程度来自协议而非模型。
症状:复现论文数字失败且方向不定;随机划分下的"新预测"回溯文献发现十年前已有报告——模型只是在插值。
解决

  1. 简单方法:报告指标时强制注明划分协议与负采样率;复现基准严格对齐 Decagon 10% held-out + 其发布负例。
  2. 进阶方法:补做时序协议——下载原始 FAERS 季度文件重建报告时间,按"训练 ≤2011 / 测试 ≥2012"(或 NSIDES 口径 2014)切分,报告性能衰减作为泛化的诚实估计。
  3. SOTA 方法:三协议并列报告(随机 / 药物对分组 / cold-start unseen drug),参考 DDINet 的 S1/S2/S3 + scaffold 划分矩阵;用 DeLong 检验比较模型而非裸点估计(DDINet 2026)。
    参考Brief Bioinform 2023 系统评估(协议差异量化)

⚠️ 坑点 8:PRR 关联 ≠ 因果,报告偏倚扭曲标签分布(分类:偏倚陷阱)

问题:自发报告漏报轻症、偏报重症与新药事件;报告率还受媒体曝光与监管警示影响。因此 TWOSIDES 的"标签"是上报行为的函数:两个药的同一种真实毒性,一个可能有 PRR 信号一个没有;PRR 显著也从不等于因果成立。论文的 EMR 验证(47 类,P < 0.0001)恰恰说明只有一部分信号能被独立数据复核。
症状:模型把"上市年份新"当作强特征(新药报告密度高);对老药组合系统性欠预测;下游药物警戒团队反馈信号价值随药品生命周期漂移。
解决

  1. 简单方法:把 PRR 显著性视为"证据等级"而非真值——评估时用置信下限加权,报告分层指标(高/低证据)。
  2. 进阶方法:加入"上市年数/报告基数 A+B"作为协变量或去偏特征;用 NEG(报出后随时间衰减的信号稳定性)过滤一次性热点信号。
  3. SOTA 方法:前沿工作将报告偏倚显式建模——以敏感性分析(不同 1:10 匹配比、不同箱宽重跑信号检测)给出标签不稳定区间,训练时做标签平滑或证据加权学习;对外声明只保留"通过 EMR 或文献外部验证"的预测。
    参考DrugPred limitations(Frontiers, 2024)Tatonetti et al. 2012 验证部分

§6.6 数据增强(安全 ✅ / 危险 ❌)

  • 对称翻转:(drug1, drug2) → (drug2, drug1) 是无损增强(药物对无序语义)。
  • 证据加权重采样:按 PRR 置信下限分层采样,缓解头部副作用主导。
  • 特征侧增强:Morgan 指纹位随机置 0/1(dropout 式)、子结构掩码,提升分子编码器鲁棒性。
  • 跨库标签合并:与 DrugBank DDI、SIDER 合并扩充标签覆盖(需防坑点 5 映射泄漏)。
  • 翻转标签极性:把未观测位置当真负例注入训练(PU 学习风险,见坑点 1)。
  • 药物级 SMILES 突变:随机原子替换可能产生无效/剧毒分子,且破坏"组合毒性来自真实分子"的语义。
  • 副作用标签同义词合并:不经 MedDRA 层级(PT→HLT)盲目字符串合并会把不同临床概念混为一谈。

§6.7 模型推荐

模型 类型 适用场景 TWOSIDES 参考表现(各自协议,不可直接比较)
Decagon(R-GCN + DEDICOM 解码) 多关系图卷积 有 PPI/药-靶外挂图时的金标准 AUROC 0.872 / AP 0.832(Zitnik 2018
DeepDDI 结构化深度网络(指纹对) 无图资源、仅分子结构 ROC-AUC 0.8301(SumGNN 复测口径)
SumGNN 子图知识图谱 GNN 需要可解释路径 ROC-AUC 0.9335(bbad235 汇总
SkipGNN 跳跃图网络 冷启动相似药迁移 ROC-AUC 0.9090
ComplEx / TransE 类 KGE 知识图谱嵌入 大规模多关系补全 AUROC 0.965 / 0.949(DrugPred 综述表,协议不同)
DCSE 端到端对比签名 均衡+前瞻双协议 SOTA AUROC 91.71/92.44(bioRxiv 2025
XGBoost + 指纹 梯度提升 快速基线/低算力 AUROC ≈0.80(Zitnik 协议基线)

§6.8 硬件需求

任务规模 配置 说明
表格基线(XGBoost/MLP) 任意笔记本 CPU 数据 <1 GB 内存即可
指纹 + 多标签分类 8 GB 内存 CPU / 入门 GPU 1,301 维输出矩阵是主要内存项
Decagon 类图神经网络 单卡 16 GB 显存(如 V100/T4) 645 节点多关系图极轻量;瓶颈在 964 类边解码
全库 MySQL 分析 8 GB 内存 2.2 亿行三元组表建议建索引或用 DuckDB 直读 CSV

§6.9 评估指标代码

# 指标三件套:逐副作用 AUROC/AUPRC(macro 平均)+ P@K(Decagon 口径)
import numpy as np
from sklearn.metrics import roc_auc_score, average_precision_score

def macro_auroc_auprc(Y_true: np.ndarray, Y_score: np.ndarray):
    aurocs, auprcs = [], []
    for j in range(Y_true.shape[1]):
        y, s = Y_true[:, j], Y_score[:, j]
        if y.sum() == 0 or y.sum() == len(y):   # 退化列跳过并记录
            continue
        aurocs.append(roc_auc_score(y, s))
        auprcs.append(average_precision_score(y, s))
    return float(np.mean(aurocs)), float(np.mean(auprcs)), len(aurocs)

def precision_at_k(Y_true: np.ndarray, Y_score: np.ndarray, k: int = 50):
    """对每个副作用类型:取预测分数 top-k 的药物对,检查其中真阳性比例(Decagon p@50 口径)"""
    pk = []
    for j in range(Y_true.shape[1]):
        idx = np.argsort(-Y_score[:, j])[:k]
        pk.append(Y_true[idx, j].mean())
    return float(np.mean(pk))

# 用法示例:
# auroc, auprc, n_valid = macro_auroc_auprc(Y_test, Y_pred)
# p50 = precision_at_k(Y_test, Y_pred, k=50)
# 报告时务必注明:负采样率、划分协议、有效副作用列数 n_valid

多随机种子与模型间显著性检验(2023 年后发表协议的最低要求):

# 3 种子重复 + DeLong 式配对比较的简化替代:配对 bootstrap 置信区间
import numpy as np

def bootstrap_ci(per_seed_scores: list[float], n_boot: int = 10000, seed: int = 0):
    """per_seed_scores: 每个种子的 macro AUROC;返回均值与 95% CI"""
    rng = np.random.default_rng(seed)
    x = np.asarray(per_seed_scores, dtype=np.float64)
    boots = [x[rng.integers(0, len(x), len(x))].mean() for _ in range(n_boot)]
    return x.mean(), np.percentile(boots, 2.5), np.percentile(boots, 97.5)

def paired_bootstrap_delta(scores_a: list[float], scores_b: list[float], n_boot: int = 10000):
    """两模型在同划分下的配对比较;Δ95%CI 不含 0 视为显著(DeLong 的工程化替代)"""
    rng = np.random.default_rng(0)
    a, b = np.asarray(scores_a), np.asarray(scores_b)
    delta = a - b
    boots = [delta[rng.integers(0, len(delta), len(delta))].mean() for _ in range(n_boot)]
    return delta.mean(), np.percentile(boots, 2.5), np.percentile(boots, 97.5)

§6.10 MLOps 笔记

事项 建议 失败后果
数据版本化 把 TWOSIDES.csv.xz 的 SHA256 与下载日期写入运行配置 2012 原版与 NSIDES v0.1 口径混用,实验不可复现
标签快照 负采样种子、min_pairs_per_effect、划分索引三者落盘(np.save 任一变化即构成新实验,指标漂移无从归因
评估对齐 团队内固定协议(推荐:Decagon 随机 + 分组 5 折 + 一个时序协议) 排行榜跨协议对比产生虚假 SOTA
漂移监控 监控"预测 top-k 与最新版数据新增信号的命中率" FAERS 季度更新后模型静默退化
合规留痕 保存许可快照;输出附"统计信号,非因果"免责文本 把关联当因果进入临床工作流

§7 质量评估与局限性

§7.1 已知偏倚

偏倚类型 描述 严重程度 缓解措施
上报偏倚 轻症漏报、重症/新药/媒体热点事件偏报,标签分布偏离真实发生率 证据加权学习;按上市年数分层评估(坑点 8)
合成关联(混淆) 适应症、合并用药、性别、年龄混淆制造的虚假信号 高(原论文核心问题) SCRUB 校正已内建;下游再做适应症过滤(坑点 2)
检测力偏倚 常用药物对报告基数大,更易触发 PRR 显著 以 A+B 报告基数做分层或协变量校正
口径偏倚 868,221(组合特异)与 3,782,910(增强型)混于一库,"相互作用"被高估 OFFSIDES 过滤或双通道标签(坑点 4)
术语漂移 MedDRA 版本演进导致同一临床概念换码 低-中 经 OMOP concept 层 join;固定词典版本
地域偏倚 美国市场用药结构与上报文化主导 跨体系验证(MedEffect);谨慎迁移至他国人群

§7.2 标注质量

标注由统计管线自动产生(见 §3.5),其质量证据链为三个银标准 + EMR 外部验证 + Decagon 文献回溯(§2.6 表)。三点提醒:其一,PRR 显著性是二值化产物,边界附近的标签不稳定(置信下限贴着 LOG(2) 的关联可靠性最低);其二,OFFSIDES 对 SIDER 38.8% 的恢复率既说明信号检测能找到说明书事件,也说明约六成说明书事件无法从报告数据中复原——逆向同理,不要假设 TWOSIDES 覆盖了全部真实组合毒性;其三,1,301 个 PT 中长尾事件的四格表计数很小,PRR 估计方差大,头部与尾部标签的可靠性不可等量齐观。

标签可靠性分层速查(建议按此分层加权训练或分层报告评估):

可靠性层 判别特征 建议
A 较大且 PRR 置信下限远超 LOG(2) 可作核心监督信号
置信下限贴近 LOG(2)(边界显著) 训练降权;评估单独报告
四格表计数极小(A 或 C 个位数) 视为弱证据;避免用于排行榜主指标
存疑 单药可解释(OFFSIDES 信号覆盖) 按"增强型"而非"组合特异"处理(坑点 4)

§7.3 泛化性

部署场景 失效风险 证据/说明
未来时间(2014 后新药) 高:新药组合无历史报告,模型无法覆盖 数据止于 FAERS 2014(NSIDES v0.1);时序协议必测
儿科/孕产人群 高:人群报告结构不代表特殊人群 官方另建 KidSIDES/AwareDX 专门覆盖
非美用药人群 中-高:用药结构与上报文化差异 建议以本地自发报告库重校准
罕见副作用预测 高:长尾 PT 证据稀薄,PRR 方差大 Decagon 裁剪至 ≥500 对的 964 类即为此因
复方制剂场景 中:三药及以上组合超出数据范围 组合特异信号仅定义于药物对;三药看 ManySIDES
直接临床决策 高:统计信号非因果、无剂量/病程信息 只可用于假设生成与优先级排序

§7.4 伦理

数据不含患者级信息(聚合计数、人口学字段 NULL 化),属于低隐私风险资源;来源报告本身由 FDA 以脱敏形式发布。伦理要点在于使用声明:模型输出若进入临床工作流,必须明示"基于自发报告统计信号",防止把关联当因果导致误撤必需联合用药(如肿瘤、HIV 场景的多药方案)。学术使用之外的商业用途应与版权方确认(官方声明对多数用途开放,见 INFOBOX 许可证行)。

§7.5 公平性

REPORT 表 age/sex 全 NULL(脱敏),数据集本身无法做亚组公平性审计;同时原始报告体系存在已知的性别/年龄上报偏倚(论文 Fig.1 明确展示了性别与年龄合成关联并被 SCRUB 校正)。这意味着:基于 TWOSIDES 的模型对女性特异事件、老年多病共存人群的信号覆盖可能系统性不足—— AwareDX(Tatonetti Lab 的性别特异风险库)正是为填补该缺口而生。任何下游部署前,建议以本地 EMR 分层(性别、年龄段)检验模型信号召回的均匀性。

§7.6 数据漂移

三个漂移轴及其监控手段:

漂移轴 机制 对模型的影响 监控/缓解
词典漂移 MedDRA 与 RxNorm 版本演进,同概念换码 历史标签与新版 join 失败、标签空间分裂 经 OMOP 概念层映射(§4.5);冻结词典版本号
报告行为漂移 监管警示/媒体曝光瞬时抬高特定药物对报告率 脉冲式伪信号混入训练标签 坑点 8 的敏感性分析与证据加权
版本漂移 2012 原版(4,651,131)与 NSIDES v0.1(5,729,992 显著三元组)口径不同;官方计划季度更新 新旧数据混训导致实验不可复现 SHA256 版本锚定;以"新增信号命中率"做漂移指标

§7.7 DAIMS 数据质量 24 项评估

# 检查项 状态 说明
1 宽格式 长格式三元组关联表;多标签矩阵需自行 pivot(§6.3)
2 唯一标识 (drug_1, drug_2, meddra_id) 复合键天然唯一;药物对无序化已由官方处理
3 特殊字符 纯 ASCII 名称与整数码;CSV 解析无陷阱
4 重复行 官方保证药物对只出现一次;跨版本合并需自行 sorted 去重(坑点 6)
5 缺失编码 ⚠️ A=C=0 行被整行剔除;映射列有 NULL;无显式缺失哨兵值
6 标签标识 ⚠️ “标签”= PRR 显著性布尔,非人工确诊;两档语义需区分(坑点 4)
7 罕见类分组 ⚠️ 1,301 PT 高度长尾;Decagon 以 ≥500 对阈值裁剪至 964 类
8 偏倚评估 ⚠️ 上报/检测力偏倚已知且方向明确,但无逐标签偏倚度量
9 数据字典 release notes 逐列说明,含数据类型与生成逻辑
10 信息性缺失解释 官方明确解释 NULL 语义(脱敏、映射不完美、退化行剔除)
11 设备记录 不适用:无设备采集数据
12 共线性 A/B/C/D 与派生量(PRR、频率)间函数关系透明,无意外共线
13 编码映射 ⚠️ MedDRA→SNOMED、RxNorm→DrugBank/ChEBI 均有缺口(坑点 5)
14 时间戳处理 发行文件无报告时间戳;时序协议需回溯原始 FAERS
15 划分建议 ⚠️ 无官方划分;社区有 Decagon 协议与 S1-S3 cold-start 惯例(§5.2)
16 泄漏讨论 ⚠️ 泄漏模式明确可枚举(§5.3),但默认随机划分本身即是泄漏源
17 标签分布 头长尾结构有完整统计(§4.2);全空间正例率 5.56% 可精确重构
18 测量偏倚 ⚠️ PRR 依赖倾向匹配流程(1:10、6 箱),流程参数即测量偏倚源
19 外部验证建议 官方示范了三银标准 + EMR 验证路径,可复用(§5.5)
20 版本记录 版本时间轴清晰:2012 原版 → NSIDES v0.1(2019-11)→ 计划季度更新
21 预处理脚本 官方公开全部 notebooks 与脚本(nsides-release 仓库)
22 合规要求 开放获取;义务仅为引用论文;无 DUA/培训要求
23 多模态对齐 分子/靶点/PPI 特征需自行跨库合并,无对齐保证(坑点 5)
24 去标识化 聚合统计 + 人口学字段 NULL 化,无再识别风险

DAIMS 评分:16.0 / 24(✅=1 分 ×12,⚠️=0.5 分 ×8,❌=0 分 ×4)

评分解读:16.0/24 处于"结构健康、方法论透明,但需要使用者自建关键基础设施"的水平。数据字典、版本记录、去标识化、官方脚本等"托管质量"项几乎满分——这在自发报告派生数据集中属第一梯队;失分集中在"建模就绪"侧:无时间戳、无官方划分、无真负例、多模态不对齐,全部是使用者必须自行决策并承担风险的环节。

对你意味着什么:(1) 不要期待"下载即训练"——先复刻 §6.3 的标签矩阵与划分管道,并把每个决策(负采样率、阈值、种子)固化为版本化资产;(2) 报告任何指标时同步披露划分协议与负采样策略,否则数字无意义;(3) 若需要时间或人群维度的分析,本数据集给不了,请回溯原始 FAERS 或转用 KidSIDES/AwareDX;(4) 跨库合并特征前先做映射审计(坑点 5),把映射表纳入版本控制;(5) 该数据集最可靠的产出是"高置信假设清单",将其设计为药物警戒工作流的前置过滤器而非自动决策器。

§7.8 外部验证矩阵

外部数据集/场景 来源机构 评估任务 性能指标 相对内部变化 关键发现
Stanford EMR 队列 Stanford 医院 47 个药物类相互作用复核 P < 0.0001(Cox 模型) 非指标对比,方向性验证 SSRI+噻嗪 QT 延长 HR 1.5(95% CI 1.2–1.9)获独立证实(Tatonetti 2012
SIDER 4.1(说明书) 二元信息挖掘 OFFSIDES 恢复率(方法学代理) 恢复 38.8%(18,842 对) 覆盖率约四成 说明书事件可部分复原;差异源于上市后新事件
AERS 时序切分 FDA(自切分) 信号前瞻检出 ROC 曲线(SCRUB+EBGM 优于裸 EBGM) 校正后 AUC 显著提升 时序验证确认 SCRUB 校正的增益(Tatonetti 2012
加拿大 MedEffect Health Canada 跨体系信号验证 ROC 曲线(三银标准之一) 与 AERS 增量报告一致 跨报告体系泛化的直接证据
后续医学文献(Decagon top-10) 公开文献 新预测回溯证实 5/10 获文献支持 Atorvastatin+Amlodipine 肌肉炎症等组合后见临床文献(Zitnik 2018

§8 基准性能与生态

§8.1 排行榜(Decagon 协议,964 类副作用)

排名 模型 AUROC AP 年份 关键技术 完整引用 代码
1 Decagon 0.872 0.832 2018 多关系 GCN + DEDICOM 解码,PPI/药-靶多模态图 Zitnik M, Agrawal M, Leskovec J. Modeling polypharmacy side effects with graph convolutional networks. Bioinformatics, 34(13):i457–i466, 2018. DOI 10.1093/bioinformatics/bty294 官方数据页
2 KGNN-LS 0.822 0.724 2020 知识图谱神经网络 + 标签平滑 Yu et al., KGNN(数值引自 Zitnik 协议汇总表)
3 拼接特征 MLP 0.793 0.697 2018 药物特征拼接基线 同 Zitnik et al. 2018 基线
4 DistMult 0.782 0.671 2018 双线性知识图谱嵌入 Yang et al., 2015(基线,见 Zitnik 2018)
5 DeepWalk 0.748 0.611 2014→2018 随机游走图嵌入 Perozzi et al., 2014(基线,见 Zitnik 2018)
6 DEDICOM 分解 0.705 2017 张量分解 Perros et al., 2017(见 DrugPred 表
7 RESCAL 0.693 2011 张量因子分解 Nickel et al., 2011(见 Zitnik 2018)

⚠️ 数值不可直接比较:上表全部来自 Zitnik et al. 2018 的同一协议(10% held-out、均衡负采样),但其他论文的 TWOSIDES 数字使用不同划分/负采样:SumGNN 复测中 Decagon 报 0.9060、SumGNN 0.9335、SkipGNN 0.9090、node2vec 0.8887(Rao et al., Brief Bioinform 2023, DOI 10.1093/bib/bbad235);DCSE 报 91.71(bioRxiv 2025)。跨论文比较一律无效。

§8.2 SOTA 总结与选型建议

基准格局分三档:(1) 有外挂知识图(PPI + 药-靶)时,多关系 GNN(Decagon)与子图 KGE(SumGNN)最强,且 Decagon 提供最好的机制可解释性(副作用嵌入按生理系统聚类);(2) 仅分子结构时,指纹 + 深度网络(DeepDDI 类)与 KGE 的差距缩小,XGBoost 是不可忽视的强基线;(3) 追求部署稳健性时,应放弃刷点、选择支持 S1/S2/S3 三档评估并做 DeLong 显著性检验的协议(DDINet、DCSE 代表了 2025-2026 年的务实方向)。选型建议:复现研究用 Decagon 起点;方法创新用 SumGNN/DCSE 协议;工业快速筛查用 XGBoost + 指纹起步。

三条来自生产实践的补充判断:

  1. 协议贡献大于架构贡献。同一模型在不同划分/负采样下的 AUROC 差异(0.83 vs 0.93)通常大于架构之间的差异——把精力投入协议标准化比换模型更划算(bbad235 系统评估)。
  2. 强基线不可跳过。Zitnik 协议下 XGBoost 达 0.80、DistMult 达 0.78,任何宣称 SOTA 的新架构都应先跨过这两条线。
  3. 可解释性是选型一票项。进入药物警戒工作流的模型必须能回答"为什么这对药、这个副作用",Decagon 的副作用嵌入聚类与 SumGNN 的子图路径是现有最实用的两类解释机制。

§8.3 评测协议

标准协议(Zitnik 2018):标签空间裁剪至 964 类(≥500 药物对);随机保留 10% 正例三元组为测试;负例 = 随机药物对替换且全图无此边;指标 = 逐副作用 AUROC/AP 的宏平均与 p@50。变体协议(2023-2026):S1 随机 / S2 seen-unseen / S3 unseen-unseen 药物三档 + scaffold 结构划分 + 均衡/不均衡双负采样率(DDINet 2026DCSE 2025)。报告规范:均值±标准差(≥3 种子)、有效副作用列数、负采样率必须披露。

数据集 关系 规模 获取
OFFSIDES 单药姊妹库(同管线) 438,801 off-label 关联;1,332 药物 官方页
OnSIDES 说明书正标签(NLP 抽取) 270 万药物-AE 对(2022 v01) onsidesdb.org(见 Cedars-Sinai 资源页
ManySIDES 三药及以上组合扩展 开发中 KG Hub 收录页
SIDER 4.1 单药说明书副作用 139,756 对;1,430 药 sideeffects.embl.de
DrugBank DDI v5.1.4 人工策展 DDI + 机制 191,808 对;86 类型 drugbank.com(学术注册)
BIOSNAP 二元 DDI 基准 41,520 DDI;1,332 药 SNAP
Decagon 多模态图 TWOSIDES 的基准化包装 964 类 + PPI 715,612 边 snap.stanford.edu/decagon

§8.5 关键论文 Top 7

  1. Tatonetti NP, Ye PP, Daneshjou R, Altman RB. Data-Driven Prediction of Drug Effects and Interactions. Sci Transl Med, 4(125):125ra31, 2012. DOI 10.1126/scitranslmed.3003377 — 数据集原始论文:SCRUB 校正 + 倾向匹配 + PRR 信号检测,TWOSIDES/OFFSIDES 双库诞生。
  2. Zitnik M, Agrawal M, Leskovec J. Modeling polypharmacy side effects with graph convolutional networks. Bioinformatics, 34(13):i457–i466, 2018. DOI 10.1093/bioinformatics/bty294 — 把 TWOSIDES 变成图学习基准(Decagon),确立 964 类协议。
  3. Nyamabo AK, Yu H, Shi JY 等(SumGNN)。Briefings in Bioinformatics, 2021-2023 系列;评估汇总见 DOI 10.1093/bib/bbad235 — 跨方法系统评估,量化协议差异对排行榜的影响。
  4. Deac A, Huang YH, Veličković P, Liò P, Jamnik M. Drug-Drug Adverse Effect Prediction with Graph Co-Attention. arXiv:1905.00534, 2019 — 共注意力图模型,明确记录 Decagon 版 4,576,785 正例口径。
  5. Chandak P, Tatonetti NP. Using Machine Learning to Identify Adverse Drug Effects Posing Increased Risk to Women. Patterns, 1(7):100108, 2020. DOI 10.1016/j.patter.2020.100108 — AwareDX:揭示报告数据性别偏倚并建立性别特异风险库。
  6. Tanaka Y, Tatonetti N 等. OnSIDES (ON-label SIDE effectS resource) Database. medRxiv, 2024. DOI 10.1101/2024.03.22.24304724 — NSIDES 家族向说明书标签 NLP 的扩展。
  7. Vilar S, Friedman C, Hripcsak G. Detection of drug-drug interactions via data fusion. J Cheminform, 2012-2013 系列 — 化学相似度路线与 TWOSIDES 的早期交叉验证。

§8.6 社区活跃度

维度 状态
引用规模 原始论文 Semantic Scholar 911+ 次(截至 2026-09),药物警戒机器学习方向的高被引基础设施
代码生态 官方 tatonetti-lab/nsides-release(数据 + 建库脚本);R 生态 dbparser 官方适配;Decagon 基准由 SNAP 长期托管
机构延续性 Tatonetti Lab 从斯坦福 → 哥伦比亚 → Cedars-Sinai 持续维护资源页,NSIDES 家族持续扩展并被 KG Hub 收录为标准数据源
基准热度 TWOSIDES 是 2018-2026 年几乎全部 DDI 副作用预测论文的标准评测集之一(Decagon/DeepDDI/SumGNN/SkipGNN/KGNN/DCSE/DDINet 谱系)
数据更新 官方推进 2022+ 数据更新与季度发布计划(截至 2026-09 信息,见 KG Hub 收录页

§8.7 生态快照

资源 类型 链接 Star/规模(截至 2026-09) 推荐理由
tatonetti-lab/nsides-release 官方数据+代码仓库 GitHub 数据 v0.1,含全部建库脚本 一站式获取可复现管线
Decagon 数据页 基准数据托管 snap.stanford.edu/decagon 4 文件标准基准 排行榜对齐的唯一选择
dbparser (rOpenSci) R 解析库 文档 CRAN 正式包 R 用户开箱即用
KG Hub: nsides 收录 知识图谱注册表 收录页 NSIDES 全家族索引 追踪 KidSIDES/ManySIDES 更新
Tatonetti Lab 资源页 官方资源索引 Cedars-Sinai 全部资源免费开放 官方许可与引用要求的权威出处

§9 相关资源与引用

§9.1 官方资源

§9.1b 教程与延伸阅读

  • NSIDES 项目主页与在线浏览nsides.io(Tatonetti Lab 官方平台入口,见 KG Hub 收录页
  • OnSIDES 浏览器(说明书标签 NLP 扩展)onsidesdb.org
  • 方法学入门:原论文 Methods 一节是自发报告信号检测(PRR + 倾向匹配 + SCRUB)最完整的公开教学材料,适合作为药物警戒信号检测的入门读物
  • 基准入门:Decagon 论文 + 其公开数据处理脚本,是理解"TWOSIDES 如何变成图基准"的标准路径
  • 药物警戒方法论:FAERS 官方文档(FDA FAERS 公开页面)解释原始报告字段与上报流程,是自建时序划分的前置知识

§9.2 BibTeX 引用

@article{tatonetti2012data,
  title   = {Data-Driven Prediction of Drug Effects and Interactions},
  author  = {Tatonetti, Nicholas P. and Ye, Patrick P. and Daneshjou, Roxana and Altman, Russ B.},
  journal = {Science Translational Medicine},
  volume  = {4},
  number  = {125},
  pages   = {125ra31},
  year    = {2012},
  month   = {3},
  doi     = {10.1126/scitranslmed.3003377},
  pmid    = {22422992},
  pmcid   = {PMC3382018}
}

@article{zitnik2018modeling,
  title   = {Modeling polypharmacy side effects with graph convolutional networks},
  author  = {Zitnik, Marinka and Agrawal, Monica and Leskovec, Jure},
  journal = {Bioinformatics},
  volume  = {34},
  number  = {13},
  pages   = {i457--i466},
  year    = {2018},
  doi     = {10.1093/bioinformatics/bty294}
}

§9.3 引用指南

使用 TWOSIDES 数据本身必须引用 Tatonetti et al. 2012;使用 964 类基准划分或其多模态图必须同时引用 Zitnik et al. 2018;使用 NSIDES v0.1 的更新数据建议同时注明该 release(2019-11,FAERS 至 2014)。若采用了 OFFSIDES 过滤或 SCRUB 相关方法细节,引用同一原始论文即可。发表于临床试验或监管文档的结果,请额外附上"自发报告统计信号、未经前瞻验证"的限定语。

引用场景速查:

使用内容 必引文献 建议附注
原始关联数据(任一版本) Tatonetti et al. 2012 注明所用版本与下载日期
964 类基准划分 / 多模态图 Zitnik et al. 2018 + Tatonetti et al. 2012 注明随机划分协议与负采样率
OFFSIDES 过滤口径 Tatonetti et al. 2012 注明两档关联的处理方式
SCRUB / PRR 方法学 Tatonetti et al. 2012 注明匹配参数(1:10、6 箱)
NSIDES v0.1 重建数据 Tatonetti et al. 2012 + release(2019-11) 注明 FAERS 截止 2014

§10 AI 使用声明卡

§10.1 本页制作使用的 AI 模型列表

  • 大语言模型:CodeBuddy(fast-model)——全文起草、结构编排、代码示例生成。

§10.2 AI 参与范围

工作项 AI 参与方式 人工介入点
事实检索与核实 汇总多次 WebSearch 结果与官方文档 逐数字对照原始来源复核
全文初稿 起草全部章节 结构与口径调整
代码示例 生成并冒烟验证语法 数据路径与口径确认
表格与 BibTeX 整理自来源文献 DOI/PMID 逐字段核对
DAIMS 裁定 依据证据提出初判 24 项逐项终审

AI 负责初稿撰写、代码示例与表格整理;全部事实性数字(规模、基准、统计、日期)均来自 §10.3 所列公开来源并由交叉核对流程约束;最终内容经人工编辑审核(见 §10.4)。

§10.3 输入来源列表

  1. Tatonetti NP, Ye PP, Daneshjou R, Altman RB. Data-Driven Prediction of Drug Effects and Interactions. Sci Transl Med, 4(125):125ra31, 2012. DOI 10.1126/scitranslmed.3003377(PubMed
  2. 论文全文(开放获取):PMC3382018
  3. Tatonetti Lab 官方资源页(TWOSIDES/OFFSIDES 规模数字与下载):tatonettilab.org/resources/tatonetti-stm.html
  4. NSIDES v0.1 release notes(13 列字段、PRR 方法、更新至 FAERS 2014):GitHub nsides-release
  5. NSIDES v0.1 Releases 页(显著三元组 5,729,992 等汇总统计):GitHub Releases
  6. Zitnik M, Agrawal M, Leskovec J. Modeling polypharmacy side effects with graph convolutional networks. Bioinformatics, 34(13):i457–i466, 2018. DOI 10.1093/bioinformatics/bty294(Decagon
  7. Decagon 基准数据页:snap.stanford.edu/decagon
  8. Rao J 等. Comprehensive evaluation of deep and graph learning on drug-drug interactions prediction. Briefings in Bioinformatics, 2023. DOI 10.1093/bib/bbad235(汇总评估
  9. DCSE: Robust prediction of drug combination side effects. bioRxiv, 2025. DOI 10.1101/2025.10.16.682750(预印本
  10. Deac A 等. Drug-Drug Adverse Effect Prediction with Graph Co-Attention. arXiv:1905.00534, 2019(论文
  11. DrugPred: EdgeConv-GNN polypharmacy ADR prediction. Frontiers, 2024(论文,含 limitations 与偏倚讨论)
  12. Tatonetti Lab 资源页(许可声明与 NSIDES 家族):Cedars-Sinai
  13. KG Hub nsides 收录页(家族成员与更新计划):kghub.org
  14. dbparser::parseTWOSIDES 文档(字段拼写与 R 适配):rOpenSci
  15. Semantic Scholar API(引用数 911,截至 2026-09):api.semanticscholar.org

§10.4 人工校验记录

内容模块 审核者 审核方式 审核状态
§1 概览与规模数字 千方病案医学编辑部 对照官方资源页与论文逐数核对 ✅ 已通过
§2 医学背景与 QT 案例 千方病案医学编辑部 对照 PMC 论文原文核对统计量 ✅ 已通过
§3-§4 规格、字典与目录树 数据工程师 对照 nsides-release v0.1 字段表核对 ✅ 已通过
§5 划分与泄漏分析 数据工程师 对照 Decagon/DCSE/DDINet 协议核对 ✅ 已通过
§6 代码与 8 坑点 数据工程师 代码冒烟运行;坑点逐条溯源官方文档/论文 ✅ 已通过
§7 DAIMS 与偏倚分析 千方病案医学编辑部 24 项逐项裁定与评分复核 ✅ 已通过
§8 基准与生态 数据工程师 排行榜数字全部锚定到引用来源 ✅ 已通过
§9-§10 引用与声明卡 千方病案医学编辑部 BibTeX 逐字段核对 DOI/PMID ✅ 已通过

§10.5 AI 生成章节标注

除 §0 审核声明、§10.4 人工校验表外,全部章节初稿由 AI 生成后经人工审核修正发布。

§10.6 最后人工审核日期

2026-09-05(与 §0 审核日期一致)。

页面状态:published(全部内容已完成审核并发布)

返回 AI-Ready 数据集