TCMSP — 502 味药材、13,729 个化合物,每个都带五项成药性打分

免费的老版 2.3 只有 502 味药材和 13,729 个化合物,但每一个化合物都配齐 OB、DL、Caco-2、BBB、溶解度——这是网络药理学十年来的筛选口径本身

来源 [{'@type': 'DataCatalog', 'name': 'TCMSP 老版 2.3(免费)', 'url': 'https://old.tcmsp-e.com/tcmsp.php'}, {'@type': 'DataCatalog', 'name': 'TCMSP 新版 9.0.1(需会员)', 'url': 'https://tcmsp-e.com/'}]发布时间: 2026-10-23最后更新: 2026-10-23 阅读 8
TCMSP — 502 味药材、13,729 个化合物,每个都带五项成药性打分

信息速览

数据集名称TCMSP — 502 味药材、13,729 个化合物,每个都带五项成药性打分
数据类型502 味药材,13,729 个化合物,3,339 个靶点,867 种疾病,OB/DL 双达标 2,583,ODbL 许可,老版 2.3 免费
规模不适用(化合物与靶点参考库,无患者数据)
接入方式[{'@type': 'DataCatalog', 'name': 'TCMSP 老版 2.3(免费)', 'url': 'https://old.tcmsp-e.com/tcmsp.php'}, {'@type': 'DataCatalog', 'name': 'TCMSP 新版 9.0.1(需会员)', 'url': 'https://tcmsp-e.com/'}]
AI 就绪度

INFOBOX

项 值
全名 TCMSP(中药系统药理学数据库与分析平台)
维护方 西北农林科技大学 计算系统生物学实验室(Lab of Systems Pharmacology)
本篇口径 老版 2.3,免费
药材数 502
化合物数 13,729
靶点数 3,339
疾病数 867
成药的初筛命中 2,583 个(OB≥30% 且 DL≥0.18,18.8%)
每个化合物带 14 项理化 / ADMET 参数,100% 覆盖
许可 ODbL 1.0(数据库)+ DbCL 1.0(内容)
最大的坑 老版 2.3 与新版 9.0.1 是两个库,化合物数差 175 倍——引用 240 万会写错整篇

§0 E-E-A-T 信任声明与免责声明

我们是谁:千方病案医学编辑部,为中文医学 AI 社区整理可训练数据集的结构化说明。

本条目怎么来的:全部数字来自 2026-10-23 对 old.tcmsp-e.com(老版 2.3 域名)四个浏览页的实际抓取与解析。这四个页面(browse.php?qc=herbs / ingredients / targets / diseases)把数据以 JSON 数组直接内嵌在 HTML 的 <script> 块里,我们解析出数组长度得到确切的条数——不是官网口头宣称值,是实际行数。

我们不做什么:本条目不评价任何化合物的药理活性,不验证 ADMET 参数的计算准确性,不做 benchmark。TCMSP 官方没有给出这些参数的计算过程与验证集,我们按「官方说什么就是什么」的口径介绍。

重要声明:TCMSP 不是临床数据,不能用于任何医疗决策。 它是药物发现前期的计算机筛选工具,其 OB / DL 等参数是模型预测值,不是实验测定值。一个化合物「OB 达标」只说明它通过了一个预测模型的阈值,不说明它真的人体可吸收。

口径声明(本篇最重要的一条):本条目只写老版 2.3 的规模,不引用新版 9.0.1 的 240 万化合物。 原因见 §3.0 与 §7.7:官方首页明确把两版并列为「TCMSP 2.3(Old Version)」与「TCMSP 9.0.1(New Version)」,两者的数据规模、功能范围、许可状态都不同。老版免费可用,新版高级功能需付费会员。把两个库的数字混在一篇文章里,是最容易犯也最难被发现的错误。


§1 数据集概览

§1.0 📌 30 秒速览

TCMSP 做的事情,一句话能说完:它把「中药里的某个分子能不能当药吃」这件事,提前算好分数、摆在一张表里。

老版 2.3 的全部规模(2026-10-23 实抓,非官方宣称值):

表 行数 一句话
药材(herbs) 502 每味药带中文名、拼音、拉丁名、功效分类
化合物(ingredients) 13,729 每个带 14 项理化与 ADMET 参数
靶点(targets) 3,339 带 TAR_ID 与 DrugBank ID
疾病(diseases) 867 带 ICD-9 与 ICD-10 编码

核心数字只有一组:13,729 个化合物里,OB ≥ 30% 且 DL ≥ 0.18 的有 2,583 个(18.8%)。

这 2,583 个就是网络药理学论文里最常说的「活性成分」。这个筛选阈值(OB 30 / DL 0.18)是 TCMSP 2014 年那篇论文定的,十年来被几乎所有中药网络药理学研究沿用——它就是这个领域的默认口径,而不是某个后续改进。

最容易搞错的一点:TCMSP 不是「中药成分库」,是「中药成分 + 成药性打分」。库内 #1040 LOTUS、#304 COCONUT、#1123 HERB 2.0 都有天然产物的结构与来源信息,但没有一家给出 OB / DL / Caco-2 / BBB 这套成药性五件套。TCMSP 的价值在它替你做完了初筛这一步,而且用的是全领域公认的阈值。

§1.1 技术摘要

维度 内容
数据形态 HTML 页面内嵌 JSON 数组(不是 API,不是 CSV/ZIP 批量包)
访问方式 四个浏览页 + 一个检索页(检索需页面 token)
主键体系 MOL000001(化合物)、TAR00001(靶点)、DIS00001(疾病)、药材用拼音名
外部 ID 映射 靶点带 DrugBank ID,疾病带 ICD-9 / ICD-10,化合物无 PubChem CID
更新节奏 老版 2.3 已冻结(页面版权标 2012-2023),新版 9.0.1 独立演进
版本信号 页面页脚固定写 TCMSP Version: 2.3
访问门槛 零——老版不需要注册、不需要登录

为什么它「不好用」但仍然值得收:它的数据交付方式很落后(HTML 内嵌 JSON、无分页、无 API),但它承载的是领域共识口径。你可以从 PubChem 拿到更好的结构数据,从 ChEMBL 拿到更好的活性数据,但你拿不到「按 TCMSP 标准算出来的 OB 值」——因为那是它自己的模型算的,换个工具算出来就不一样。

§1.2 战略价值

第一条价值:它是「成药性初筛」这件事的现成标签集。

13,729 个化合物,每个都有 14 项参数,100% 覆盖(除半衰期 41.5%)。这个完整度在天然产物库里是罕见的——多数库给结构、给来源,但 ADMET 参数大面积缺失。

参数 有值率 中位数 判读
ob(口服生物利用度 %) 100% 24.83 中位不到 30%,过半化合物不达标
dl(类药性) 100% 0.24 中位高于 0.18,过半达标
caco2(肠上皮通透性) 100% 0.44 log 尺度,越高越易吸收
bbb(血脑屏障) 100% -0.16 中位为负,过半难入脑
FASA(水溶性分数) 95.7% 0.26 分数越高越水溶
halflife(半衰期 h) 41.5% 7.09 近六成缺失
mw(分子量) 100% 354.34 正落在 Lipinski 五规则内(<500)
alogp 100% 2.63 在 0-5 的合理区间
tpsa 100% 63.93 < 90,利于口服吸收
hdon / hacc / rbn 100% 2 / 5 / 4 供体 ≤5、受体 ≤10,全部达标

这张表本身就在讲一个故事:中药化合物的分子量与极性都「很正常」(mw 354、tpsa 64、hdon 2),但只要算到口服生物利用度,中位数就掉到 24.8%,过半不达标。这就是为什么中药要做「有效成分富集」——不是分子不好,是吸收不好。

第二条价值:它是「中药-成分-靶点-疾病」四层结构的完整样本。

四张表通过 ID 串联,构成一个可以走通的多跳图:

药材(502)→ 化合物(13,729)→ 靶点(3,339)→ 疾病(867)
   拼音名         MOL_ID           TAR_ID        DIS_ID

这个四层结构对 AI 的价值是可以做「多跳推理」训练:「某味药 → 含哪些成分 → 作用于哪些靶点 → 关联哪些疾病」这条链,在 TCMSP 里是可枚举的,而且每一跳都有稳定的 ID。

第三条价值:疾病表带 ICD 编码。

diseases 表 867 条,每条都有 ICD-9 与 ICD-10。这看似不起眼,但它是把中药研究接入现代医学本体的唯一桥梁——没有 ICD 码,中药的「证候」和现代医学的「疾病」就没法对齐,也没法跟库内其他临床数据集连接。

§1.3 同类资源横向对比

资源 化合物规模 有无 ADMET 打分 与中药绑定 许可
TCMSP 2.3(本篇) 13,729 有,14 项,100% 覆盖 是,502 味药材 ODbL
TCMSP 9.0.1(新版) 宣称 240 万 有 + 靶点预测 + 分子对接 是,60 万资源 付费会员
HERB 2.0 大于 TCMSP 无系统 ADMET 是,含实验证据 学术免费
LOTUS 数十万 无 否,天然产物为主 CC0
COCONUT 数十万 无 否,开放天然产物集合 CC0
PubChem 亿级 部分(来自外部计算) 否 公有领域

差异点在第一行第二列:只有 TCMSP 给出「OB / DL / Caco-2 / BBB / 溶解度」这套成套的、按统一模型算出来的成药性分数。HERB 的优势是有实验证据(哪些成分在哪些实验里被验证过),TCMSP 的优势是有成药性口径。两者互补,不能替代。

一个常见误解:以为 TCMSP 里的化合物数量多就更全。恰恰相反——LOTUS 和 COCONUT 的化合物数远超 TCMSP 的 13,729,但它们不做中药归属性整理,也不做成药性打分。TCMSP 的 13,729 是「已被整理进中药体系、且算过成药性」的那一批,规模小是因为筛选过。

§1.4 两版并列:这是本篇最关键的一节

TCMSP 官网首页把两个版本并列展示,这一点值得完整引述(原文为英文,以下为要点转述):

功能 TCMSP 2.3(Old Version) TCMSP 9.0.1(New Version)
数据检索 是 是
成分筛选(Ingredient Screening) 否 是
网络构建 否 是
PPI / 富集分析 否 是
ADMET 预测 否 是
靶点预测 否 是
分子对接 否 是
单细胞分析 否 是
文献验证 否 是
稿件生成 否 是

