信息速览
| 维度 | 内容 |
|---|---|
| 它是什么 | 疾病相关蛋白编码突变(protein-coding mutation,下称 PCM)的文献知识库 |
| 谁做的 | 中国科学院北京基因组研究所(国家生物信息中心),通讯作者贾佩琳 |
| 一行规模 | 一万一千余条基因-突变-疾病记录,三条轴分别是三千五百余个基因、四千五百余种疾病、23 种突变类型 |
| 记录单元 | 一行 = 一篇文献里的一个「基因 × 具体突变 × 疾病」组合 |
| 抽取方式 | DeepSeek V3 读摘要 + 人工两阶段复核,再按置信度分 Tier 1 / Tier 2 |
| 标注深度 | 核苷酸与蛋白双序列映射、SIFT 与 PolyPhen-2 功能预测、gnomAD 人群频率、遗传模式 |
| 疾病术语 | Disease Ontology 映射 46.3%,Orphanet 判罕见 37.4%,GWAS Catalog 判常见 10.9% |
| 与 ClinVar 的关系 | 36.3% 重合,63.7% 为本库独有 |
| 取数方式 | 网页浏览与检索 + Browse 页导出 XLSX;无公开 REST 文档,前端调用内部 JSON 接口 |
| 访问门槛 | 无需注册、无需申请 |
| 数据格式 | 表格(网页 JSON 与导出 XLSX);单条详情页另有序列查看器 |
| 与患者数据的关系 | 不存患者、不存原始测序读段,只存摘要里公开写出的突变描述 |
| 更新节奏 | 论文写明每三个月整体更新一次,首页 News 记录逐批收录过程 |
| 适合谁 | 遗传病研究者、变异解读团队、要做基因-疾病知识图谱的工程组 |
| 不适合谁 | 需要临床分级结论的人、需要人群频率精确值的人、只做常见病 GWAS 的人 |
SeqPCMdb 是一个把「文献里写过的致病突变」变成可检索表格的库。它不做测序,也不重新判定致病性,做的是把散在 PubMed 摘要里的基因、突变、疾病三件东西抽出来,对齐到参考基因组,再挂上功能预测与人群频率。
它的位置落在一个很具体的缝里:ClinVar 收的是实验室与专家panel 提交的临床解读,OMIM 讲的是基因与疾病的对应关系,两者都不回答「这篇 2023 年的病例报告里到底报过哪几个具体核苷酸改变」。SeekPCMdb 补的正是这一层,也因此它最有价值的数字不是总量,而是那 63.7% 的「不在 ClinVar 里」。
先划边界:它是证据索引,不是判读结论。一条记录代表「某篇文献报告过这个突变与该疾病有关」,不代表「这个突变致病」。把它当 ClinVar 用,方向就错了;把它当检索入口先找到原文,再回去读病例,才是对的位置。
§1 它要解决的具体麻烦
1.1 一句话结论:这是给变异解读做「查文献」这一步的加速器
变异解读(variant interpretation)有一道固定工序:手上有一个错义突变,要知道文献里有没有人报过它、报到什么病、有没有旁证。这道工序过去靠人工检索 PubMed,一个人一天能查完的基因有限。
SeekPCMdb 把这道工序的产出先做了一遍:从 12,159 篇摘要中抽出 7,016 篇里能找到的完整三元组,整理成 11,395 条记录。使用者的动作从「检索并阅读」变成「检索并回读原文确认」。这个顺序的调换,是它最实在的用处。
1.2 三条常见的错误期待
| 期待 | 为什么不成立 | 它实际能给什么 |
|---|---|---|
| 「可以拿它判定致病性」 | 库里没有临床分级字段,记录的来源是摘要陈述,不是 ACMG 证据评级 | 每条记录附 SIFT 与 PolyPhen-2 的预测倾向,以及 ClinVar 是否收录 |
| 「它比 ClinVar 全」 | 方向相反:ClinVar 收录的是临床解读,本库收录的是文献陈述,两者交集只有 36.3% | 作为 ClinVar 的补充检索面,而不是替代 |
| 「摘要里写的突变它都收了」 | 只解析摘要,正文与补充材料里的突变大概率漏掉 | 摘要层面的高召回;正文层面的召回需要另外检索 |
三条期待里,第一条最危险。一个基因-突变-疾病记录的存在,只说明有人写过;写过的东西可能是错的,可能是同一突变在不同报道里被赋予不同疾病。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 查某基因下有哪些被报道的突变 | 该基因全部记录,可按基因精确或模糊检索 | 够 |
| 查某突变在文献里对应哪些疾病 | 疾病名与原文献 PMID | 够(疾病名未标准化的部分需自行归一) |
| 判断突变是否致病 | 无临床分级;只有 SIFT、PolyPhen-2 的预测标签 | 不够 |
| 拿人群频率 | gnomAD 的总体与分祖源 MAF(仅对有 rsID 的变异) | 部分够(57.6% 有 rsID) |
| 看突变在蛋白上的位置 | 详情页有核苷酸与蛋白序列的变更前后对照 | 够(序列层面) |
| 看突变影响的三维结构 | 无 | 不够,论文把结构分析列为后续方向 |
| 批量拉全库做统计 | 网页可导出 XLSX;无公开 REST 文档 | 勉强够(见 §5) |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 手上有一个错义突变,ClinVar 判「意义未明」 | 查该突变或该基因的文献记录,看有没有未提交 ClinVar 的病例报道 | 逐条回读 PMID 原文,判断病例质量 |
| 要做一个罕见病基因的候选清单 | 按疾病名检索,拿到该病关联的全部基因 | 用 DO 或 Orphanet 编号做二次归一 |
| 要训一个变异-疾病关系抽取模型 | 万余条三元组可做弱监督语料 | 先看 Tier 1 与 Tier 2 的混比,别把推断记录当金标 |
| 要给知识图谱补边 | 基因-突变类型-疾病的三元组结构,可直接建边 | 边上要带 PMID 与 Tier,否则无法溯源 |
| 要比较不同突变类型偏向哪些通路 | 论文给了 missense 与 nonsense 的通路偏向差异 | 自己重跑富集前,先确认基因集口径 |
1.5 一句话判断
如果你的问题形状是「这个突变/这个基因,文献里报过什么」,它是国内公开资源里最好用的入口之一;如果你的问题形状是「这个突变到底致病吗」,请带着它的 PMID 去 ClinVar、去原文、去 ACMG 判读流程,而不是停在这张表上。
1.6 不适合谁:四条边界
| 边界 | 说明 |
|---|---|
| 不做临床分级 | 全库无致病性分级字段,不能用于报告出具 |
| 不覆盖常见病 | 与 GWAS Catalog 只重合 10.9%,复杂疾病的常见变异基本不在里面 |
| 不做结构解释 | 只有序列层面预测,没有三维结构或结构域破坏的判定 |
| 不做人群频率 | MAF 是转引 gnomAD,且只对有 rsID 的 57.6% 成立 |
1.7 一个基因从提问到结论的四步
把使用流程拆成四步,每一步的输入输出都明确下来,才能看出这个库在整条链上到底占几成。
| 步骤 | 输入 | 动作 | 输出 | 本库参与程度 |
|---|---|---|---|---|
| 检索 | 一个基因符号或一个突变描述 | 查库内记录 | 候选记录清单 | 全参与 |
| 溯源 | 记录里的 PMID | 下载原文核对摘要与正文 | 可引用的病例事实 | 半参与(给编号,不给原文) |
| 判读 | 病例事实与人群频率 | 按 ACMG/AMP 规则评级 | 证据等级 | 不参与(只给 SIFT 与 PolyPhen-2 参考) |
| 报告 | 证据等级 | 出具报告并登记 ClinVar | 结构化提交 | 不参与 |
这张表要说明的比例关系是:整条链有四个环节,本库占第一环的全部、第二环的一半、后两环的不参与。把它当第一环用,效率提升明显;把它当第三环用,等于跳过判读。
第四步值得一提。变异解读的最后一步通常是把结论提交回 ClinVar,而本库与 ClinVar 的交集只有三分之一略多,也就是说大量记录最终没有回流到临床数据库。这正是它作为补充资源的价值来源,也解释了为什么两个库都自称「疾病相关变异库」却可以并存。
1.8 三种规模的读法
新手最先遇到的问题是「这个库到底多大」,答案取决于问的是哪一层。
| 层的名字 | 数字 | 回答的问题 | 误用后果 |
|---|---|---|---|
| 文献层 | 一万二千余篇检索,七千余篇有抽取结果 | 花了多少检索成本 | 拿文献数当记录数,规模被高估 |
| 记录层 | 一万一千余条 | 库里有多少行 | 当独立事实数,重复报道被算多次 |
| 事实层 | 一万一千三百余个三元组 | 有多少个不重复的基因×突变×疾病组合 | 仍不等于突变数,同一突变对多病会拆行 |
三层的关系是嵌套而非并列:文献层最大,记录层次之,事实层最小,而真正意义上的「不同突变」比事实层还要再少一截,因为同一个突变可以出现在不同疾病的三元组里。
写论文引用规模时最稳妥的做法是引两层:写「一万余条记录、一万一千余个三元组」,两个数字一起出现,读者就不会误以为是一万多个独立突变。只写一个数字时,选记录层,因为那与官方摘要的口径一致。
§2 数据构成与规格
2.1 三条轴:基因、突变、疾病
库的基本单元是三元组。三条轴各自有独立的编号体系,这一点决定了后续所有关联操作的方式。
| 轴 | 数量 | 编号 | 是否可作主键 |
|---|---|---|---|
| 基因 | 三千五百余 | 内部 geneId,另有基因符号 | 是(geneId 稳定) |
| 突变 | 11,166 对 gene-mutation | 突变描述字符串(c. 与 p. 混写) | 否(字符串需解析后才能当键) |
| 疾病 | 四千五百余 | 内部 diseaseId,另有 DO 编号(部分) | 部分(仅 46.3% 有 DO 编号) |
| 突变类型 | 23 | 类型名 | 是(枚举) |
| 文献 | 7,016 篇有抽取结果 | PMID | 是 |
三元组总数 11,338,比记录总数少 57 条,差额是同一三元组在不同文献中的重复报道——这是理解「记录数不等于事实数」的第一个提示。
2.2 字段字典
Browse 页导出的表格是六列,接口返回的每条记录是十列。两者差在接口多给了内部编号与置信度层。
| 字段 | 类型 | 说明 | 示例值 | 导出表是否含 | 缺失表示 |
|---|---|---|---|---|---|
| pmid | Integer | 来源文献 PubMed ID | 24939586 | 含 | 无 |
| gene | Text | 基因符号 | A2ML1 | 含 | 无 |
| geneId | Integer | 库内基因编号 | 1 | 不含 | 无 |
| variant | Text | 突变描述(核苷酸或蛋白层) | c.1432C>T (p.R478*) | 含 | 无 |
| variantType | Text | 突变类型 | Nonsense | 含 | 无 |
| variantTypeId | Integer | 类型编号 | 15 | 不含 | 无 |
| variantTier | Text | 置信层级 tier1 / tier2 | tier1 | 含 | 无 |
| inheritancePattern | Text | 遗传模式 | - | 含 | 破折号 |
| disease | Text | 疾病名 | Triple A Syndrome | 含 | 无 |
| diseaseId | Integer | 库内疾病编号 | 4320 | 不含 | 无 |
导出表的六列是 gene、variant、variantType、inheritancePattern、disease、pmid,也就是「不带内部编号」的那一版。要做跨版本比对,必须用接口取的十列版本,因为 geneId 与 diseaseId 是全库唯一稳定的连接键。
2.3 一条记录的完整解剖
拿一条实际返回的记录看:
{
"pmid": 30381913,
"gene": "AAAS",
"geneId": 2,
"variant": "c.1432C>T (p.R478*)",
"variantTier": "tier2",
"variantType": "Nonsense",
"variantTypeId": 15,
"inheritancePattern": "-",
"disease": "Triple A Syndrome",
"diseaseId": 4320
}
这条记录说的三件事:某篇文献报道了 AAAS 基因上 c.1432C>T 这个无义突变,与 Triple A 综合征有关。值得注意的有两点:Tier 标为 tier2,说明突变类型或位点有一部分是模型推断的;遗传模式是破折号,说明摘要里没写。前一点影响结论强度,后一点影响遗传分析能否直接用。
同一个 PMID 下还有一条 p.R286*,Tier 1。同一篇文献、同一基因、同一个病,两条记录的置信层级不同,这在后续统计 Tier 分布时会形成明显的不对称。
2.4 分布:突变类型与遗传模式
| 突变类型 | 记录数 | 占比 | 备注 |
|---|---|---|---|
| Missense | 6,508 | 57.2% | 检索量最大的一类 |
| Frameshift | 1,705 | 15.0% | 移码 |
| Nonsense | 1,523 | 13.4% | 无义 |
| Splice-site | 916 | 8.1% | 剪接位点 |
| 其余 19 类 | 合计 743 | 6.5% | 含同义、起始丢失、终止丢失等 |
| 遗传模式 | 占比 |
|---|---|
| 常染色体隐性 | 49.2% |
| 常染色体显性 | 23.1% |
| X 连锁 | 5.5% |
| 体细胞 | 1.6% |
| 线粒体 | 0.2% |
| 破折号(摘要未写) | 其余 |
两张表的共同含义:这个库以孟德尔遗传的罕见病为主体。接近一半是隐性,近六成是错义——这两条一起决定了它的典型用户是遗传病门诊的变异解读员,而不是肿瘤的体细胞突变分析。
2.5 与同类资源的字段差异
| 资源 | 记录单元 | 临床分级 | 序列映射 | 人群频率 | 文献溯源 |
|---|---|---|---|---|---|
| SeekPCMdb | 基因×突变×疾病 | 无 | 有(GRCh38) | 有(gnomAD,部分) | 有(PMID) |
| ClinVar | 变异提交 + 临床解读 | 有 | 有 | 有(转引) | 部分 |
| OMIM | 基因与疾病条目 | 无 | 无 | 无 | 有(文献) |
| COSMIC | 肿瘤体细胞突变 | 部分 | 有 | 有 | 部分 |
| HGMD | 突变与疾病 | 有 | 有 | 部分 | 有(订阅制) |
差异最明显的一行是「临床分级」。这张表里只有 SeekPCMdb 与 OMIM 两列是「无」,它们的分工因此很清楚:OMIM 答「这个基因与这个病有没有关系」,SeekPCMdb 答「这个基因的这个具体改变被谁报过」。
2.6 实体与 ID 的链接关系
三条轴各有自己的编号,记录本身却没有独立编号,这决定了连接方式。
| 实体 | 库内 ID | 外部 ID | 是否全库唯一 | 典型用途 |
|---|---|---|---|---|
| 基因 | geneId | HGNC 符号、NCBI Gene | 是 | 做基因层聚合 |
| 疾病 | diseaseId | DOID(46.3%)、Orphanet 编号(37.4%) | 是 | 做疾病层聚合 |
| 突变类型 | variantTypeId | 无 | 是 | 做类型统计 |
| 变异 | 无独立 ID | rsID(57.6%) | 否 | 做位点级去重 |
| 文献 | 无独立 ID | PMID | 是 | 溯源 |
最容易出问题的两行是「变异」与「文献」。变异没有独立编号,只能靠突变描述字符串匹配;同一变异在库里可能存在三种写法(只写核苷酸、只写蛋白、两者都写),字符串一不等就被当成两条。文献没有独立编号,但 PMID 本身就是天然主键,可以直接用。
按基因或疾病做聚合相对安全,因为它们有内部整数 ID。按变异做去重必须先解析字符串:把 c.1432C>T (p.R478*) 拆成核苷酸部分与蛋白部分,再用核苷酸部分做键,只有核苷酸部分缺失时才退化到蛋白部分。
2.7 查询结果表的结构
检索页返回的表是「一条记录一行」,列的顺序在全库固定。
| 列 | 内容 | 是否可排序 | 是否可点击 |
|---|---|---|---|
| Gene | 基因符号 | 可 | 可,跳基因详情页 |
| Variant | 突变描述 | 可 | 可,带突变参数跳详情页 |
| Variant type | 突变类型 | 可 | 否 |
| Tier | 置信层级 | 可 | 否 |
| Inheritance | 遗传模式 | 可 | 否 |
| Disease | 疾病名 | 可 | 可 |
| PMID | 文献编号 | 可 | 可,外链 PubMed |
可点击的四个列构成了站内的跳转面:基因与疾病通向详情页,PMID 通向 PubMed。这一层设计比接口更有用,因为详情页会补上接口不返回的序列对照与网络图。
§3 建库链条:从摘要到序列
3.1 检索:十把钥匙开一个抽屉
建库第一步是确定检索式。作者没有用「所有突变」这种宽口径,而是按十种突变类型逐个检索,再合并去重。
| 突变类型 | 检出文献数 | 访问日期 |
|---|---|---|
| Missense | 5,434 | 2025-05-08 |
| Nonsense | 1,881 | 2025-05-20 |
| De novo | 3,235 | 2025-06-11 |
| Frameshift | 1,850 | 2025-07-02 |
| Splice-site | 1,035 | 2025-07-02 |
| In-frame | 398 | 2025-07-02 |
| Stop-loss | 24 | 2025-07-02 |
| Start-loss | 11 | 2025-07-02 |
| Synonymous | 879 | 2025-07-02 |
| Protein-coding | 1,673 | 2025-07-02 |
| 合计(去重后) | 12,159 | — |
- 检索式骨架是
(WES OR WGS) AND mutation AND human,再叠一个突变类型词 - 清单里的最小一类只有 11 篇(起始丢失),最大一类五千余篇,差了三个数量级
- 十类之间存在大量交叉:一篇讲移码的摘要往往也命中「突变」这一宽词,去重后总数远小于逐类相加
这份检索清单本身就是使用说明书的一部分:它告诉你哪些文献没有被覆盖。检索式锁定 WES/WGS 与「mutation」,意味着纯靶向 panel 的研究、纯功能研究的论文,都不在池子里。
3.2 抽取:DeepSeek 读摘要
抽取环节交给 DeepSeek V3-0324,部署在中国科技云上,为的是不受请求限速影响。每篇摘要输入五个字段(PMID、发表日期、标题、摘要、期刊名),要求模型输出八个字段。
| 抽取字段 | 说明 | 典型问题 |
|---|---|---|
| PMID | 文献编号 | 无 |
| Publication date | 发表日期 | 无 |
| Journal | 期刊名 | 无 |
| Reported gene | 基因符号 | 同基因多名需归一 |
| Mutation description | 突变描述 | c. 与 p. 混写 |
| Mutation type | 突变类型 | 需映射到 23 类枚举 |
| Inheritance pattern | 遗传模式 | 摘要常不写,返回破折号 |
| Associated disease | 疾病名 | 病例报道常写成一段描述 |
| One-sentence summary | 主要结论一句话 | 用于人工快速判断 |
模型被明确要求:字段在摘要里找不到就返回破折号。这条约定的后果是「破折号」承担了两种含义——真的没有,以及「有但模型没找到」。这两个在数据里不可区分,是所有下游统计必须先想清楚的前提。
3.3 评测:一千篇摘要的准确率
作者随机抽 1,000 篇摘要做人工评测,结论如下。
| 指标 | 数值 | 说明 |
|---|---|---|
| 抽出记录数 | 1,443 | 876 条正、567 条负 |
| 总体准确率 | 98.9%(1,427/1,443) | 与摘要交叉验证 |
| 正例召回 | 99.1%(868/876) | 三实体齐全者 |
| 负例正确率 | 98.6%(559/567) | 摘要本身不含完整关系者 |
98.9% 这个数字要放在正确的语境里读:它衡量的是「模型抽出来的东西与摘要是否一致」,不是「抽出来的东西在生物学上是否成立」。摘要本身写错的情况,这个评测抓不到。
3.4 两阶段人工复核与 15 条推断错误
所有抽取结果都要过两遍人工:抽取时做合理性初筛,聚合后再核一遍。核对中发现 69 条记录的核苷酸与氨基酸改变对不上。
| 不一致的构成 | 条数 | 结论 |
|---|---|---|
| 回查摘要后确认抽取正确 | 54 | 摘要原文即如此写法 |
| 摘要只给蛋白层,核苷酸由模型反推 | 15 | 反推错误 |
这 15 条是本库唯一被官方点名的系统性错误,规模很小(占全库千分之一量级),但性质重要:模型会在信息不全时补全。它由此催生了 Tier 分级——Tier 1 是摘要明确写出,Tier 2 是模型从间接信息推断。全库 Tier 2 只有 32 条。
3.5 序列与功能注释
抽取只是拿到字符串,要让字符串变成可比较的变异,需要一串外部工具。
| 步骤 | 工具 / 参考 | 作用 |
|---|---|---|
| 基因组坐标 | UCSC Table Browser,GRCh38 | 定位到染色体 |
| 转录本选择 | GENCODE V48 | 每突变选最具代表性的一条转录本 |
| 序列映射 | CDS 与蛋白序列 | 展示变更前后对照 |
| 功能预测 | SIFT | deleterious / tolerated |
| 功能预测 | PolyPhen-2 | probably / possibly damaging |
| rsID 判定 | Ensembl VEP | 是否在 dbSNP 有编号 |
| 人群频率 | gnomAD | 总体与十个祖源分层 MAF |
功能预测的分布值得记住:能映射到 SIFT 的 5,971 条中,87.0% 被判 deleterious;能映射到 PolyPhen-2 的 5,388 条中,76.8% 被判 probably 或 possibly damaging;两个工具都判有害的 3,968 条构成高置信子集。
3.6 疾病与基因的术语归一
疾病名先人工整理,再用 Jaro-Winkler 字符串相似度模糊匹配到 Disease Ontology,匹配结果全部人工复核。罕见病判定同样是「模糊匹配 + 人工核验」。
| 参照库 | 匹配到的条数 | 百分比 | 含义 |
|---|---|---|---|
| Disease Ontology | 2,086 | 46.3% | 有结构化编号 |
| Orphanet | 1,685 | 37.4% | 属罕见病目录 |
| GWAS Catalog | 491 | 10.9% | 有常见变异 GWAS 数据 |
46.3% 这个比例常被误读成「质量差」。实际上它反映的是疾病命名的本来状态:病例报道里大量疾病名是「X 综合征伴 Y 和 Z」这种描述,没有对应本体条目。作者的处理是保留原文描述,而不是硬套一个编号——这个取舍是对的,代价是下游做疾病聚合时必须自己再做一次归一。
3.7 案例:从听力损失到 104 个基因
用「hearing loss」与「deaf」检索,得到 300 条记录、180 篇文献。这个案例最能说明库的形状。
| 维度 | 数值 | 说明 |
|---|---|---|
| 记录数 | 300 | 来自 180 篇文献 |
| 基因数 | 104 | 论文指出既往文献报过 60 余个 |
| 最常见基因 | KCNQ4、MYO15A、CDH23、GJB2、PKHD1L1 | 均是该领域长期研究过的基因 |
| 疾病分型 | 非综合征型占主导,含 DFNA 与隐性、X 连锁亚型 | 也有综合征型描述 |
§3.7 的案例说明一件事:在同一疾病内部,这个库的记录密度高度不均。少数「明星基因」占据大量记录,机制未明的基因可能只有一两条。做疾病内基因排序时,记录数反映的是研究热度,不是致病贡献。
3.8 案例:自闭症里两种证据的错位
第二个案例是自闭症谱系障碍(ASD)。库里有 99 条记录、65 个基因、67 篇文献,全部来自病例报道中的蛋白编码突变。
作者拿 ASD 的 GWAS 汇总统计做了 MAGMA 基因水平分析,结果是没有一个基因达到全基因组显著,但有九个基因名义显著(P 在 0.0035 至 0.048 之间),包括 DNM1、RERE、FOXP1、NCL、CUL3、NASP、KCNMA1、SETD2、MBD5。
| 证据类型 | 来源 | 结论强度 |
|---|---|---|
| 罕见的高外显率突变 | 本库的病例报道 | 个体层面强,群体层面无法估计频率 |
| 常见变异关联 | GWAS + MAGMA | 群体层面可估,单基因效应弱 |
| 两者交集 | 上述九个基因 | 名义显著,未过全基因组阈值 |
§3.8 的案例给出的是「怎么正确读这个库」:它提供的是罕见变异一侧的证据,与常见变异证据并列而不是替代。把两边混成一句「这个基因与 ASD 有关」,会丢掉证据类型这一关键限定。
3.9 检索式的取舍:为什么是十把钥匙
十类关键词不是随便挑的,它对应的是临床报告里最常见的几种写法。
| 关键词 | 想抓的东西 | 漏掉的东西 |
|---|---|---|
| missense | 错义替换的完整描述 | 只说「变异」不说替换类型的研究 |
| nonsense | 提前终止 | 把无义归入「截短」的写法 |
| de novo | 新发突变的家系描述 | 未提家系的研究 |
| frameshift | 移码 | 只说 indel 不说移码的写法 |
| splice-site | 剪接位点 | 只说内含子变异的写法 |
| in-frame | 框内插入缺失 | — |
| stop-loss | 终止丢失 | 极少数报道 |
| start-loss | 起始丢失 | 极少数报道 |
| synonymous | 同义 | 常被当作「不致病」而不报 |
| protein-coding | 泛指编码区突变 | 非编码区一切 |
这张表读出来的结论是:检索式是召回优先的,它要的是「凡是用这些词写过的研究都进来」,代价是漏掉用别的词写的同一类研究。反过来说,这也解释了为什么某些类别的文献量差三个数量级——终止丢失只有 24 篇,不是这类突变少,而是这样写的报道少。
值得注意最后一行。锁定 protein-coding 意味着非编码区的调控变异、深内含子变异、拷贝数变异全部不在范围内。做全基因组解读的团队要清楚:这个库覆盖的是编码区,不是全基因组。
3.10 抽取评估的方法学细节
一千篇的评测有三种可能的失败模式,论文的处理方式各有不同。
| 失败模式 | 表现 | 评测能否发现 |
|---|---|---|
| 漏抽 | 摘要里有三元组,模型没抽 | 能,计入召回 |
| 错抽 | 模型抽出的关系与摘要不符 | 能,计入准确率 |
| 摘要本身写错 | 模型忠实还原了错误内容 | 不能,评测口径不覆盖 |
| 推断补全 | 摘要信息不全,模型自行补 | 部分能,靠人工回查发现 |
第三种是最容易被忽略的:如果摘要本身把基因写错、把突变写错,模型抽得再准也是错的。库内所有记录的准确率上限因此不是 100%,而是「摘要的平均正确率」。
第四种正是 15 条核苷酸推断错误的来源。评测阶段没有暴露它,是后续人工复核时发现的——这说明评测与复核承担不同的职责:评测看一致性,复核看合理性。
3.11 转录本选择的后果
同一条突变,在不同转录本上的编号可能完全不同。作者的处理是每突变选一条最具代表性的转录本。
| 选择 | 好处 | 代价 |
|---|---|---|
| 统一用 GENCODE V48 的代表转录本 | 全库一致、可复现 | 与原文报告的转录本可能不同 |
| 按原文报告的转录本 | 与文献一致 | 全库不可比 |
| 同时保留两套编号 | 最完整 | 工作量翻倍,未采用 |
这个取舍的后果在跨库比对时最明显:拿库里的 c. 编号去 ClinVar 检索,可能找不到——因为 ClinVar 用的是另一条转录本。稳妥的做法是先用 rsID 匹配,只有 rsID 缺失时才用基因 + 蛋白层描述匹配。
§4 内容层的三个维度
4.1 基因维度:94.1% 落在 OMIM 里
| 参照基因集 | 参照总数 | 交集 | 百分比 | Fisher P |
|---|---|---|---|---|
| ClinVar 基因 | 19,250 | 3,330 | 94.7% | 2.7e-138 |
| OMIM 基因 | 17,451 | 3,309 | 94.1% | 9.0e-296 |
| 管家基因 | 3,804 | 636 | 18.1% | 0.008 |
| 抑癌基因 | 1,217 | 309 | 8.8% | 7.7e-33 |
| DNA 损伤修复基因 | 219 | 78 | 2.2% | 9.2e-13 |
94.1% 与 OMIM 重合,说明这个库在基因层面几乎完全落在已知的孟德尔基因集合内,没有引入大量新基因。抑癌基因只占 8.8%,说明它不是肿瘤库——这一点常被误解,因为「突变」二字容易让人联想到体细胞突变。
记录最多的基因是 FBN1,46 条,跨 7 种突变类型、14 种疾病;关联疾病最多的是 LMNA,22 种,横跨肌营养不良、心肌病、脂肪代谢障碍与早老症四类。
4.2 疾病维度:长尾与孤点
| 结构指标 | 数值 | 含义 |
|---|---|---|
| 只关联一个基因的疾病 | 3,796 | 占全部疾病的八成以上 |
| 只关联一种疾病的基因 | 2,074 | 占全部基因的近六成 |
| 关联基因最多的疾病 | 神经发育障碍,81 个基因、8 种突变类型 | 通路富集集中在突触功能与神经信号 |
| 突变类型与通路的偏向 | 错义偏向神经信号与激素通路;无义偏向细胞分裂与细胞骨架 | 论文按类型分别做富集 |
| Charcot-Marie-Tooth 病 | 103 条、64 篇、24 个亚型 | 病例报道的典型颗粒度 |
「孤点」是这张表最该被记住的数字。八成以上的疾病只连一个基因,意味着做疾病-基因网络分析时,绝大多数节点是度为 1 的端点。网络拓扑指标(聚类系数、模块度)在这种图上没有解释力,只有少数枢纽节点值得看。
4.3 变异维度:63.7% 不在 ClinVar
| 对比项 | 重合 | 对方独有 | 本库独有 |
|---|---|---|---|
| ClinVar | 4,136 条(36.3%) | 3,592,675 个变异 | 63.7% |
| COSMIC | 323 条 | 1,179,850 个变异 | 绝大多数 |
两组数字的对比方式不同,读法也不同。与 ClinVar 的对比是「同一层级」的:两者都在收集疾病相关变异,交集 36.3% 说明各自都有对方没有的内容。与 COSMIC 的对比层级不齐:COSMIC 是肿瘤体细胞库,体量百万级,交集只有 323 条属于正常。
57.6% 的变异在 dbSNP 有 rsID,这批里有 97.0% 的 MAF 低于 0.05。这两个数字合起来说明:即便是「有编号」的那部分,也绝大多数是罕见变异,人群频率这一列对常见变异筛查没有参考价值。
4.4 案例:LMNA 的 22 种疾病
LMNA 编码核纤层蛋白 A/C,一个基因对应二十多种表型,是本库「一基因多病」的代表。
| 维度 | 数值 |
|---|---|
| 关联疾病数 | 22 |
| 疾病大类 | 肌营养不良、心肌病、脂肪代谢障碍、早老症 |
| 本库收录的突变类型 | 错义、无义、移码、剪接位点 |
| 在库内记录数 | 35 条(按基因检索口径) |
§4.4 的案例提示一个反向风险:当使用者按疾病检索时,LMNA 会反复出现,容易被误读成「该病的主要致病基因」。实际上它同时是二十多种病的基因,出现频次高是因为表型谱宽,而不是因为它在某一个病里贡献最大。
4.5 场景:一个意义未明的错义突变怎么走
变异解读里最常见的一类问题是意义未明的错义突变(variant of uncertain significance)。三个最常用的动作是按基因检索、看疾病分布、回读原文。
| 动作 | 在本库的操作 | 得到什么 | 判读价值 |
|---|---|---|---|
| 按基因检索 | 输入基因符号 | 该基因全部记录的疾病分布 | 判断这个基因是否集中在某类表型 |
| 看同病其他突变 | 按疾病检索 | 同一疾病下的其它基因与突变类型 | 判断表型是单基因还是遗传异质 |
| 覆盖度检查 | 看该基因条目数相对于领域常报基因的量级 | 文献是否被抽到 | 区分「文献没有」与「我没找到」 |
| 回读原文 | 点 PMID | 病例细节 | 判读的唯一有效输入 |
第一与第三个动作的区别值得强调。按基因检索得到空结果时,有两种可能:这个基因确实没被报道过,或者它被报道过但检索式没覆盖到。区分办法是看这个基因在 OMIM 里有没有条目、在 ClinVar 里有没有记录——两个都没有,才可以初步认定「真的没人报过」。
§4.5 的案例给出的是一条排除法路径:本库缺席 + OMIM 缺席 + ClinVar 缺席,三者同时成立才是强证据;只在本库缺席,只能说明抽取没覆盖到。
4.6 基因-疾病骨架的稀疏性
把全部记录压成基因-疾病二部图,得到的图非常稀疏。
| 指标 | 近似值 | 计算口径 |
|---|---|---|
| 可能的基因-疾病组合 | 千余万 | 基因数乘疾病数 |
| 实际出现的组合 | 一万余 | 三元组去重后 |
| 稀疏度 | 千分之一量级 | 实际除以可能 |
| 度为 1 的节点占比 | 六成以上 | 只连一个对端的节点 |
这种稀疏图的常见误用是拿它跑图神经网络,然后报告一个很高的链接预测 AUC。高 AUC 主要来自「绝大多数组合不存在」这一先验,而不是模型学到了生物学规律。想让它有意义,必须给出基于度的基线(比如按基因研究热度排序的命中率)。
§5 怎么拿到数据
5.1 四种取数路径与各自的天花板
| 路径 | 形式 | 自动化程度 | 适用 |
|---|---|---|---|
| Browse 页浏览与筛选 | 表格分页 | 手动 | 探索、抽查 |
| Browse 页导出 | 浏览器内生成 XLSX | 半自动 | 批量取当前筛选结果 |
| 内部 JSON 接口 | POST /api/browse/tableInfo |
全自动 | 脚本化取全库 |
| 单条详情页 | 网页 | 手动 | 看序列与 Sankey 图 |
两条自动路径要说清性质:XLSX 是前端生成的,浏览器把当前查询结果用表格库写成文件,服务端没有对应的导出端点;JSON 接口是前端自己调的,没有公开文档,参数形态只能靠前端脚本反推。
5.2 官网明确给出的取数承诺
官方在论文里写的是「所有展示数据均可免费下载,无需注册」,以及「支持精确与模糊检索、支持用竖线分隔的批量检索,批量检索只支持精确匹配」。这两句是唯一可引用的官方承诺。
| 官方原话(摘要转述) | 含义 | 不要过度解读为 |
|---|---|---|
| 数据免费下载、无需注册 | 没有账号门槛 | 有稳定的公开 API 契约 |
| 批量检索支持竖线分隔 | 一次查多个基因/疾病 | 一次拉全库 |
| 每三个月更新一次 | 有维护计划 | 有版本号或 changelog 可查 |
| 鼓励通过 Contact 报告问题 | 有反馈渠道 | 有 issue tracker |
5.3 全量取数的脚本
下面的脚本按页拉取,依赖接口的四个字段:page、pageSize 从 1 起算,orderBy 与 orderType 决定排序。分页必须带稳定排序,否则翻页会重复或漏行。
#-- 目录假设:脚本放在任意目录,输出写到 ./seekpcmdb/entries.jsonl
#-- 前置:能访问 https://ngdc.cncb.ac.cn/seekpcmdb/api
import json, time, urllib.request
API = "https://ngdc.cncb.ac.cn/seekpcmdb/api"
BODY = {"orderBy": "gene", "orderType": "ascending",
"pmid": [], "gene": [], "variantType": [], "disease": [],
"pmidExact": False, "geneExact": False,
"variantTypeExact": False, "diseaseExact": False}
def fetch_page(page, size=200):
body = dict(BODY, page=page, pageSize=size)
req = urllib.request.Request(
API + "/browse/tableInfo",
data=json.dumps(body).encode(),
headers={"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(req, timeout=60) as r:
return json.loads(r.read())["data"]
first = fetch_page(1)
total, size = first["total"], 200
pages = (total + size - 1) // size
print("total", total, "pages", pages)
with open("seekpcmdb/entries.jsonl", "w", encoding="utf-8") as f:
for p in range(1, pages + 1):
d = first if p == 1 else fetch_page(p)
for row in d["list"]:
f.write(json.dumps(row, ensure_ascii=False) + "\n")
time.sleep(0.5) #-- 限速,避免触发服务端保护
print("done")
三个坑都在这段里处理了:筛选项一律传空数组而不是 null(传 null 会得到 400);必须带 orderBy,否则分页顺序不稳定;每页之间留半秒间隔,服务端对连续请求偶尔直接断连。
5.4 只查某个基因
日常最常用的操作是按基因取全部记录。把 gene 传成数组,geneExact 控制精确与模糊。
#-- 目录假设:与上一段同目录,复用 fetch_page
import json
def by_gene(symbol, exact=True, size=100):
body = dict(BODY, page=1, pageSize=size, gene=[symbol], geneExact=exact)
req = urllib.request.Request(
API + "/browse/tableInfo",
data=json.dumps(body).encode(),
headers={"Content-Type": "application/json", "User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(req, timeout=60) as r:
return json.loads(r.read())["data"]
d = by_gene("LMNA")
print("records", d["total"])
for row in d["list"][:5]:
print(row["variant"], row["variantType"], row["variantTier"], row["disease"])
5.5 用官方下拉接口做候选词校验
站点首页与检索页的候选词来自四个建议接口,它们返回的是全库去重后的词表,可以直接当受控词表用。
#!/usr/bin/env bash
#-- 目录假设:输出写到当前目录 vocabs/
#-- 四个建议接口各自返回 value/id 数组,id 即库内编号
set -euo pipefail
mkdir -p vocabs
BASE="https://ngdc.cncb.ac.cn/seekpcmdb/api"
for ep in suggestionGene suggestionDisease suggestionVariantType; do
curl -fsSL --http1.1 -A "Mozilla/5.0" \
-H "Accept: application/json" \
"$BASE/browse/$ep" -o "vocabs/$ep.json"
echo "$ep $(wc -c < "vocabs/$ep.json") bytes"
done
#-- 用法:jq '.data | length' vocabs/suggestionVariantType.json
这批词表的价值在于编号与名字的对应:variantTypeId 从 1 到 23,diseaseId 与 geneId 是全库唯一稳定键。自己下载全库后做连接,用它比自己造映射表可靠。
5.6 取数时的服务端行为
| 现象 | 触发条件 | 应对 |
|---|---|---|
| 400 Bad Request | 筛选项传 null,或缺 orderBy |
一律传空数组 + 固定排序键 |
| 连接被直接断开 | 短时间内高频请求 | 请求间留间隔,失败后退避重试 |
| 只返回当前页 | pageSize 过大被服务端截断 |
用 100 或 200,按 total 自己算页数 |
| 导出文件与接口不一致 | XLSX 只有六列 | 要内部编号时走接口,不走导出 |
最后一行是实际操作中最容易踩的:用导出表做分析,做完了想按 geneId 合并别的东西,才发现导出表根本没有 geneId。
5.7 增量更新与快照
论文写明每三个月整体更新一次。对做时间序列分析的人来说,这意味着两次抓取之间可能相差数百条记录。
| 做法 | 实现 | 适合 |
|---|---|---|
| 全量快照 | 每次抓全库存一份,按日期命名 | 要追溯变化 |
| 增量追加 | 只抓新增页,按 PMID 差集合并 | 只关心总量 |
| 主键快照 | 只存 gene/variant/disease/pmid 四列 | 要控体积 |
推荐第一种,因为库没有版本号,唯一的版本标识就是抓取日期。快照目录用 YYYYMMDD 命名,配合一个 meta.json 记录当时的 total,就能在两个月后回答「这期间新增了多少条」。
5.8 云端笔记本的最小流程
不想装环境时,云端笔记本里三步就能跑通:装依赖、抓一页看看、再决定要不要全量。
#!/usr/bin/env bash
#-- 目录假设:在任意云端 shell 里执行,依赖只有 python3 与 curl
#-- 第一步:确认接口活着,拿到总数
curl -fsSL --http1.1 -A "Mozilla/5.0" \
-X POST -H "Content-Type: application/json" \
-d '{"page":1,"pageSize":1,"orderBy":"gene","orderType":"ascending","pmid":[],"gene":[],"variantType":[],"disease":[],"pmidExact":false,"geneExact":false,"variantTypeExact":false,"diseaseExact":false}' \
https://ngdc.cncb.ac.cn/seekpcmdb/api/browse/tableInfo \
| python3 -c 'import sys,json; d=json.load(sys.stdin)["data"]; print("total", d["total"])'
#-- 第二步:确认建议接口给出的受控词表规模
for ep in suggestionGene suggestionDisease suggestionVariantType; do
n=$(curl -fsSL --http1.1 -A "Mozilla/5.0" \
"https://ngdc.cncb.ac.cn/seekpcmdb/api/browse/$ep" \
| python3 -c 'import sys,json; print(len(json.load(sys.stdin)["data"]))')
echo "$ep $n"
done
这段脚本只做两件事:确认总数、确认词表规模。它的价值是把「能不能取数」这个判断压到十秒内完成,而不是先写一大段爬虫再发现接口变了。
5.9 取数失败时的三条退路
| 退路 | 做法 | 代价 |
|---|---|---|
| 回到导出表 | 在 Browse 页筛选后点下载 | 只有六列,无内部编号 |
| 用前端脚本反推 | 读站点静态资源里的请求常量 | 每次接口变动都要重做 |
| 换上游 | 直接用 PubMed 检索式自己重跑抽取 | 等于重建一个库 |
第三条虽然成本最高,但在一种情况下反而最合理:需要的时间跨度比库的版本更早,或者要覆盖摘要之外的全文。检索式是公开的,十类关键词与字段定义都在论文里,照着做一遍得到的是自己的库。
§6 与库内其它条目的关系
6.1 关系图谱
| 关联条目 | 关系类型 | 分工 |
|---|---|---|
| ClinVar | 互补(交集 36.3%) | ClinVar 给临床解读,本库给文献陈述 |
| OMIM | 上游概念 | OMIM 给基因-疾病,本库给具体突变 |
| gnomAD | 上游数据 | 本库的 MAF 列来自 gnomAD |
| Disease Ontology | 术语标准 | 本库 46.3% 的疾病有 DO 编号 |
| Orphanet | 术语标准 | 罕见病判定依据 |
| COSMIC | 同层但不同域 | 肿瘤体细胞 vs 生殖系疾病 |
| dbsnp | 编号来源 | 57.6% 的变异有 rsID |
6.2 检索路径
三类问题三种入口,走错门会白费时间。
| 我要问的问题 | 从哪个入口进 | 为什么 |
|---|---|---|
| 这个基因有哪些被报道的突变 | 首页按基因检索 | 基因符号是最稳的键 |
| 这个病关联哪些基因 | 首页按疾病检索 | 疾病名是自由文本,用模糊匹配 |
| 这类突变偏向哪些通路 | Knowledge Graph 页的 GO 富集 | 疾病关联基因数 ≥10 才出富集 |
| 某个具体变异有没有人报 | 首页按突变类型 + Browse 组合筛 | 无突变位点精确检索,需组合 |
| 这批基因的文献证据有多少 | Browse 检索后导出 | 导出表带 PMID,可回溯 |
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
三种最常见的误判先把话说开。第一,把记录数当证据强度:一条记录代表一次文献报告,同一突变被三个人报过与只被一个人报过,记录数一样。第二,把破折号当缺失:遗传模式与部分疾病字段的破折号,既可能是摘要没写,也可能是模型没抽到。第三,把 98.9% 当生物学准确率:它衡量的是抽取与摘要一致,不衡量摘要本身对不对。
这三种误判的共同根源是把「文献事实」与「生物学事实」混为一谈。本库自始至终只承诺前者。
7.1 五维评分
| 维度 | 分数 | 理由 |
|---|---|---|
| 覆盖广度 | 3/5 | 只覆盖摘要,只覆盖 WES/WGS 文献,罕见病为主 |
| 记录深度 | 4/5 | 序列映射、双工具预测、频率、遗传模式俱全 |
| 可及性 | 3/5 | 免费无门槛,但无公开 API 文档,导出表缺内部键 |
| 可追溯性 | 5/5 | 每条记录带 PMID,可逐条回原文 |
| 可维护性 | 3/5 | 论文承诺季度更新,但站点无版本号与变更记录 |
7.2 与外部库的口径对照
| 对照对象 | 本库口径 | 对方口径 | 直接比较的风险 |
|---|---|---|---|
| ClinVar | 文献陈述的突变 | 提交的临床解读 | 一个是「有人写过」,一个是「有人判过」 |
| COSMIC | 生殖系疾病突变 | 肿瘤体细胞突变 | 域不同,交集本应很小 |
| HGMD | 文献突变 | 文献突变(订阅制) | 论文明确说因订阅限制未做大规模比对 |
| OMIM | 具体突变 | 基因-疾病条目 | 层级不同,不可比计数 |
7.3 已知的、可枚举的偏差
| 偏差 | 表现 | 严重度 | 缓解 |
|---|---|---|---|
| 只读摘要 | 正文与补充材料中的突变缺失 | 高 | 对关键基因另做全文检索 |
| 检索式偏向 | 靶向 panel 研究、病例报道欠代表 | 中高 | 结论限定在大规模测序研究范围内 |
| 研究热度偏差 | 明星基因记录数远超冷门基因 | 高 | 记录数只用于检索排序,不用于致病贡献排序 |
| 罕见病偏差 | 与 Orphanet 重合 37.4%,与 GWAS Catalog 只有 10.9% | 高 | 常见病问题到别处查 |
| 模型推断偏差 | 32 条 Tier 2 为推断记录 | 低 | 统计时排除 Tier 2 看两版结果 |
| 祖源偏差 | gnomAD 频率的分层继承其样本构成 | 中 | 做频率解读时注明祖源 |
| 命名不一致 | 疾病名为自由文本,含大小写与复数变体 | 中 | 按 DO 编号二次归一 |
7.4 DAIMS 二十四项
| # | 检查项 | 状态 | 说明 |
|---|---|---|---|
| 1 | 宽格式 | ✅ | 一条记录一行,字段平铺 |
| 2 | 唯一标识 | ⚠️ | 有 geneId 与 diseaseId,但记录本身无独立 ID |
| 3 | 特殊字符 | ⚠️ | 突变描述含 c.、p.、* 与大于号 |
| 4 | 重复行 | ⚠️ | 同一三元组多文献报道会重复出现,官方未去重 |
| 5 | 缺失编码 | ⚠️ | 统一用破折号,「未写」与「未抽到」不可分 |
| 6 | 标签标识 | ✅ | 突变类型、Tier、遗传模式均为枚举 |
| 7 | 罕见类分组 | ✅ | 23 类突变类型已归并 |
| 8 | 偏倚评估 | ✅ | 论文讨论检索式与摘要层的局限 |
| 9 | 数据字典 | ⚠️ | 字段说明散在论文与页面,无独立字典 |
| 10 | 信息性缺失解释 | ❌ | 破折号的成因未在字段层解释 |
| 11 | 设备记录 | ✅ | 不适用(文献衍生),已声明 |
| 12 | 共线性 | ⚠️ | 基因间高度相关,未提示 |
| 13 | 编码映射 | ⚠️ | 疾病 46.3% 有 DO 编号,其余无 |
| 14 | 时间戳处理 | ⚠️ | 有文献发表日期,无记录入库时间 |
| 15 | 划分建议 | ❌ | 无官方训练测试划分 |
| 16 | 泄漏讨论 | ❌ | 无相关说明 |
| 17 | 标签分布 | ✅ | 突变类型与遗传模式占比齐备 |
| 18 | 测量偏倚 | ✅ | 摘要层与检索式局限均有讨论 |
| 19 | 外部验证建议 | ✅ | 与 ClinVar、COSMIC 做了交叉比对 |
| 20 | 版本记录 | ⚠️ | 论文写 v1.0,站点无版本号 |
| 21 | 预处理脚本 | ⚠️ | 抽取流程描述完整,未开源代码 |
| 22 | 合规要求 | ✅ | 免费开放,数据来源为公开摘要 |
| 23 | 多模态对齐 | ✅ | 不适用(单模态),已声明 |
| 24 | 去标识化 | ✅ | 不含患者标识 |
DAIMS 评分:13.5 / 24。扣分集中在「给下游准备元信息」这一类:缺失编码、重复行、划分建议、泄漏讨论四项全无或含糊。
评分解读:对文献型知识库,这个分数属中等。加分项来自它把每一项外部标注(SIFT、gnomAD、DO)都标了来源与访问日期,这在同类库里并不常见;扣分项来自它把记录当成品交付,没有把「怎么用」写进字段层。
对你意味着什么:动手前补三件事——自己按 PMID 去重一次、把 Tier 2 单独标出来、把疾病名按 DO 编号重建一次。三件事做完,扣分项里的重复行、缺失编码、编码映射三项的实际影响可以压到很低。
7.5 它为何能持续:机构托底加季度节奏
支撑来自中国科学院战略性先导专项与自然科学基金,挂在国家生物信息中心的数据库体系下,与同一课题组此前建的门户(如 CPAD、CancerSEA 一类功能注释资源)形成同构的技术栈。存储与检索成本对文献型知识库很低——一万余条记录的表在 MySQL 里只是小表——真正的成本在抽取与复核的人力。
这一点解释了论文里两个看似矛盾的承诺:一边说「每三个月整体更新」,一边说「人工复核会限制可扩展性」。「每三个月」针对的是增量(重新检索 PubMed),不是全量重抽;后者要随模型能力与抽检策略升级。对使用者意味着:版本节奏由机构决定,抓数那天务必记下抓取日期。
§8 生态位与历史
8.1 它出现的时间点
| 时间 | 事件 |
|---|---|
| 2025-05-08 | 首批 missense 文献入库 |
| 2025-05-20 | 补入 nonsense 类文献 |
| 2025-06-11 | 补入 de novo 类文献 |
| 2025-07-02 | 五类合并检索完成 |
| 2025-11-22 | 论文在 NAR 在线 |
| 2025-12-02 | 追加 532 篇文献并更新既有条目 |
| 2026 | NAR 数据库专辑收录(54 卷 D1 期) |
8.2 在文献抽取这条线上的位置
它自称是第一个把大模型用于突变信息抽取的数据库。这个「第一」的可验证边界是「突变-基因-疾病三元组」这个颗粒度;更早的大模型抽取工作集中在命名实体识别与关系抽取的通用任务上。
真正的差别不在模型,而在把评测写进了流程:先抽一千篇做人工评测,再决定上全量;抽完再过两遍人工;发现不一致就人工回查,再把不一致拆成「原文如此」与「模型推断」两类。这套流程比 98.9% 这个数字更值得抄。
8.3 同赛道的其他做法
| 做法 | 代表 | 与本库的区别 |
|---|---|---|
| 人工精读全文 | HGMD | 质量高、规模小、订阅制 |
| 实验室提交 + 专家panel | ClinVar | 有临床分级,覆盖存在提交偏倚 |
| 规则抽取 | 早期文献挖掘库 | 精度高但召回低,难处理自由表述 |
| 大模型抽取摘要 | 本库 | 召回高,需要人工复核兜底 |
| 大模型抽取全文 | 后续方向 | 论文已列为规划 |
8.4 更新的公开说明
论文写明的更新策略有四条:每三个月重新检索 PubMed、跟踪大模型能力并相应迭代抽取流程、定期同步外部参考库(NCBI 基因注释、ClinVar、Disease Ontology)、通过 Contact 收集反馈。四条都是方向性承诺,没有给出具体排期或版本号。
8.5 从文献抽取到知识图谱的四条正交选择
做同类库时,四组选择彼此正交,每一组都影响最终产物的形状。
| 维度 | 选择 A | 选择 B | 本库的选择 | 后果 |
|---|---|---|---|---|
| 输入层 | 只读摘要 | 读全文与补充材料 | A | 召回受限于摘要 |
| 抽取器 | 规则或序列标注 | 大语言模型 | B | 召回高、需人工兜底 |
| 置信分层 | 不分层 | 分两层及以上 | B(两层) | 使用者可自行取舍 |
| 疾病归一 | 保留原文 | 强制映射本体 | 折中(能映则映) | 46.3% 有编号 |
四组里最值得讨论的是第三组。不分层的库,使用者拿到一条记录只能全信或全不信;分层的库,研究者可以算两遍——含 Tier 2 一遍、排除 Tier 2 一遍——看结论是否稳健。这是把「不确定性」当字段而不是当脚注的做法。
8.6 它回答不了的问题清单
把边界写成问题形式,比写成形容词好用。
| 问题 | 为什么回答不了 |
|---|---|
| 这个突变在某个民族的频率是多少 | 频率来自 gnomAD,本库只是转引 |
| 这个突变在健康人群里常见吗 | 需要对照组,摘要通常不报 |
| 这个基因的突变一律致病吗 | 需要外显率与不完全外显的讨论,摘要少有 |
| 这个病在人群中的患病率 | 与文献抽取无关 |
| 这个突变影响哪个结构域 | 只有序列层,无结构注释 |
| 同一突变在儿童与成人中表现是否不同 | 年龄字段不在抽取范围内 |
| 这个突变是新发的吗 | 摘要有时写 de novo,但未做成字段 |
第三与第七两条最常被误以为「库里应该有」。实际上 de novo 只作为检索关键词出现,并未成为独立字段;外显率则完全不在抽取目标里。
§9 使用指引
9.1 三种角色的最短路径
| 角色 | 第一步 | 第二步 | 第三步 |
|---|---|---|---|
| 变异解读人员 | 按基因符号检索 | 排除 Tier 2,看 Tier 1 记录的疾病分布 | 逐条读 PMID 原文与补充材料 |
| 数据工程师 | 拉全库 JSON | 按 geneId 与 diseaseId 建连接键 | 用 PMID 接原文,用 rsID 接 gnomAD |
| 研究选题者 | 按疾病检索,看基因分布 | 找度为 1 的孤点与度为 1 的枢纽 | 用 GO 富集看通路偏向 |
9.2 一条最短的可用流程
从「手上有一个基因」到「拿到可复核的记录表」,中间只需三步。
#-- 目录假设:data_root/seekpcmdb/ 存放输出
#-- 目标:给定基因,输出按疾病聚合的记录表,标注 Tier 与 PMID
import json, os, urllib.request
from collections import defaultdict
API = "https://ngdc.cncb.ac.cn/seekpcmdb/api/browse/tableInfo"
os.makedirs("data_root/seekpcmdb", exist_ok=True)
def query(gene):
body = {"page": 1, "pageSize": 500, "orderBy": "gene", "orderType": "ascending",
"gene": [gene], "geneExact": True,
"pmid": [], "variantType": [], "disease": [],
"pmidExact": False, "variantTypeExact": False, "diseaseExact": False}
req = urllib.request.Request(API, data=json.dumps(body).encode(),
headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=60) as r:
return json.loads(r.read())["data"]["list"]
gene = "FBN1"
rows = query(gene)
by_disease = defaultdict(list)
for r in rows:
by_disease[r["disease"]].append(r)
print("基因", gene, "记录", len(rows), "疾病", len(by_disease))
for d, rs in sorted(by_disease.items(), key=lambda kv: -len(kv[1]))[:5]:
tiers = [x["variantTier"] for x in rs]
print(f"{d:45s} n={len(rs):3d} tier2={tiers.count('tier2')} pmids={len({x['pmid'] for x in rs})}")
with open(f"data_root/seekpcmdb/{gene}.jsonl", "w", encoding="utf-8") as f:
for r in rows:
f.write(json.dumps(r, ensure_ascii=False) + "\n")
第三步输出的表就是复核清单:疾病名、记录数、Tier 2 条数、独立文献数。四个数字里,独立文献数最容易被忽略——同一篇文献报三个突变会形成三条记录,按记录数排序会把这类文献顶上去。
9.3 引用方式
引用本库时,除主论文外建议写清:数据抓取日期、是否排除了 Tier 2、疾病名是否做过本体归一。三者决定别人能否复现你的计数。
@article{yang2026seekpcmdb,
title = {SeekPCMdb: knowledge on disease-associated protein-coding mutations},
author = {Yang, Peng and Wang, Ziyang and Xiong, Tuo and Fang, Zhanjie and Zhu, Xiuli
and Yao, Lilin and Cui, Ying and Wei, Rongxing and Qian, Zhiming
and Wang, Jian and Wang, Yin-Ying and Jia, Peilin},
journal = {Nucleic Acids Research},
volume = {54},
number = {D1},
pages = {D1646--D1657},
year = {2026},
doi = {10.1093/nar/gkaf1221}
}
9.4 一篇论文里该怎么写方法段
用这个库做了分析,方法部分至少要交代五件事,缺一件别人就复现不了。
| 要写清的项 | 写法示例 | 为什么必须写 |
|---|---|---|
| 抓取日期 | 数据于某年某月自官方接口获取 | 库无版本号,日期是唯一版本标识 |
| 总量口径 | 抓取时接口返回多少条记录 | 与论文正文的数字可能不同 |
| 去重规则 | 按 PMID 与突变描述合并或不去重 | 决定统计量的分母 |
| Tier 处理 | 全部保留或排除 Tier 2 | 直接影响计数 |
| 归一方式 | 疾病是否映射到 DO | 决定疾病层统计 |
第三项最容易被漏掉。若不做去重,同一篇文献报三个突变会算三次,同一突变被三篇文献报也会算三次,两个「三」的性质完全不同,却都叫「记录数」。
9.5 三类常见后续分析的做法
| 分析 | 数据准备 | 主要指标 | 常见陷阱 |
|---|---|---|---|
| 基因层富集 | 按疾病取基因集 | GO 或 KEGG 富集显著性 | 背景基因集用错(应为本库基因全集) |
| 突变类型比较 | 按类型分组 | 各类型在通路上的偏向 | 类型间基因数差异极大,需按基因数归一 |
| 知识图谱补边 | 三元组建图 | 链接预测的精确率与召回 | 用度基线对照,否则 AUC 虚高 |
| 文献计量 | 按年份与期刊聚合 | 报告量随时间的变化 | 检索式截止日期不同会截断曲线 |
第二项值得展开。论文给了错义与无义在通路上偏向不同的结论,但这个结论的可靠性依赖基因数:错义记录数是无义的四倍多,直接把两组的富集 P 值并排比较,等于比较两个样本量相差四倍的实验。稳妥做法是先把每组基因数抽稀到相同规模,再比富集。
9.6 一份可直接套用的一致性检查
拿到一批记录后先跑一遍自检,能排掉多数的后续麻烦。
#-- 目录假设:seekpcmdb/entries.jsonl 为 §5.3 的输出
#-- 目标:检查 5 个一致性指标,任何一项异常都说明数据或理解有问题
import json, re
from collections import Counter
rows = [json.loads(l) for l in open("seekpcmdb/entries.jsonl", encoding="utf-8")]
n = len(rows)
tier2 = sum(1 for r in rows if r["variantTier"] == "tier2")
dash = sum(1 for r in rows if r["inheritancePattern"] in ("-", "", None))
nucl = sum(1 for r in rows if re.match(r"^[cn]\\.", r["variant"].strip()))
triplet = len({(r["gene"], r["variant"], r["disease"]) for r in rows})
print("rows", n)
print("tier2 rate", round(tier2 / n, 4))
print("dash inheritance rate", round(dash / n, 4))
print("nucleotide-first rate", round(nucl / n, 4))
print("unique triplets", triplet, "dup rows", n - triplet)
print("top disease", Counter(r["disease"] for r in rows).most_common(3))
五个指标的正常范围:tier2 应远低于百分之一;破折号遗传模式应过半(摘要普遍不写);核苷酸开头的突变描述应占多数;重复行应有几十条;最高频疾病应是神经或心血管一类的大类。任何一项明显偏离,先怀疑取数脚本(比如分页重复取到了同一页),再怀疑库本身。
§10 AI 使用声明
| 项 | 内容 |
|---|---|
| 使用模型 | CodeBuddy Code(大语言模型) |
| 参与范围 | 正文结构、表格、代码示例与 JSON-LD 构建 |
| 输入来源 | 官方首页、官方 JSON 接口返回、NAR 论文全文(PMC) |
| 事实核对 | 全部规模数字取自论文 Results / Table 1-2 与官方接口返回,未做全量下载重算 |
| 未覆盖内容 | 单条详情页的序列查看器内容、Knowledge Graph 页的渲染结果 |
| 分析性内容 | §7.1 五维评分、§7.4 DAIMS 评分、§1.2 与 §1.6 的边界判断为编写者分析 |
| 最后人工审核日期 | 2026-09-05 |
| 页面状态 | published |
常见误读与避坑清单
| # | 常见说法 | 实际情况 | 证据 |
|---|---|---|---|
| 1 | 「这是 ClinVar 的替代品」 | 两者只重合 36.3%,本库无临床分级 | 论文 Discussion 的 4,136/11,395 |
| 2 | 「记录数就是不同突变数」 | 三元组只有 11,338 个,多出的是重复报道 | 论文 Results 三元组计数 |
| 3 | 「它的记录都是可靠的」 | 32 条为模型推断的 Tier 2 | 论文 Results 的 Tier 分布 |
| 4 | 「摘要里没有突变,就是没人报过」 | 正文与补充材料中的突变不在抽取范围 | 论文 Discussion 局限段 |
| 5 | 「它可以估人群频率」 | MAF 转引 gnomAD,且只有 57.6% 有 rsID | 论文 Results |
| 6 | 「98.9% 说明生物学判断准确」 | 评测只比对抽取结果与摘要是否一致 | 论文 LLM performance evaluation |
| 7 | 「疾病名可直接聚合」 | 只有 46.3% 映射到 DO,其余为原文自由文本 | 论文 Table 2 |
| 8 | 「导出表就是全字段」 | 导出只有六列,缺 geneId、diseaseId 与 Tier 编号 | Browse 页导出字段 |
术语表
| 术语 | 含义 |
|---|---|
| PCM | protein-coding mutation,蛋白编码区突变 |
| Tier 1 | 摘要中明确报告的记录 |
| Tier 2 | 模型从间接信息推断的记录 |
| 三元组 | 基因、突变、疾病三者的组合 |
| DOID | Disease Ontology 的编号 |
| SIFT | 基于序列保守性的氨基酸替换有害性预测 |
| PolyPhen-2 | 基于多重序列比对与结构特征的预测工具 |
| gnomAD | 基因组聚集数据库,提供人群频率 |
| VEP | Ensembl 的变异注释工具 |
| MAF | minor allele frequency,次要等位频率 |
| Orphanet | 罕见病与孤儿药目录 |
| 外显率 | 携带特定基因型个体表现出表型的比例 |
| 错义突变 | 改变一个氨基酸的替换 |
| 无义突变 | 提前产生终止密码子的替换 |
| 移码突变 | 改变阅读框的插入或缺失 |
| 剪接位点突变 | 影响内含子剪切的变异 |
| 同义突变 | 不改变氨基酸的替换 |
| 起始丢失 | 破坏起始密码子的突变 |
| 终止丢失 | 破坏终止密码子的突变 |
| 常染色体显性 | 一条等位基因突变即致病 |
| 常染色体隐性 | 两条等位基因均突变才致病 |
| 生殖系突变 | 存在于生殖细胞、可遗传的突变 |
| 体细胞突变 | 仅存在于个体某些细胞、不遗传的突变 |
| 因果推断 | 判断变异与疾病是否存在因果链的分析 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 层级 |
|---|---|---|---|
| 记录数 | 一万一千余条 | 论文 Results | 官方论文 |
| Tier 1 / Tier 2 | 11,363 / 32 | 论文 Results | 官方论文 |
| 三元组数 | 11,338 | 论文 Results | 官方论文 |
| 基因数 | 三千五百余 | 论文摘要 | 官方论文 |
| 疾病数 | 四千五百余 | 论文摘要 | 官方论文 |
| 突变类型 | 23 | 论文摘要 | 官方论文 |
| 检索文献量 | 一万二千余篇 | 论文 Table 1 | 官方论文 |
| 抽取成功文献 | 7,016 | 论文 Results | 官方论文 |
| ClinVar 独有比例 | 63.7% | 论文 Results | 官方论文 |
| DO 映射率 | 46.3% | 论文 Table 2 | 官方论文 |
附录 B:数字来源分层
| 层级 | 内容 | 举例 |
|---|---|---|
| 官方论文 | 规模、分布、比对结果 | 63.7%、46.3% |
| 官方网站 | 更新记录、联系人、查询模块 | 2025-12-02 追加 532 篇 |
| 官方接口 | 实时计数(含入库后新增) | 接口返回的 total 与论文不同 |
附录 C:完整参考文献
- Yang P, Wang Z, Xiong T, et al. SeekPCMdb: knowledge on disease-associated protein-coding mutations. Nucleic Acids Res. 2026;54(D1):D1646–D1657. doi:10.1093/nar/gkaf1221
- Landrum MJ, et al. ClinVar. Nucleic Acids Res. 2018;46(D1):D1062–D1067
- Amberger JS, et al. OMIM. Nucleic Acids Res. 2019;47(D1):D1038–D1046
- Schriml LM, et al. Disease Ontology. Nucleic Acids Res. 2019;47(D1):D955–D962
- Vaser R, et al. SIFT missense predictions. Nat Protoc. 2016;11:1–9
- Adzhubei IA, et al. PolyPhen-2. Nat Methods. 2010;7:248–249
- Karczewski KJ, et al. gnomAD. Nature. 2020;581:434–443
附录 D:任务代码
把全库记录整理成「基因-疾病」二部图,是这套数据最常见的下游用法。
#-- 目录假设:seekpcmdb/entries.jsonl 由 §5.3 脚本生成
import json, itertools
from collections import defaultdict
edges = defaultdict(int)
genes, diseases = set(), set()
with open("seekpcmdb/entries.jsonl", encoding="utf-8") as f:
for line in f:
r = json.loads(line)
edges[(r["gene"], r["disease"])] += 1
genes.add(r["gene"]); diseases.add(r["disease"])
deg_g = defaultdict(int); deg_d = defaultdict(int)
for (g, d) in edges:
deg_g[g] += 1; deg_d[d] += 1
print("基因节点", len(genes), "疾病节点", len(diseases), "边", len(edges))
print("度为 1 的基因", sum(1 for v in deg_g.values() if v == 1))
print("度为 1 的疾病", sum(1 for v in deg_d.values() if v == 1))
print("边权最高", max(edges.items(), key=lambda kv: kv[1]))
输出的两个「度为 1」的数字,正是 §4.2 里那张表想说明的形状:图的大部分是端点,只有少数节点承担连接。
附录 E:如果只记五件事
- 它的单元是「文献里报过的基因×突变×疾病」,不是临床判读结论。
- ClinVar 独有 63.7% 是它存在的理由,也是它唯一不可替代的价值。
- 只读摘要,所以正文里的突变要另查。
- 57.6% 有 rsID,其余的人群频率无从谈起。
- Tier 2 只有 32 条,但做统计时必须单独标出来。
需要更高工程化程度或合规出域的商业版本?
当前展示的公开版本适用于学术研究与原型验证。千方医数集依托三甲医院直采网络,提供经专家标注、符合伦理合规的专病数据集交易服务。
前往商城查看可交易产品 →