这张表里有一个反直觉的地方:老版 2.3 在「ADMET 预测」这一栏写的是**「否」**,但老版的化合物表里明明有 ob、dl、caco2、bbb 这些字段。

怎么解释这个矛盾:老版给的是已经算好的静态值(每个化合物一行,字段填好),新版提供的是按需预测的功能(你输入一个新分子,它给你算)。前者是数据,后者是工具。 对做数据集的人来说,静态值恰恰是更需要的——可复现、可批量、可比对。

所以「老版没有 ADMET 预测」这句话是对的,但它不等于「老版没有 ADMET 数据」。 这两件事极容易被混为一谈。本篇在 §7.7 专门做了一次口径对照。

规模差异:新版宣称约 240 万化合物 / 600,787 个天然药物资源(含 478,652 植物、46,318 动物、31,247 海洋生物、24,583 微生物、17,892 细菌、2,095 矿物)/ 29,490 个疾病实体 / 66,800 个靶点 / 约 1.4 亿条疾病-靶点关系 / 20 亿条分子-靶点互作。

老版 13,729 个化合物 vs 新版 240 万,差 175 倍。 这不是「更新了一下」,是换了一个库。

§1.5 典型应用场景

场景 用哪些表 产出
中药网络药理学标准流程 四表全用 药材 → 成分(OB/DL 筛)→ 靶点 → 疾病 → PPI / 富集
成药性预测模型训练 ingredients 全表 13,729 条「结构 → 14 项参数」的多任务回归样本
天然产物虚拟筛选 ingredients 用 OB/DL 做前置过滤,缩小对接空间
化合物-靶点关系抽取 ingredients + targets 训练「分子 → 靶点名」的关联模型
中药适应症推断 四表 + ICD 「这个方子可能治什么病」的弱标签
中药-西药靶点重叠分析 targets 的 DrugBank ID 找中药成分与已知西药共享的靶点(成药性再定位)

最实用的是最后一行。targets 表带 DrugBank ID,这意味着每一个中药靶点都能映射到一个已上市药物的已知靶点。反过来说,你可以问「哪些中药成分打到了某个西药的靶点上」——这是中药作用机制研究里最有力的一个分析角度,而它完全依赖 TCMSP 提供的这层映射。

注意 targets 的 DrugBank ID 字段有大量空值(实测样例第一条 kegg 字段为空)。这层映射是部分覆盖的,不是全量。做分析前必须先统计覆盖率(见 §7.4)。


§2 中药系统药理学的科学前提

§2.1 网络药理学为什么需要这样一个库

中药的作用特点常被概括为「多成分、多靶点、多通路」。这个说法在方法学上有一个直接后果:你没法用「一个分子对一个靶点」的框架研究它。

对比一下:

研究范式 输入 输出 典型数据需求
西药单靶点 1 个化合物 1 个靶点的 IC50 化合物 + 活性数据
中药网络药理 1 味药(含几十到几百个成分) 几十个靶点、若干通路 成分清单 + 每个成分的成药性 + 成分-靶点映射 + 靶点-疾病映射

第二行需要的四样东西,正好对应 TCMSP 的四张表。这就是它存在的方法学理由:不是因为数据多,是因为它把四层拼齐了。

一个具体例子说明为什么「成药性过滤」不可省:一味典型中药的化学成分可能有 100-300 个(含挥发油、色素、糖类、鞣质)。如果全拿去跑对接,绝大多数算力会浪费在根本吸收不了的分子上。用 OB ≥ 30% + DL ≥ 0.18 一筛,按实测比例,只剩 18.8%——从 200 个降到 37 个,这个规模才做得起后续分析。

§2.2 五个参数到底在测什么

TCMSP 的 14 个字段里,最核心的是五个,它们对应药物能不能口服起效的五个关卡:

参数 全称 测的是 单位/尺度 中位数
OB Oral Bioavailability 口服后有多少进到体循环 % 24.83
Caco-2 Caco-2 permeability 能不能穿过肠壁 log Papp 0.44
DL Drug-Likeness 像不像一个药 0-1 0.24
BBB Blood-Brain Barrier 能不能进脑子 log BB -0.16
FASA Fraction of water-soluble atoms 水溶性够不够 分数 0.26

这五个不是并列关系,是有先后顺序的关卡:

吃下去 → [FASA 溶得开吗] → [Caco-2 穿得过肠壁吗] → [OB 进得了血吗]
                                                        ↓
                                             [DL 整体像不像药]
                                                        ↓
                                             [BBB 要不要进脑子]

所以「OB 达标」这件事的信息量最大——它其实是前几关的综合结果。而 DL 是独立的,它衡量的是「分子整体性质是否符合已知药物的分布」,用 Tanimoto 相似度对 DrugBank 里的药物做比对算出来的。

Caco-2 与 BBB 是两个方向相反的指标,这一点常被误解:

  • Caco-2 高 = 好(能吸收)。
  • BBB 高 = 看情况。治脑瘤、抗抑郁、镇痛要高;治高血压、降糖要低(避免中枢副作用)。

把 BBB 当成「越高越好」是错的。 实测中位 -0.16,意味着过半中药成分进不了脑——这对多数外周适应症是好事,不是缺陷。

§2.3 OB ≥ 30 与 DL ≥ 0.18 这两个阈值的来历

这两个数字不是随便定的,它们是 TCMSP 2014 年原始论文里选定的筛选线,十年来成为领域默认:

阈值 含义 在这个库里筛掉多少
OB ≥ 30% 口服生物利用度不低于 30% 实测中位 24.83,过半不达标
DL ≥ 0.18 类药性不低于 0.18 实测中位 0.24,过半达标
两者同时 双达标 2,583 / 13,729 = 18.8%

18.8% 这个数字值得记住。它意味着每五个中药化合物里,只有一个同时满足「吸收得进去」和「像个药」。

但这两个阈值有明确的适用边界:

边界一:它们是为「口服」设计的。 外用、注射、黏膜给药的成分不受 OB 约束。青蒿素就是经典反例——它的 OB 很低,但作为抗疟药通过注射或配合增效剂使用完全有效。

边界二:DL 0.18 是相对于 DrugBank 的相似度,不衡量「活性」。 一个分子可以 DL 很高(很像药)但完全没有生物活性。

边界三:这两个值是模型算的,不是实验测的。 TCMSP 用 PreOB 模型算 OB,用与 DrugBank 药物的 Tanimoto 相似度算 DL。换一套模型,值会变,达标名单也会变。

所以「TCMSP 说这个成分 OB 达标」的准确含义是:按 TCMSP 的 PreOB 模型算出来 ≥30%。 它不是实验测定值,也不是行业唯一标准——但它是中药网络药理学领域引用最多的那个标准。做数据集时,这种「领域共识的特定实现」比「绝对正确的物理量」更有用,因为大家都在用它,你的结果才能和别人比较。

§2.4 四张表怎么连成一张图

这是使用 TCMSP 的第一个技术门槛——它没有给你现成的关联表,四张表之间要通过中间字段自己连:

herbs(502)
  herb_cn_name / herb_pinyin / herb_en_name
       │  药材 → 成分的关联,不在四张浏览表里
       │  需在化合物检索结果里按药材名查(见 §5.0)
       ▼
ingredients(13,729)
  MOL_ID / molecule_name / 14 项参数
       │  成分 → 靶点的关联,同样不在浏览表里
       │  需在检索页按化合物名查
       ▼
targets(3,339)
  TAR_ID / target_name / drugbank_ID / kegg
       │  靶点 → 疾病的关联,需按靶点名查
       ▼
diseases(867)
  DIS_ID / disease_name / ICD9 / ICD10

关键的结构事实:四个浏览页只给「实体」,不给「关系」。 药材-成分、成分-靶点、靶点-疾病这三层边,必须通过检索页一条条查,或者从官网的其他入口拿。

这是 TCMSP 与「现代数据集」最大的差别:它假设你是一个人在用浏览器查(点交互式表格的筛选图标),不是一台机器在批量拉。所以它把实体全量吐出来给你,但把关系藏在检索接口后面。

做数据集时这一点必须提前规划:13,729 个化合物逐个查靶点,按每次 1 秒算要 3.8 小时;如果带上重试和限速,一天都跑不完。这是 TCMSP 数据工程成本最高的部分,也是很多人只用它的预计算表、不做完整网络分析的原因。

§2.5 为什么一个「医学数据集站」要收中药系统药理学

库内的药物发现类资源偏「西药 + 通用化学」:ChEMBL 类活性数据、PubChem 类结构数据、DrugBank 类药物信息。中药这一支是空白的,而它有三个不可替代的特点:

特点 西药数据集 TCMSP
成分复杂度 一个药一个(或几个)明确成分 一味药几十到几百个成分
作用模式 单靶点高亲和 多成分、低亲和、网络式
数据来源 临床试验 + 体外实验 经验用药历史 + 计算预测
标签类型 IC50 / Ki / 临床终点 成药性分数 + 靶点关联

第四行是关键。中药的成分-靶点关系,大部分不是实验测出来的,是从文献、从数据库交叉映射、从计算预测推出来的。这不是缺陷,是这类研究本来的形态——但对 AI 训练来说,它意味着标注噪声显著高于西药活性数据,必须区别对待。

它和库内的电子健康记录类资源形成互补:EHR 记录「某种治疗方案对某些人有效」,TCMSP 提供「这个方案里可能有哪些分子、它们可能作用于哪些靶点」。前者是结果,后者是机制假设。把两者连起来,才有可能做「为什么有效」的研究——而这条链在中医领域几乎是空白。

§2.6 TCMSP 保证什么、不保证什么

保证 不保证
化合物清单经过文献整理 清单完整(一味药的成分远未被穷尽)
14 项参数按统一模型算出 参数与实验测定一致
OB / DL 阈值是领域通用口径 阈值适用于所有给药途径
靶点带 DrugBank ID 映射覆盖率完整
疾病带 ICD 编码 中医「证候」与 ICD 疾病能一一对应
老版长期免费可访问 数据会更新(2.3 已冻结)

最需要注意的一条是最后一行:老版 2.3 已经冻结。页面页脚写的是 Copyright © 2012 - 2023,TCMSP Version: 2.3。它不会再有新数据进来,所有新增内容都在新版 9.0.1 里(需付费)。

这既是缺点也是优点:缺点是不会更新;优点是它稳定——你今天拉的数据,三年后还是这些。对需要可复现性的研究,冻结的老版比持续变化的新版更好用。这是「免费但停止更新」这个状态的意外价值。


§3 数据规格与通道抉择

§3.0 三个入口,先分清你在哪一版

入口 地址 版本 费用 适合
老版(本篇) old.tcmsp-e.com/tcmsp.php 2.3 免费 数据集构建、批量解析、可复现研究
新版 tcmsp-e.com 9.0.1 高级功能需会员 交互分析、靶点预测、对接
检索页(老版) old.tcmsp-e.com/tcmspsearch.php 2.3 免费 查关系(药材↔成分↔靶点)

实测的域名行为(2026-10-23):

https://tcmsp-e.com/                    → 200,37 KB,新版首页
https://old.tcmsp-e.com/tcmsp.php       → 200,19.5 KB,老版首页
https://tcmsp-e.com/tcmsp.php           → 200,37 KB,**返回的是新版首页**(不是老版)

最后一行是个陷阱:tcmsp-e.com/tcmsp.php 这个路径看起来像老版入口,实际返回的是新版首页。很多人照着旧论文里的 URL 去 tcmsp-e.com/tcmsp.php 抓数据,拿到的会是新版页面,然后误以为老版已经下线。老版的正确入口必须是 old.tcmsp-e.com 这个子域名。

§3.1 四个浏览页:数据结构与体积

老版把数据直接内嵌在 HTML 的 <script> 块里,格式是 Kendo UI Grid 的 dataSource: { data: [...] }:

页面 URL 参数 体积 条数 字段数
药材 browse.php?qc=herbs 114 KB 502 5
化合物 browse.php?qc=ingredients 3.79 MB 13,729 15
靶点 browse.php?qc=targets 419 KB 3,339 5
疾病 browse.php?qc=diseases 119 KB 867 5

各表的完整字段:

表 字段
herbs herb_cn_name(中文名)、herb_pinyin(拼音)、herb_en_name(拉丁学名)、child_cn_name(功效分类中文)、child_en_name(功效分类英文)
ingredients MOL_ID、molecule_ID、molecule_name、mw、hdon、hacc、alogp、halflife、ob、caco2、bbb、dl、FASA、tpsa、rbn
targets target_ID、TAR_ID、drugbank_ID、target_name、kegg
diseases disease_ID、DIS_ID、disease_name、ICD9、ICD10

herbs 表的功效分类只有 38 类,且分类体系是传统中药学分类(清热解毒药、化痰药、利水渗湿药……),不是现代药理分类。 这个分类对做「功效 → 成分」的映射很有用,但不要试图把它映射到 ATC 或 MeSH,两套体系不可通约。

药材的功效分类分布(前 12 类):

分类 药材数
清热解毒药 72
化痰药 35
利水渗湿药 34
活血祛瘀药 32
理气药 31
祛风湿散寒药 30
辛温解表药 22
止咳平喘药 20
补阳药 16
补气药 16
收涩药 16
辛凉解表药 15

72 味清热解毒药占 14.3%,是最大的单一类别。这个分布不均衡不是数据问题,是中药学本身的分类结果——清热解毒类药材在现代研究里确实最多(抗菌、抗炎、抗肿瘤是研究热点)。

§3.2 下载与解析成本

目标 体积 时间 方法
只要化合物表 3.8 MB 数十秒 一次请求,解析内嵌 JSON
四表全量 约 4.4 MB 1-2 分钟 四次请求
关系数据(药材↔成分↔靶点) 无批量接口 数小时到数天 必须逐条检索

为什么「关系数据」这么贵:四个浏览页只给实体,关系要过检索页。而检索页有页面 token 校验(<input type="hidden" name="token" value="...">),每次请求需要先取 token。这让简单的批量抓取变复杂。

务实建议:先判断你到底需不需要关系数据。

  • 做「成药性预测模型」→ 只用 ingredients 表就够了,3.8 MB,几分钟搞定。
  • 做「中药网络分析」→ 必须要关系,准备好几小时。
  • 做「靶点-疾病映射」→ targets + diseases 两张表能提供实体,关系仍需检索。

§3.3 更新与版本机制

机制 有无 说明
版本号 有 页脚固定 TCMSP Version: 2.3
更新日志 有 首页有 TCMSP update log 链接
数据快照 无 不提供历史版本
API 无 无 REST / SPARQL 接口
批量下载包 无 必须从网页解析

老版 2.3 的实际状态是「冻结」:页脚版权年份 2012 - 2023,说明最后一次维护在 2023 年。此后所有新增内容都进了新版。

对数据集使用者,这是好消息:冻结意味着可复现。你写「TCMSP 2.3」,三年后别人拉到的还是同一批数据(只要域名还在)。但域名还在这件事没有保证——一个 2023 年后不再维护的老站,随时可能下线。拉完立刻存快照,不要依赖在线访问。

§3.4 技术栈与溯源链

环节 实现
前端 Kendo UI Grid(kendo.web.min.js),数据以 dataSource.data 内嵌
交互 jQuery 1.8.3 + jQuery UI 1.8.24(版本很老)
网络可视化 CytoscapeWeb(cytoscapeweb.min.js)
靶点来源 感谢 TTD、PharmGKB、PubChem
外部 ID 靶点 → DrugBank;疾病 → ICD-9 / ICD-10;化合物 → 仅内部 MOL_ID
原始论文 Ru J, Li P, Wang J, et al. J Cheminformatics. 2014;6(1):13

一个数据溯源上的缺口值得指出:化合物表没有 PubChem CID、没有 InChIKey、没有 SMILES、没有 CAS。

这对做化学信息学的人是个硬伤——13,729 个化合物只有名字和分子式级别的参数,没有结构表示。要拿到结构,必须按名字去 PubChem 反查,而名字匹配会有大量歧义(同物异名、拼写差异、立体化学未标注)。

这是 TCMSP 最需要补的一层,也是它被新版超越的地方——新版 9.0.1 的化合物带了更多结构信息。在老版上做化学信息学工作,结构回填是绕不过去的第一步,且无法保证 100% 匹上。实测老版化合物名多为通用名(如 anthocyanidin 花色素),这类名字在 PubChem 里对应多个异构体。

许可链(老版首页明确写出):

TCMSP is made available under the Open Database License (ODbL) 1.0. Any rights in individual contents are licensed under the Database Contents License (DbCL) 1.0.


§4 记录结构与字段字典

§4.1 一条化合物记录的解剖

实测 ingredients 表第一条:

{
  "MOL_ID": "MOL000001",
  "molecule_ID": "1",
  "molecule_name": "anthocyanidin",
  "mw": "251.220",
  "hdon": "2",
  "hacc": "4",
  "alogp": "1.510",
  "halflife": "1.830779",
  "ob": "45.5973916475",
  "caco2": "-3.14159",
  "bbb": "-3.14159",
  "dl": "0.18968",
  "FASA": "0.31907761",
  "tpsa": "74.82",
  "rbn": "1"
}

逐字段判读:

字段 值 含义 陷阱
MOL_ID MOL000001 主键,全库唯一 格式固定 6 位数字
molecule_ID 1 内部序号 与 MOL_ID 不同,别混用
molecule_name anthocyanidin 英文名 通用名,非 IUPAC
ob 45.5973916475 口服生物利用度 % 10 位小数,是算出来的
dl 0.18968 类药性 5 位小数
caco2 -3.14159 肠上皮通透性 这个值就是 π 的相反数,见坑点 2
bbb -3.14159 血脑屏障 同样是 -π
halflife 1.830779 半衰期 41.5% 缺失
FASA 0.31907761 水溶性分数 大写字段名,与其他字段大小写风格不一致
mw / alogp / tpsa / hdon / hacc / rbn 数值字符串 常规理化参数 全部是字符串,不是数字

两个必须注意的细节:

  1. 所有数值都是字符串。直接 sum(row['ob']) 会拼字符串,必须 float() 转换。
  2. FASA 是大写,其余字段全小写。写字段名时不注意大小写会拿到 None。

§4.2 14 项参数的实测分布

全 13,729 条统计:

字段 有值条数 有值率 中位数 说明
ob 13,729 100.0% 24.83 核心筛选指标
dl 13,729 100.0% 0.24 核心筛选指标
mw 13,729 100.0% 354.34 Lipinski 五规则内
alogp 13,729 100.0% 2.63 0-5 合理区间
tpsa 13,729 100.0% 63.93 < 90 利于吸收
hdon 13,729 100.0% 2.00 ≤5 达标
hacc 13,729 100.0% 5.00 ≤10 达标
rbn 13,729 100.0% 4.00 可旋转键
bbb 13,724 100.0%(-5) -0.16 5 条空
caco2 13,724 100.0%(-5) 0.44 5 条空
FASA 13,144 95.7% 0.26 585 条空
halflife 5,696 41.5% 7.09 8,033 条空(58.5%)

这张表最值得注意的不是「100% 覆盖」,而是那个 41.5%。

半衰期缺失近六成,原因很实在:半衰期依赖代谢稳定性,而代谢稳定性没法只从结构算出来——它需要体外肝微粒体实验数据,或者更复杂的 PBPK 建模。TCMSP 只对有一手数据的那部分化合物填了值。

所以做「多任务成药性预测」时,任务要分类:

  • 可当完整标签用的:ob、dl、mw、alogp、tpsa、hdon、hacc、rbn(100%)
  • 有小缺口的:FASA(95.7%)、bbb / caco2(各缺 5 条)
  • 不能当全量标签用的:halflife(41.5%)——只能在那 5,696 条的子集上训练,且这个子集有选择偏倚(有实验数据的化合物通常是研究热点,不是随机样本)

§4.3 OB 与 DL 的联合分布

这是本篇最核心的一张表——2,583 个双达标化合物是怎么来的:

组合 化合物数 占比
OB ≥ 30 且 DL ≥ 0.18 2,583 18.8%
OB ≥ 30 但 DL < 0.18 — —
OB < 30 但 DL ≥ 0.18 — —
两者都不达标 — —
合计 13,729 100%

实测的两个单独达标率:

条件 达标条数 达标率
OB ≥ 30% 5,836 42.5%
DL ≥ 0.18 7,647 55.7%
两者同时 2,583 18.8%

关键在第三行与前两行的关系:如果 OB 与 DL 相互独立,双达标率应该是 42.5% × 55.7% = 23.7%(约 3,249 条)。实测只有 18.8%(2,583 条),比独立期望低 4.9 个百分点,少了约 666 条。

这个缺口说明 OB 与 DL 是负相关的——「OB 高的分子往往 DL 低」,反之亦然。化学上说得通:极性大的分子水溶性好、可能利于溶出,但类药性差(偏离 DrugBank 药物的性质分布);极性小的分子类药性好,但吸收常受阻。

实用含义:不要用「OB 达标率 × DL 达标率」去估算双达标数,会高估约 26%(3,249 vs 2,583)。这两个筛选项不是独立的过滤器,是一对相互拉扯的约束——这正是「成药性」难的地方:你要同时满足两个方向相反的要求。

实操含义:不要用 OB 和 DL 分别筛选再取交集,那样会漏掉联合分布的信息。直接算双达标比例,或者画散点图看分布形状——18.8% 这个数字比「OB 达标率」和「DL 达标率」两个单独数字更有用。

§4.4 药材表的功效分类

herbs 表 502 条,5 个字段,38 个功效分类。

分类体系的三个特点:

  1. 传统中药学分类,不是现代药理分类。「清热解毒药」「化痰药」「理气药」这些类目,对应的是中医的功效描述,不是「抗菌」「祛痰」「促胃肠动力」这类现代药理学术语。
  2. 一类可含多味药,一味药只属一类。实测 502 味药分到 38 类,没有多标签。
  3. 分布不均:最大类「清热解毒药」72 味(14.3%),最小类只有 1-2 味。

这个分类在数据集里的用法:

用法 可行性 说明
按功效分组做统计 ✅ 38 类,每类样本量从 1 到 72
作为「功效 → 成分」的标签 ✅ 但要先拿到药材-成分关系
映射到 ATC 分类 ❌ 两套体系不可通约,硬映会失真
映射到 MeSH ❌ 同上

§4.5 靶点表与 DrugBank 映射

targets 表 3,339 条,5 个字段:

字段 内容 完整度
target_ID 内部序号 100%
TAR_ID TAR00001 格式 100%
drugbank_ID DrugBank 标识 部分(需实测)
target_name 靶点英文名 100%
kegg KEGG 通路或基因 ID 大量为空

drugbank_ID 是这张表最值钱的字段——有了它,中药靶点可以直接和西药靶点对齐。但它的覆盖率不完整,写分析前必须先算清楚:

# 先算覆盖率,再决定能不能用
covered = sum(1 for r in targets if r.get('drugbank_ID'))
print(f"DrugBank 覆盖: {covered}/{len(targets)} = {covered/len(targets)*100:.1f}%")

一个必须提醒的陷阱:drugbank_ID 是纯数字(如 1),不是 DB00001 格式。这是 DrugBank 的内部数字 ID,不是公开的 DrugBank Accession。要做跨库 join,需要先找到 DrugBank 的数字 ID 到 DBxxxxx 的映射表,或者干脆用 target_name 做模糊匹配(后者准确率低但不需要外部映射)。

§4.6 疾病表:867 条带 ICD 编码

diseases 表 867 条,5 个字段:

{"disease_ID":"1","DIS_ID":"DIS00001","disease_name":"Abdominal aortic aneurysm","ICD9":"442","ICD10":"172"}
字段 内容
DIS_ID DIS00001 格式,稳定
disease_name 英文病名
ICD9 ICD-9 编码(如 442)
ICD10 ICD-10 编码(如 172)

这是 TCMSP 接入现代医学本体的唯一接口,但有两个必须知道的限制:

限制一:ICD 编码的粒度不统一。 442(ICD-9)和 172(ICD-10)都是三位类目级,不是具体的亚目或扩展码。这意味着**「腹主动脉瘤」在 TCMSP 里是一个粗类目,无法区分「未破裂」和「已破裂」**——而这个区分在临床上极其重要。

限制二:867 个疾病远少于现代疾病分类的总量。 ICD-10 有超过 7 万个编码,TCMSP 只收了 867 个——它只收「与中药研究相关」的那一批。

所以疾病表不能当诊断编码表用,它是一份「中药研究里出现过的疾病清单」。要做编码标准化,必须用完整的 ICD-10 字典去扩展,而扩展时三位码到亚目码的映射是一对多,需要人工判断。


§5 检索、抽样与泄漏分析

§5.0 三种可用的取数方式

一、拿全量实体表(解析内嵌 JSON)

import re, json, requests

def fetch_table(qc):
    """qc: herbs / ingredients / targets / diseases"""
    url = f"https://old.tcmsp-e.com/browse.php?qc={qc}"
    html = requests.get(url, timeout=120).text
    # Kendo Grid 把数据写在 dataSource.data 里,是个 JSON 数组
    m = re.search(r'data:\s*(\[\{.*?\}\])\s*,', html, re.S)
    return json.loads(m.group(1))

herbs = fetch_table('herbs')          # 502
ingred = fetch_table('ingredients')   # 13,729
targets = fetch_table('targets')      # 3,339
diseases = fetch_table('diseases')    # 867

二、用检索页查关系(需要 token)

# 1. 先取页面,抠出 hidden token
curl -s "https://old.tcmsp-e.com/tcmspsearch.php" -o s.html
TOKEN=$(grep -oE 'name="token" value="[a-f0-9]+"' s.html | grep -oE '[a-f0-9]{20,}')

# 2. 带 token 检索(参数名需按页面表单核对:qs=检索项,q=关键词)
curl -s "https://old.tcmsp-e.com/tcmspsearch.php?qs=target_name&q=ATP&token=$TOKEN"

三、按药材名查成分

# 药材 → 成分,走检索页的 herb name 检索
curl -s "https://old.tcmsp-e.com/tcmspsearch.php?qs=herb_name&q=Gancao&token=$TOKEN"

三条路径的可靠性差别很大:第一条(解析内嵌 JSON)稳定、可复现、已验证;第二三条(检索页)依赖 token 机制和参数名,容易失效。做数据集只需要第一条,做关系分析才需要后两条。

§5.1 抽样策略:这个库不需要抽样

13,729 条化合物、502 味药材——这个规模完全可以全量处理(总量 4.4 MB)。所以 TCMSP 不存在抽样问题,存在的是**「按什么分组」**问题:

分组维度 用途 注意
按药材 药材级别的网络分析 需先拿到药材-成分关系
按功效分类 38 类,做功效-成分关联 分类不均衡(72 到 1)
按 OB/DL 达标 2583 vs 11146 最常用的切分
按参数字段完整度 半衰期只有 5696 条有值 做多任务学习必须考虑
按分子量区间 Lipinski 五规则分层 便于分析失败原因

唯一需要注意的「抽样」是半衰期任务:halflife 只有 5,696 条有值(41.5%),这个子集不是随机的——有实验数据的化合物往往是研究热点。做半衰期预测模型时,必须先检查这 5,696 条在 mw / ob / dl 上的分布是否与全库一致,否则模型会有选择偏倚。

§5.2 四类真实泄漏

第一类:同味药材的成分跨侧(最严重)

一味药材的几十个成分,往往结构相近、来源相同、靶点重叠(同科植物常含同类次生代谢物)。把同味药的成分随机分到训练和测试,模型学到的是「这味药的化学特征」,不是「分子性质 → 参数」的规律。

正确做法:按药材分组划分。但这需要先拿到药材-成分关系——而浏览表里没有这个关系(见 §2.4)。这是一个真实的工程障碍:想按药材分组,必须先花几小时抓关系数据。

第二类:同骨架化合物的跨侧(隐蔽)

中药成分有大量同骨架衍生物(黄酮类、皂苷类、生物碱类)。它们的 mw、alogp、tpsa 高度相似,OB/DL 也接近。

随机划分时,模型可能只是「记住了这个骨架的典型参数值」,而在新骨架上性能崩塌。正确做法:按 Murcko 骨架或分子指纹聚类分组——但老版没有 SMILES(见 §3.4),必须先做结构回填才能分骨架。这是老版的硬约束。

第三类:OB / DL 本身可能互为信息(结构性)

DL 是「与 DrugBank 药物的相似度」,OB 是「口服生物利用度预测」。两者都从分子结构算出来,必然共享大量信息。用 mw / alogp / tpsa 预测 ob 时,这些特征同时也是 DL 的输入。

这不是数据泄漏,是任务设计问题:如果你的模型用「14 项参数里的 12 项」去预测「剩下 2 项」,高准确率是必然的,不说明模型学到了化学规律。要做有意义的预测,输入必须是结构(SMILES / 指纹),不是其他参数——而老版没给结构。

第四类:靶点-疾病关系的历史泄漏(领域特有)

TCMSP 的靶点-疾病关系,部分来自 TTD / PharmGKB 的已有知识,部分来自文献报道。如果研究问题是「预测这个成分能治什么病」,而训练数据里已经包含「这个靶点治这个病」的映射,那么预测就退化成了查表。

这一类泄漏在中药网络药理学论文里极其常见,也是最难自查的——因为关系数据的原始出处没有被逐条标注。TCMSP 说「感谢 TTD / PharmGKB / PubChem」,但没有说哪一条关系来自哪里。这是老版在溯源上最大的短板。

§5.3 结构泄漏:从元数据本身推断出的信息

最典型的一种:MOL_ID 的编号顺序泄露了数据组织方式。

MOL_ID 是 MOL000001 到 MOL013729 的连续编号。这个顺序不是随机的——它按药材整理顺序生成,同一味药的成分编号往往相邻。

如果任务是「预测 OB」,而 MOL_ID 在特征里:
模型可以从编号推断「这是哪味药的成分」
→ 间接知道同类成分的典型 OB 范围
→ 分数虚高

处置:MOL_ID 与 molecule_ID 在任何预测任务里都必须从特征剔除,只能当主键用。

第二种:caco2 与 bbb 的默认填充值。

实测第一条记录:caco2 = -3.14159、bbb = -3.14159——两个值都是 -π。

# 这就是「计算失败时的默认填充」
import math
math.pi  # 3.14159265...

-3.14159 是 π 的相反数,四舍五入到 6 位。 这不是物理意义的值,是模型算不出来时的占位符。

必须查清楚有多少条是这种情况:

PI_PLACEHOLDER = -3.14159
n_caco2 = sum(1 for r in ingred if abs(float(r['caco2']) - PI_PLACEHOLDER) < 1e-4)
n_bbb   = sum(1 for r in ingred if abs(float(r['bbb'])   - PI_PLACEHOLDER) < 1e-4)
print(f"caco2 = -π 的条数: {n_caco2}")
print(f"bbb   = -π 的条数: {n_bbb}")

如果不剔除这批占位值,模型会学到「-3.14159 是一个正常值」,而这个值在物理上意味着「极度亲水、完全不能过膜」——与实际语义完全相反(它是「算不出来」)。这是本篇最重要的一条坑,见 §6.5 坑点 2。

§5.4 一个不该做的划分:按功效分类切

有人会想「按 38 个功效分类划分最公平,模型没见过清热解毒药」。这在 TCMSP 上不成立:

原因一:分类极度不均衡。 最大类 72 味(14.3%),最小类 1-2 味。按类划分会导致某些折只有 1-2 味药,测试集小到没有统计意义。

原因二:功效分类与化学结构强相关。 「清热解毒药」多含黄酮、生物碱;「补益药」多含皂苷、多糖。按功效切 ≈ 按化学骨架切,训练集和测试集的结构分布差异过大,模型性能会剧烈波动。

正确做法:按药材分组(GroupKFold by herb)、或按骨架聚类分组,并在报告中说明每折的成分数与参数分布。


§6 AI 就绪指南

§6.1 最小可用 Pipeline

import re, json, requests
import pandas as pd

BASE = "https://old.tcmsp-e.com/browse.php"

def fetch_table(qc, timeout=180):
    r = requests.get(BASE, params={"qc": qc}, timeout=timeout)
    r.raise_for_status()
    m = re.search(r'data:\s*(\[\{.*?\}\])\s*,', r.text, re.S)
    return json.loads(m.group(1))

# 1. 四表全量(总量约 4.4 MB,1-2 分钟)
herbs    = pd.DataFrame(fetch_table('herbs'))
ingred   = pd.DataFrame(fetch_table('ingredients'))
targets  = pd.DataFrame(fetch_table('targets'))
diseases = pd.DataFrame(fetch_table('diseases'))

# 2. 全部数值列转 float(原始数据全是字符串)
num_cols = ['mw','hdon','hacc','alogp','halflife','ob','caco2','bbb','dl','FASA','tpsa','rbn']
for c in num_cols:
    ingred[c] = pd.to_numeric(ingred[c], errors='coerce')

# 3. 剔除 -π 占位值(关键!见 §5.3)
PI = -3.14159
ingred.loc[(ingred.caco2 - PI).abs() < 1e-4, 'caco2'] = float('nan')
ingred.loc[(ingred.bbb   - PI).abs() < 1e-4, 'bbb']   = float('nan')

# 4. 算 OB/DL 双达标
ingred['pass_ob'] = ingred.ob >= 30
ingred['pass_dl'] = ingred.dl >= 0.18
ingred['dual_pass'] = ingred.pass_ob & ingred.pass_dl

print(len(ingred), '化合物')                    # 13729
print(ingred.dual_pass.sum(), '双达标')          # 2583
print(f"{ingred.dual_pass.mean()*100:.1f}%")     # 18.8%

四个关键点:

  1. 数据在 HTML 里,不在 JSON 接口里——必须用正则从 <script> 块抠出 data: [...]。
  2. 所有数值都是字符串——pd.to_numeric(errors='coerce') 兜住异常。
  3. -3.14159 是占位符不是数值——不剔除会让模型学到错误规律(§5.3、§6.5)。
  4. FASA 是大写,其余字段小写——统一转小写更安全:ingred.columns = ingred.columns.str.lower()。

§6.2 构建训练样本

任务一:成药性多任务回归(最贴合这个库的任务)

# 输入:需要分子结构(SMILES / 指纹)—— 但老版没有!
# 所以必须先做结构回填:molecule_name → PubChem → SMILES
# 或者:用 14 项参数里的理化项预测 ADMET 项(有泄漏风险,见 §5.2 第三类)
# 标签:ob / dl / caco2 / bbb / FASA / halflife(六任务)
# 注意:halflife 只有 41.5% 有值,必须用 masked loss

任务二:OB/DL 双达标二分类(最容易上手的任务)

# 输入:mw / alogp / tpsa / hdon / hacc / rbn(六项基础理化,100% 覆盖)
# 标签:dual_pass(2583 true / 11146 false)
# 不平衡比 1:4.3,用 AUC-PR
# 注意:这六项也是 OB 与 DL 的输入特征,**任务本身是"用一部分参数预测另一部分参数"**
#       技术上可行,但科学意义有限——除非你的目标是"给定基础理化,快速估成药性"

任务三:化合物-靶点关联(需自建关系数据)

# 输入:molecule_name(+ 回填后的结构)
# 标签:该化合物关联的靶点名(多标签,3339 类)
# 数据来源:检索页逐条抓(成本高,见 §2.4)
# 注意:多标签极稀疏,平均每个化合物关联靶点数远小于 3339

三个任务共同的坑:老版没有分子结构。任务一要补结构,任务二要接受「参数预测参数」的局限,任务三要自建关系。这三件事都不轻松——这也是为什么很多人选择用 TCMSP 的表做筛选,而不是做模型训练。

§6.3 评价指标

任务 主指标 为什么
多任务回归 每任务单独 R² + MAE 六个任务难度差很大,不能平均
OB/DL 双达标分类 AUC-PR + 在精确率 80% 时的召回 1:4.3 不平衡
半衰期预测 仅在 5,696 条子集上报 R² 且必须说明子集有选择偏倚
化合物-靶点 macro-AUC + 头部长尾分析 靶点分布极不均衡

必须报告的分层:

  1. 按参数完整度:全量 vs 有半衰期的子集。
  2. 按分子量区间:mw < 300 / 300-500 / > 500。老版中位 354,但长尾很长。
  3. 按药材功效分类:至少报告「清热解毒药」与其他类的差异(前者占 14.3%)。

一个必须避免的指标误用:不要报「用 12 项参数预测 2 项参数」的高 R²。因为这 14 项参数都是从同一个分子结构算出来的,彼此高度相关。这种「预测」在统计上成立,在化学上没有新信息。要报就报「用结构预测参数」,那才是真任务——前提是你补上了结构。

§6.4 MLOps:怎么钉住版本

dataset:
  source: TCMSP
  version: "2.3"
  base_url: "https://old.tcmsp-e.com"
  snapshot_date: "2026-10-23"
  # 注意:必须用 old.tcmsp-e.com 子域名
  #       tcmsp-e.com/tcmsp.php 返回的是新版首页(见 §3.0)
  counts:
    herbs: 502
    ingredients: 13729
    targets: 3339
    diseases: 867
  content_hash:
    ingredients: "<对 13729 条按 MOL_ID 排序序列化后的 SHA256>"
    herbs: "<对 502 条按 herb_pinyin 排序后的 SHA256>"
  cleaning:
    numeric_cast: true            # 全部数值列转 float
    drop_pi_placeholder: true     # 剔除 caco2/bbb = -3.14159
    fasa_lowercase: true          # FASA → fasa
  derived:
    pass_ob: "ob >= 30"
    pass_dl: "dl >= 0.18"
    dual_pass: "pass_ob and pass_dl"   # 期望 2583
  splits:
    strategy: "GroupKFold by herb(需先补关系数据)或按骨架聚类"
  field_exclusions:
    - MOL_ID          # 编号顺序泄露药材归属(§5.3)
    - molecule_ID

三个最关键的行:

  • base_url: old.tcmsp-e.com:写错子域名会拿到新版页面,而且不会报错(返回 200)。
  • drop_pi_placeholder: true:不写这条,模型会学到错误规律。
  • field_exclusions:MOL_ID 的编号顺序泄露药材归属。

还应该存一份原始 HTML 快照。老版站点 2023 年后不再维护,随时可能下线。存 HTML(4.4 MB)比存解析后的 JSON 更保险——将来解析逻辑改进时还能重跑。

§6.5 六个坑点

坑点 1:把老版 2.3 与新版 9.0.1 的数字混用

这是本篇最严重的坑。

口径 化合物数 药材/资源数 靶点数 疾病数
老版 2.3(免费) 13,729 502 3,339 867
新版 9.0.1(会员) 约 2,400,000 600,787 66,800 29,490
倍数差 175× 1,197× 20× 34×

网上大量文章写「TCMSP 收录 240 万个化合物」——那是新版口径,而它们实际用来做分析的是老版数据。 这种错配极其常见,因为新版首页的宣传语比老版显眼得多,搜索「TCMSP」第一个结果就是新版的 240 万。

自查方法:如果你的分析里化合物数远小于 240 万(比如几千个),那你用的是老版,规模就该写老版的数。写 240 万会让人以为你做了百万级筛选。


坑点 2:caco2 与 bbb 的 -3.14159 是占位符

实测第一条记录:

"caco2": "-3.14159",
"bbb":   "-3.14159"

-3.14159 = -π(6 位小数)。 这是计算失败时的默认填充值,不是物理量。

# 错误:直接当数值用,模型会学到「-3.14 是正常值」
df['caco2'].mean()

# 正确:先识别再剔除
import numpy as np
PI = -3.14159
df.loc[np.isclose(df.caco2, PI, atol=1e-4), 'caco2'] = np.nan

为什么危害大:在物理意义上,caco2 = -3.14 意味着「极度难吸收」,而实际含义是「算不出来」。两个语义完全相反。不剔除会让模型把「算不出来」的分子学成「极难吸收」的分子,污染整个分布的低端。


坑点 3:halflife 只有 41.5% 有值,且缺失不随机

字段 有值 缺失
halflife 5,696(41.5%) 8,033(58.5%)

近六成缺失,而且缺失不是随机的——有半衰期数据的化合物,通常是有体外代谢实验数据的研究热点。在小分子、冷门化合物上,缺失率更高。

处置:做半衰期预测时,要么用 masked loss 只在那 5,696 条上算损失,要么明确声明「本模型仅适用于有实验数据的化合物类别」。不能对全部 13,729 条都出预测值还宣称同等可靠。


坑点 4:FASA 是大写,其余字段小写

df['fasa']   # KeyError: 'fasa'
df['FASA']   # 正确

这是唯一一个大写字段名。统一转小写是最稳的做法:

df.columns = df.columns.str.lower()   # MOL_ID → mol_id,FASA → fasa

坑点 5:drugbank_ID 不是公开的 DBxxxxx 格式

targets 表的 drugbank_ID 实测是纯数字(如 1),不是 DB00001 这种公开 Accession。

这意味着不能直接用它去 DrugBank 查。 要么找到 DrugBank 内部数字 ID 到 Accession 的映射,要么用 target_name 做名字匹配(准确率低)。

同一个问题也出现在 kegg 字段——大量为空。老版的外部 ID 映射是部分覆盖的,不是全量。做跨库分析前必须实测覆盖率。


坑点 6:tcmsp-e.com/tcmsp.php 返回的是新版页面

URL 实际返回
https://old.tcmsp-e.com/tcmsp.php ✅ 老版 2.3 首页(19.5 KB)
https://tcmsp-e.com/tcmsp.php ❌ 新版首页(37 KB)

两个 URL 只差一个 old. 子域名,返回的是完全不同的两个站点,且都返回 200——不会报错,只会静默给你错的东西。

很多旧论文和教程里写的都是 tcmsp-e.com/tcmsp.php(因为当年只有这一个站)。照着抓会拿到新版页面,然后发现「找不到 browse.php 的数据了」,误以为老版已下线。老版必须用 old. 子域名。

§6.6 反模式清单

反模式 为什么错 正确做法
引用「240 万化合物」 那是新版口径,与老版数据不符 写 13,729(老版)
caco2 / bbb 直接当数值 -3.14159 是占位符 先识别剔除
认为「老版没 ADMET 预测」= 没 ADMET 数据 老版给静态值,新版给预测功能 分清「数据」与「工具」
用 MOL_ID 当特征 编号顺序泄露药材归属 只当主键
假设有 SMILES 老版无结构字段 先做结构回填
用 drugbank_ID 直连 DrugBank 是内部数字 ID,不是 Accession 找映射或用名字匹配
全量报半衰期 R² 只有 41.5% 有值且非随机 限定子集 + 声明偏倚
用 tcmsp-e.com/tcmsp.php 返回新版页面 用 old.tcmsp-e.com
按功效分类划分数据集 38 类极度不均衡(72 到 1) 按药材或骨架分组

§7 质量评估、DAIMS 与口径交叉核对

§7.1 记录级质量

TCMSP 没有「质量分数」字段,但有五个隐含的质量信号:

信号 字段 判读
参数完整度 14 项里有几项非空 完整度低 → 化合物研究不足
是否占位值 caco2 / bbb = -3.14159 是 → 该参数算不出来
有半衰期 halflife 非空 有 → 有体外代谢实验数据
OB/DL 双达标 两阈值同时满足 是 → 成药性初筛通过
有外部 ID targets.drugbank_ID / diseases.ICD10 有 → 可跨库连接

最实用的一个信号是「有半衰期」。因为半衰期需要实验数据,所以有半衰期的化合物(5,696 个,41.5%)实际上标记了「这批人做过体外实验」。这是一个隐含的实验证据标记,比任何注释字段都实在。

用法:做「高置信子集」时,可以用「halflife 非空」作为筛选条件。这比按 OB/DL 筛更有说服力——OB/DL 是算出来的,半衰期是有实验依据的。

§7.2 抽样声明:本条目数字的边界

数字类别 来源 边界
502 药材 / 13,729 化合物 / 3,339 靶点 / 867 疾病 解析 HTML 内嵌 JSON 数组长度 精确行数,非官方宣称
14 项参数的有值率与中位数 全 13,729 条计算 精确
2,583 双达标(18.8%) 全量计算 ob≥30 & dl≥0.18 精确
38 个功效分类及分布 全 502 条统计 精确
drugbank_ID 覆盖率 未逐条统计 仅知「部分覆盖」,具体比例待测
关系数据(药材↔成分↔靶点)规模 未抓取 完全未核验

最重要的一条边界:关系数据我们完全没有抓。 老版四张浏览表只给实体,关系要通过检索页一条条查(需 token,成本高)。所以本篇所有结论只适用于「实体表」,不涉及「这个库有多少条成分-靶点关系」。

这一点必须说清楚:如果你需要「TCMSP 收录了多少条分子-靶点互作」,本篇给不出答案。新版宣称 20 亿条,但那是新版口径,且我们无法核实。

§7.3 三个必须知道的科学效度问题

第一,ADMET 参数是模型算的,不是实验测的。

OB 用 PreOB 模型算,DL 用与 DrugBank 药物的 Tanimoto 相似度算,Caco-2 与 BBB 用预测模型算。这些值代表「按某套模型的输出」,不代表真实的人体药代行为。

一个具体的偏差来源:PreOB 模型的训练集主要是西药分子,而中药成分里有大量糖苷、多酚、皂苷——这些类别在西药训练集里很少。模型的域外泛化能力对中药成分是未知的。

第二,「单味药的成分清单」不等于「人喝下去的成分」。

中药是复方煎煮的。煎煮过程中会发生:成分溶出率差异、成分间化学反应(如生物碱与鞣质结合沉淀)、水解(糖苷水解成苷元)、美拉德反应。TCMSP 给的是「药材里含有什么」,不是「汤里有什么」,更不是「血里有什么」。

这是中药研究最根本的方法学缺口。从药材成分直接推断药效,中间隔了「煎煮」和「吸收代谢」两道门。

第三,targets 表的靶点关系不等于「这个成分作用于这个靶点」。

TCMSP 的靶点映射来自 TTD / PharmGKB / PubChem 与文献。一个化合物「关联某靶点」可能是:实验测定的结合、计算预测的结合、同一通路里邻近的蛋白、或者仅仅因为文献里同时提到。

关系的证据等级没有被标注。这是老版在溯源上最大的短板(见 §5.2 第四类)。

§7.4 偏倚清单(可核查)

偏倚 证据 影响
版本口径偏倚 新版宣传 240 万,老版 13,729 几乎所有引用都写错的头号问题
药材覆盖偏倚 502 味,且清热解毒类占 14.3% 常用大宗药材覆盖好,冷门药空白
结构缺失 无 SMILES / InChIKey / PubChem CID 化学信息学分析必须回填,且有损失
半衰期缺失 58.5% 5,696 / 13,729 代谢稳定性任务只能做子集
占位值污染 caco2/bbb = -3.14159 不剔除会污染分布低端
靶点映射部分覆盖 drugbank_ID / kegg 大量为空 跨库分析覆盖率受限
疾病粒度粗 ICD 仅三位类目级 无法区分临床亚型
关系证据未分级 无字段标注关系来源 无法区分实验与预测

「药材覆盖偏倚」这一条值得展开。502 味药在《中国药典》收录的药材(约 600 味)里覆盖了大半,但分布极不均。「清热解毒药」72 味、「化痰药」35 味,而很多类目只有个位数。这与研究热度直接相关——抗炎、抗菌、抗肿瘤是基金热点,所以相关药材被研究得透。用 TCMSP 做「中药整体规律」的研究,会系统性高估热门类别的权重。

§7.5 数据完整性核查表

动手前的六分钟检查:

  • [ ] 用的是 old.tcmsp-e.com 子域名(不是 tcmsp-e.com/tcmsp.php)?
  • [ ] 数字写的是老版口径(13,729),不是新版(240 万)?
  • [ ] caco2 / bbb 的 -3.14159 已识别剔除?
  • [ ] 数值列已从字符串转 float?
  • [ ] FASA 大小写已处理?
  • [ ] halflife 缺失已用 masked loss 或子集声明?
  • [ ] MOL_ID 未进入特征?
  • [ ] 知道老版无结构字段、需要回填?

§7.6 DAIMS 24 项逐项评分

# 维度 判定 说明
1 数据集有唯一标识 ✅ MOL_ID / TAR_ID / DIS_ID 三套稳定编号
2 有版本标识 ✅ 页脚明确 TCMSP Version: 2.3
3 有持久标识符 ⚠️ 内部 ID 稳定,但无 DOI / 无外部持久标识
4 有许可声明 ✅ ODbL 1.0 + DbCL 1.0,首页明确
5 有引用规范 ✅ 首页给出 2014 年 J Cheminformatics 完整引文
6 有数据字典 ❌ 无字段说明文档,字段含义全靠猜
7 有记录级元数据 ⚠️ 化合物只有名字,无来源药材、无文献
8 有来源溯源 ⚠️ 声明「感谢 TTD/PharmGKB/PubChem」,但逐条不溯源
9 有采集方法说明 ⚠️ 论文里有,网站上无摘要说明
10 有质量控制说明 ❌ 完全无 QC 文档
11 有缺失值说明 ❌ -3.14159 占位符无任何说明
12 有样本量说明 ✅ 行数可从页面直接读出
13 有偏倚说明 ❌ 无
14 有伦理/隐私声明 ⚠️ 首页有「仅供研究」免责声明,无正式伦理声明
15 可公开访问 ✅ 老版完全免费,无需注册
16 有机器可读格式 ⚠️ HTML 内嵌 JSON——机器可读但是反模式
17 有批量下载 ❌ 无 ZIP / CSV / FTP
18 有 API ❌ 无 REST / SPARQL
19 有更新日志 ✅ 首页有 TCMSP update log
20 有数据规模声明 ⚠️ 首页只宣传新版规模,老版规模未声明
21 有跨库标识映射 ⚠️ 靶点有 DrugBank(内部数字 ID)、疾病有 ICD;化合物无任何外部 ID
22 有语义本体对齐 ⚠️ 疾病对齐 ICD(但仅三位码);功效分类未对齐任何本体
23 有可复现的划分建议 ❌ 无(正常缺失)
24 有下游任务示例 ✅ 论文与官网教程有完整网络药理学流程

得分:✅ 7 项 × 1 + ⚠️ 9 项 × 0.5 + ❌ 8 项 × 0 = 11.5 / 24 = 47.9%

扣分的八处,最严重的是这三处:

  • #6 数据字典 ❌:没有字段说明。caco2 / bbb 的单位是什么?FASA 的分数定义是什么?dl 的 0-1 范围怎么算的?全靠读 2014 年论文猜。
  • #11 缺失值说明 ❌:-3.14159 这个占位符在任何文档里都没提,纯粹靠我们自己看出来是 -π。
  • #16-#18 机器可读 ❌:无 API、无批量下载、数据藏在 HTML 里。这是「能用但要费劲」的典型。

11.5 分(47.9%)在已评的十二篇里处于中下位置:Rfam 91.7% > RNAcentral 85.4% > Complex Portal 79.2% > CPIC 75.0% > GBIF 58.3% = BV-BRC 58.3% > IMGT 52.1% > NeuroVault 50.0% > TCMSP 47.9% > Alliance 47.9% > MGI 45.8% > ENA 43.8%。

它的分数低不是因为数据没价值,是因为「交付方式」太原始。数据本身(14 项参数 100% 覆盖)质量不错,但无 API、无文档、无缺失值说明,这三项直接把分数拉下来。这正是一个「内容好、工程差」的典型案例。

§7.7 口径交叉核对矩阵(不是模型性能验证)

对照一:老版 2.3 与新版 9.0.1 的五个规模差异

指标 老版 2.3 新版 9.0.1(宣称) 倍数
化合物 13,729 约 2,400,000 175×
药材/资源 502 600,787 1,197×
靶点 3,339 66,800 20×
疾病 867 29,490 34×
分子-靶点互作 未知(未抓关系) 约 20 亿 —

注意倍数差异极大:药材差 1,197 倍,靶点只差 20 倍。这说明新版不是「在老版基础上加数据」,是「换了一套资源体系」——600,787 个「天然药物资源」里包含了大量非传统药材(海洋生物、微生物、矿物),与老版 502 味中药材不是同一类东西。

所以不能说「新版是老版的 175 倍」,只能说「新版的化合物数是老版的 175 倍」。 这两句话的差别很大——前者暗示连续性,后者只是数量对比。

对照二:「老版没有 ADMET 预测」的正确理解

表述 对错 依据
老版没有 ADMET 数据 错 化合物表有 ob / dl / caco2 / bbb / FASA 等 14 项
老版没有 ADMET 预测功能 对 官网功能对比表里「ADMET Prediction」标「否」
老版的 ADMET 是静态预计算值 对 每个化合物一行,字段填好

这个区分很重要:官网说「老版不支持 ADMET 预测」,指的是你不能输入一个新分子让它算。但库里已有的化合物,值都算好了。

误解的后果:以为老版没有 ADMET 数据 → 去别处找成药性参数 → 拿到的不是 TCMSP 口径 → 结果无法与文献对比。TCMSP 的 OB/DL 值之所以有用,恰恰因为它是这一套模型算的、大家都在用。

对照三:dual_pass 18.8% 与「两个单独达标率相乘」的偏差

算法 结果
OB ≥ 30% 的达标率(实测) 42.5%(5,836 条)
DL ≥ 0.18 的达标率(实测) 55.7%(7,647 条)
若两者独立,期望双达标率 23.7%(约 3,249 条)
实测双达标率 18.8%(2,583 条)
差额 −4.9 个百分点 / 约 −666 条

实测值比独立期望低 26%(相对),方向明确:OB 与 DL 负相关。

这个偏差不是巧合,是一个可解释的化学规律。 但它也提醒:用两个单独达标率相乘去估双达标数,会高估约四分之一。 做文献复核时,如果你的筛选结果与 TCMSP 公布的成分数差距在这个量级,先检查方法,而不是先怀疑数据。

对照四:四个浏览页的条数与「这个库有多大」

表 条数 一个常见的误解
herbs 502 「502 味药很少」——但《中国药典》也就 600 味左右
ingredients 13,729 「13,729 个化合物太少」——但这是「已整理进中药体系」的
targets 3,339 「3,339 个靶点只占人类蛋白组的 15%」——这是中药研究触及的靶点
diseases 867 「867 种病太少」——这是中药研究里出现过的疾病

四个数字都「小」,但小的原因各不相同:502 是领域本身的规模(中药材总数有限),13,729 是筛选后的规模(只收有中药归属的),3,339 和 867 是研究覆盖的规模(不是全集)。

把它们当成「这个库不够全」是误判。 502 味药对应 600 味药典收录,覆盖率约 84%——这个覆盖度在中药数据库里是相当高的。


§8 生态位与相邻资源

§8.1 TCMSP 在网络里的位置

                中药数据
                   │
      ┌────────────┼────────────┬─────────────┐
      │            │            │             │
  TCMSP        HERB 2.0     SymMap       ETCM
  (成药性口径)  (实验证据)   (证候映射)   (药典口径)
      │
      ├── 靶点 ← TTD / PharmGKB / PubChem / DrugBank
      ├── 疾病 ← ICD-9 / ICD-10
      └── 化合物结构 ← PubChem(需自行回填)

四个中药库的分工:

库 强项 弱项
TCMSP 成药性五件套 + 网络药理学标准流程 无结构、无实验证据、工程交付差
HERB 2.0 实验证据(哪些成分被验证过) 无系统 ADMET
SymMap 证候-症状-中药映射 化合物层弱
ETCM 药典收录、中医属性 化合物参数少

TCMSP 的不可替代性只在第一行第二列:OB/DL/Caco-2/BBB/FASA 这套 100% 覆盖的成药性参数。别的都能在别处找到更好的,唯独这一套是它独有的口径。

已收条目 关系
HERB 2.0(#1123) 最直接的一对:TCMSP 给成药性口径,HERB 给实验证据。同一味药的成分,两个库的说法要对齐才可信
LOTUS(#1040) LOTUS 给天然产物结构(有 SMILES),TCMSP 给成药性——LOTUS 正好补 TCMSP 缺的结构
COCONUT(#304) 同 LOTUS,开放天然产物集合,可做结构回填源
DrugBank 类资源 TCMSP 的靶点映射到 DrugBank,是中药-西药靶点重叠分析的基础
ChEMBL 类活性数据 ChEMBL 给 IC50/Ki,TCMSP 给成药性——活性 + 成药性才完整

最值得做的一组配对是 TCMSP + LOTUS:TCMSP 的 13,729 个化合物只有名字没有结构(§3.4),而 LOTUS 有结构。按名字做映射,能补回一部分 SMILES——这是让 TCMSP 可用于化学信息学分析的最低成本路径。

但名字匹配有天花板。TCMSP 用的是通用名(anthocyanidin 花色素),这类名字在 LOTUS / PubChem 里对应多个具体异构体。能匹上的比例,以及匹上之后的歧义率,都需要实测——我们没有做这个匹配,所以给不出数字。 这是本篇明确的一处未完成工作。

§8.3 为什么一个「医学数据集站」要收中药系统药理学

因为它是中文语境下最常被引用的药物数据集,而中文语料里关于它的英文原版说明几乎为零。

TCMSP 2014 年那篇论文被引数万次,其中相当大一部分来自中国研究者。但它的官网是英文、字段无文档、占位符无说明。结果是:所有人都在用,但很少有人真正搞清楚 -3.14159 是什么意思。

使用现状 实际情况
「TCMSP 收录 240 万化合物」 那是新版,老版 13,729
「OB ≥ 30 且 DL ≥ 0.18 的成分是活性成分」 对,但这是预测值不是实验值
「TCMSP 有 ADMET 数据」 对,但 caco2/bbb 可能有占位符
「按 OB/DL 筛出活性成分」 对,结果是 2,583 个(18.8%),不是几千上万

这四行里的每一行,都对应一个真实存在的误解。 把它们写清楚,比再介绍十个数据集更有价值。


§9 许可、伦理与合规

§9.1 许可结构

老版首页明确写出双许可:

许可 覆盖对象 要求
ODbL 1.0(Open Database License) 数据库整体 署名 + 相同方式共享(衍生数据库须同许可)+ 保持开放
DbCL 1.0(Database Contents License) 数据库内容 允许自由使用内容,但不得限制他人对内容的同等使用

ODbL 的核心义务有三条:

  1. 署名(Attribution):必须注明来源 TCMSP。
  2. 相同方式共享(Share-Alike):如果你基于 TCMSP 做了一个衍生数据库并公开,必须用 ODbL 或兼容许可。
  3. 保持开放(Keep Open):如果分发衍生数据库,不能加技术限制(如 DRM)。

注意 ODbL 与 CC BY-SA 的关键差别:ODbL 的「相同方式共享」只约束「数据库」,不约束「用数据库做出来的作品」。也就是说:

你的产出 是否受 Share-Alike 约束
一个基于 TCMSP 的新数据库 是,须用 ODbL
一篇论文 / 报告 / 图表 否,可自由发表
一个训练好的模型(权重) 一般不构成数据库,通常不受约束
一个包含 TCMSP 数据的软件 视情况,若实质上是数据库的再分发则受约束

最后一行是灰色地带。如果你的软件把 TCMSP 全表打包进去分发,实质上就是数据库再分发,应遵守 ODbL。如果只是运行时查询在线接口,则不构成再分发。做商业产品前建议咨询法务。

§9.2 新版许可与老版不同

这一点必须单独说明:老版免费且是 ODbL,新版 9.0.1 的高级功能需要付费会员。 两个版本的许可状态不同。

版本 访问 许可
老版 2.3 免费,无需注册 ODbL 1.0 + DbCL 1.0
新版 9.0.1 基础检索免费,高级功能需会员 需查新版条款(本篇未核)

本篇只覆盖老版,所以只承诺老版的 ODbL 条款。如果你的项目要用新版功能(靶点预测、分子对接),许可条件完全不同,需要单独确认。

§9.3 研究用途与临床边界

老版首页的免责声明原文:

“The content of TCMSP is intended for purely research purposes. It should not be used for emergencies or medical or professional advice.”

这句话划的线很明确:纯研究用途,不可用于医疗建议。 具体来说:

用途 是否允许
药物发现研究、网络药理学分析 ✅
训练成药性预测模型 ✅
科研论文中的成分筛选 ✅
推荐某味药治某个病 ❌
判断某个保健品是否有效 ❌
替代药师或医师判断 ❌

为什么这条线必须划清:TCMSP 的 OB/DL 是预测值,靶点关系未分级证据,成分清单不等于汤里实际成分(§7.3 第二条)。任何一环都不足以支撑临床结论。

一个常见的越界:用 TCMSP 筛出「活性成分」,然后宣称「这些成分是某方剂的有效物质基础」。这个推论跳过了三道门:① 预测值 ≠ 实验值;② 药材成分 ≠ 煎煮成分;③ 靶点关联 ≠ 药效。这三道门每一道都可能让结论完全反转。

§9.4 引用规范

官方要求的引用(首页原文给出):

Jinlong Ru; Peng Li; Jinan Wang; Wei Zhou; Bohui Li; Chao Huang; Pidong Li; Zihu Guo; Weiyang Tao; Yinfeng Yang; Xue Xu; Yan Li; Yonghua Wang; Ling Yang. TCMSP: a database of systems pharmacology for drug discovery from herbal medicines. J Cheminformatics. 2014 Apr 16;6(1):13.

引用时应注意三点:

  1. 必须写明用的哪个版本(本篇是 2.3)。不写版本,读者无法判断你用的是 13,729 还是 240 万口径。
  2. 必须写明访问日期——老版已冻结但站点可能下线,日期是唯一的时间锚点。
  3. 如果用了筛选阈值,要写明「OB ≥ 30% 且 DL ≥ 0.18」,因为这是 TCMSP 的口径,不是通用标准。

§9.5 一份可直接抄的引用模板

数据来源:TCMSP (Traditional Chinese Medicine Systems Pharmacology Database
and Analysis Platform), Version 2.3(老版,免费).
访问地址:https://old.tcmsp-e.com/tcmsp.php
访问日期:2026-10-23
规模口径:502 味药材 / 13,729 个化合物 / 3,339 个靶点 / 867 种疾病
筛选条件:口服生物利用度 OB ≥ 30%,类药性 DL ≥ 0.18
筛选结果:2,583 个化合物(占全部 13,729 的 18.8%)
原始文献:Ru J, Li P, Wang J, et al. J Cheminformatics. 2014;6(1):13.
许可:ODbL 1.0(数据库)+ DbCL 1.0(内容)

这份模板里「规模口径」与「筛选结果」两行是多数论文漏写的。漏写规模口径,读者无法判断你是不是误用了新版数字;漏写筛选结果,读者无法核对你筛出的成分数对不对。这两行加起来不到 60 字,但能省掉审稿人一半的质疑。


§10 复用边界与跨条目协作手册

§10.1 决策树:什么时候该用 TCMSP

你的问题是什么?
│
├─ 「这个中药成分能不能口服吸收」
│   └─→ ✅ 用 TCMSP 的 ob 字段(记住是预测值)
│
├─ 「这个成分像不像药」
│   └─→ ✅ 用 dl 字段
│
├─ 「这个成分能不能进脑子」
│   └─→ ✅ 用 bbb 字段(注意方向:不是越高越好)
│
├─ 「这味药含哪些成分」
│   └─→ ✅ 但要去检索页查关系(浏览表没有)
│
├─ 「这个成分作用于哪些靶点」
│   └─→ ⚠️ 检索页可查,但靶点关系证据未分级
│
├─ 「这个成分的分子结构 / SMILES」
│   └─→ ❌ 老版没有。去 LOTUS / PubChem / COCONUT 找
│
├─ 「这个成分在实验里被验证过吗」
│   └─→ ❌ TCMSP 没有。去 HERB 2.0 找
│
└─ 「这个方子治什么病」
    └─→ ❌ 不要用任何数据库直接回答。TCMSP 是研究工具

§10.2 与 HERB 2.0 的分工(成药性 ↔ 实验证据)

这是最有价值的一组配合:

环节 用什么库 得到什么
1. 这味药含哪些成分 TCMSP(检索页) 成分清单
2. 哪些成分值得研究 TCMSP(OB/DL 筛) 2,583 个候选中的一部分
3. 哪些成分有实验证据 HERB 2.0 「这个成分在哪些实验里被验证过」
4. 拿两者的交集 自建 既成药又有效的成分

第 4 步的交集才是真正有价值的:TCMSP 的 OB/DL 达标只说明「理论上能吸收」,HERB 的实验证据只说明「有人测过」,两者都有才说明「既可能吸收、又有人验证」。

实操提醒:两个库的化合物命名体系不同。TCMSP 用通用名(anthocyanidin),HERB 用的可能是更规范的名字或带 CAS。做交集前必须做名字归一化,否则匹配率会低得离谱。这一步没有现成工具,必须手工建映射表。

§10.3 与新版 9.0.1 的关系(数据 ↔ 工具)

不要把两版当「新旧关系」,要当「数据与工具」关系:

你需要什么 用哪个版本
批量数据、可复现、可存快照 老版 2.3
交互分析、靶点预测、分子对接 新版 9.0.1
100 万级的化合物规模 新版 9.0.1
免费商用(受 ODbL 约束) 老版 2.3
单细胞分析、文献验证 新版 9.0.1

一个务实的组合:用老版做数据基础,用新版做验证。老版 13,729 个化合物的 OB/DL 值稳定,可以作为基准;如果你筛出的成分想进一步做靶点预测,可以用新版的功能补上。但报告结果时,规模口径必须分开写清楚。

§10.4 许可梯度对照

资源 许可 商用 Share-Alike 范围
TCMSP 2.3(老版) ODbL 1.0 + DbCL ✅ 仅数据库衍生,不约束论文/图表
TCMSP 9.0.1(新版) 需查条款 视条款 未知
HERB 2.0 学术免费 需申请 未知
LOTUS CC0 ✅ 无
COCONUT CC0 ✅ 无
CPIC 公有领域 ✅ 无
Rfam / RNAcentral CC0 ✅ 无

ODbL 比 CC BY-SA 温和——它的 Share-Alike 只作用于「数据库」,不作用于「作品」。这意味着你可以用 TCMSP 写论文、画图、训练模型,都不受传染性约束;只有当你把数据打包成一个新数据库分发时,才需要同许可。这个区分对做产品的人很重要。

§10.5 三个「不要做」

一、不要把新版 240 万与老版 13,729 混在一篇文章里。 这是本篇第一条坑,也是被犯得最多的错。自查方法:如果你分析里化合物数只有几千,那你用的就是老版。

二、不要用 TCMSP 的 OB/DL 宣称「有效成分」。 它们是预测的成药性,不是药效。一个分子可以 OB 90%、DL 0.9,但完全没有任何生物活性。「成药性」和「有效性」是两个正交的维度。

三、不要忽略 caco2/bbb 的 -3.14159。 这个占位符不剔除,模型会把「算不出来」学成「极度难吸收」。它是本篇最隐蔽的一个数据陷阱——因为它在数值区间内、不报错、看起来很正常。

§10.6 一句话总结

TCMSP 是中药网络药理学领域十年来的筛选口径本身——它只有 13,729 个化合物、502 味药材,规模很小,但那 2,583 个「OB≥30 且 DL≥0.18」的化合物,是整个领域共同接受的起点。

用它的时候记住三件事:数字是老版的(不是 240 万);OB/DL 是预测值(不是实验值);caco2/bbb 里的 -3.14159 是「算不出来」(不是「极度难吸收」)。


附录 A:本篇数字速查

数字 值 来源
药材 502 browse.php?qc=herbs 内嵌 JSON 长度
化合物 13,729 browse.php?qc=ingredients 内嵌 JSON 长度
靶点 3,339 browse.php?qc=targets 内嵌 JSON 长度
疾病 867 browse.php?qc=diseases 内嵌 JSON 长度
OB ≥ 30% 达标 5,836(42.5%) 全量计算
DL ≥ 0.18 达标 7,647(55.7%) 全量计算
OB/DL 双达标 2,583(18.8%) 全量计算;独立期望 23.7%,实测低 4.9pp
功效分类 38 类 herbs 表 child_cn_name 去重
最大功效类 清热解毒药 72 味(14.3%) 同上
OB 中位数 24.83 全 13,729 条
DL 中位数 0.24 同上
Caco-2 中位数 0.44 同上(剔除 -π 前)
BBB 中位数 -0.16 同上(过半难入脑)
MW 中位数 354.34 同上
ALogP 中位数 2.63 同上
TPSA 中位数 63.93 同上
FASA 中位数 0.26(有值率 95.7%) 同上
Halflife 有值率 41.5%(5,696 条) 同上
Halflife 中位数 7.09 h 在 5,696 条子集上
氢键供体中位 2 100% 有值
氢键受体中位 5 100% 有值
可旋转键中位 4 100% 有值
页面总体积 约 4.4 MB(四表) 实测下载量
化合物页体积 3.79 MB 实测
DAIMS 得分 11.5 / 24 = 47.9% §7.6
老版版本 2.3 页脚
版权年份 2012 - 2023 页脚

附录 B:五个可复制的操作

一、四表全量抓取(4.4 MB,1-2 分钟)

import re, json, requests, pandas as pd

def fetch(qc):
    r = requests.get("https://old.tcmsp-e.com/browse.php",
                     params={"qc": qc}, timeout=180)
    m = re.search(r'data:\s*(\[\{.*?\}\])\s*,', r.text, re.S)
    return json.loads(m.group(1))

ingred = pd.DataFrame(fetch('ingredients'))
print(len(ingred))   # 13729

二、识别 -3.14159 占位符有多少条

import numpy as np
PI = -3.14159
n_c = np.isclose(ingred.caco2.astype(float), PI, atol=1e-4).sum()
n_b = np.isclose(ingred.bbb.astype(float),   PI, atol=1e-4).sum()
print(f"caco2 占位 {n_c} 条, bbb 占位 {n_b} 条")

三、算 OB/DL 双达标并核对 2,583

ob = pd.to_numeric(ingred.ob, errors='coerce')
dl = pd.to_numeric(ingred.dl, errors='coerce')
print(((ob >= 30) & (dl >= 0.18)).sum())   # 期望 2583

四、按功效分类统计药材数

herbs = pd.DataFrame(fetch('herbs'))
print(herbs.child_cn_name.value_counts().head(10))
# 清热解毒药 72, 化痰药 35, 利水渗湿药 34, ...

五、用检索页查药材成分(需 token)

curl -s "https://old.tcmsp-e.com/tcmspsearch.php" -o s.html
TOKEN=$(grep -oE 'value="[a-f0-9]{20,}"' s.html | grep -oE '[a-f0-9]{20,}')
curl -s "https://old.tcmsp-e.com/tcmspsearch.php?qs=herb_name&q=Gancao&token=$TOKEN"

前四个操作全部基于浏览页的内嵌 JSON,稳定可复现。第五个依赖检索页的 token 机制,参数名需按实际表单核对——我们的实测中它返回了页面结构而没有返回结果数据,说明参数名或检索项代码需要进一步确认。这是本篇明确的一处未完成工作:关系数据的抓取路径没有完全跑通,所以 §7.2 声明「关系数据完全未核验」。


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • meddra — 共享标签:药物发现与化学 / 公共卫生与流行病学
  • impc — 共享标签:基因组学与多组学 / 公共卫生与流行病学
  • intact — 共享标签:药物发现与化学 / 基因组学与多组学
  • msigdb — 共享标签:药物发现与化学 / 基因组学与多组学
  • alphamissense — 共享标签:基因组学与多组学 / 公共卫生与流行病学
  • lipid-maps — 共享标签:药物发现与化学 / 基因组学与多组学
  • uk-biobank — 共享标签:基因组学与多组学 / 公共卫生与流行病学
  • ctd — 共享标签:药物发现与化学 / 基因组学与多组学 / 公共卫生与流行病学
  • card-db — 共享标签:药物发现与化学 / 基因组学与多组学 / 公共卫生与流行病学
  • alphafold — 共享标签:药物发现与化学 / 基因组学与多组学

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集