想象一座城市档案馆,中央最显眼的位置存放着一部被奉为“生命之书”的巨型蓝图——参考基因组。它由大约 32 亿个 A/C/G/T 字母写成,记录着人体所有细胞的基本设计图。有一天,一位病人带着自己细胞的“复印本”前来求助,希望查明身体异常的原因。复印本与蓝图表面看起来几乎一样,但里面藏着几处“错别字”:有些是复印机产生的墨点(测序错误),有些是真正印在细胞里的变异。变异检测,就是派出“基因侦探”,把复印本逐页放回蓝图逐字校对——哪一处是真正的错别字(致病变异)?哪一处只是墨点(实验噪声)?它被多少张独立的复印纸同时证实?本文从测序数据出发,完整走一遍“基因破案”流程:从数据准备、比对、变异识别,到深度学习增强、假阳性过滤与临床验证,让你掌握这套现代精准医学的侦探工具链。

岗位关联

掌握变异检测,是 AI 工程师踏入临床基因组学与精准医学的钥匙——你将能用深度学习从海量测序数据中精确识别致病变异,直接服务于疾病诊断与药物研发。

目录
  1. 可视化演示
  2. 变异检测基础
  3. 测序数据准备
  4. 比对与预处理
  5. 变异识别方法
  6. 深度学习增强
  7. 假阳性过滤
  8. 临床验证流程
  9. 应用与展望
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

演示从测序读段识别SNP/Indel/结构变异、传统检测pipeline,以及DeepVariant分类与假阳性过滤验证。

本节配有交互动效(进入视口后自动加载,约 3KB)。

变异类型检测 SNP/Indel/结构变异三类 读段堆叠识别差异 对比个体与参考基因组

变异检测基础

侦探接手案件的第一步,是了解“错别字”长什么样。档案馆的《生命之书》有大约 32 亿个字母,最常见的错误是“单字母被替换”——比如蓝图某个位置本该是 G,却写成了 A,这就是 SNP(单核苷酸多态性/单碱基替换)。还有一类是“字串被插入或缺失”——某个位置多了一两个字母或少了一两个,这就是 Indel(插入缺失)。更严重的,是一整段文字被复制、颠倒、甚至挪到别的章节,这就是结构变异(SV),包括拷贝数变异、倒位、易位等。侦探只有先分清错别字的类型,才能决定用哪种方法去查。

在基因组学里,这些“错别字”统称为基因变异,正常的参考序列称为参考基因组。由于人类是二倍体——每人每个基因有两份拷贝——同一个位置两份拷贝可能不同:一份是参考型 A,另一份是变异型 G,它们被称为等位基因。一个样本是纯合(两份相同)还是杂合(两份不同),直接决定了变异在测序数据中呈现的比例,这也是后面所有计算的起点。

除了变异本身,侦探还要能评价“证据可信度”。测序仪给每个碱基都附带一个 Phred 质量值 Q,定义如下。Q=30 意味着该碱基测错概率约千分之一;Q=20 则约百分之一。高质量数据是准确变异检测的前提。

现在侦探手里有了“错别字图鉴”(变异类型)和“证据可信度量表”(Phred 质量值),可以正式出发了。下一站是复印室——去看看原始的“复印件”长什么样,也就是测序数据。

Q=−10log⁡10(Perr)\displaystyle Q = -10\log_{10}(P_{\text{err}})
Q 值越大,测错概率越低。Q=30 约等于千分之一错误率,是主流测序仪的质量门槛。
  1. $P_{\text{err}}$该碱基被测序仪读错的概率,例如 0.01 表示每 100 个碱基约有 1 个被读错。
    Perr=0.01P_{\text{err}} = 0.01
  2. $\log_{10}$取以 10 为底的对数,把小概率小数转换成整数量级,便于阅读。
    log⁡10(0.01)=−2\log_{10}(0.01) = -2
  3. $-10 \times$乘以 -10 把负数翻正并放大,得到 0 到 60 之间的常用质量分数。
    Q=−10×(−2)=20Q = -10 \times (-2) = 20

测序数据准备

案件的第一步是取回“现场复印件”。测序仪的工作方式,更像一台疯狂复印机:它先把基因组 DNA 随机切成几百万个小碎片,再把每个碎片复制成几千份,然后一边合成一边读取每个字母。这样一整本《生命之书》被拆成了无数张写着短句的“纸片”,每张纸片只覆盖蓝图的一小段——这就是高通量测序(NGS)的基本原理。

每张“纸片”在计算机里以 FASTQ 格式存储,四行一组:第一行是编号标签(像快递单地址),第二行是碱基序列(纸片内容),第三行是"+"分隔符,第四行是与序列等长的质量字符串,每个字符对应一个 Phred 分数。质检工具会检查这些纸片是否破损、接头是否残留、质量分布是否异常,把不合格的纸片提前扔掉。

侦探最关心的是“覆盖深度”:每个位点平均被多少张纸片覆盖。深度服从泊松分布——平均深度为 λ 时,某位点恰好有 k 张纸片覆盖的概率如下。全外显子组测序一般要求 30×,而肿瘤低频突变检测常要求数千×,因为深度决定了你能分辨多低频的变异。

FASTQ 纸片虽然多,但还只是一堆乱序碎片。侦探下一步要做的,是把每一张纸片放回《生命之书》对应的那一页——这就是比对。

P(k)=e−λλkk!\displaystyle P(k) = \frac{e^{-\lambda}\lambda^{k}}{k!}
深度分布像“随机撒豆子”:平均撒到 30 粒,但有些格子只有 20 粒,有些则有 40 粒,纯属随机波动。
  1. $\lambda$平均测序深度,例如 λ=30 表示每位点平均覆盖 30 条读段。
    λ=30\lambda = 30
  2. $e^{-\lambda}$概率衰减因子,深度越高,覆盖率严重不足的位点越少。
    e−30≈9.4×10−14e^{-30} \approx 9.4 \times 10^{-14}
  3. $\lambda^{k}/k!$泊松分布的核心项,描述“恰好出现 k 条读段”的概率;例如 k=30 时。
    P(30)=e−30×303030!≈0.073P(30) = \frac{e^{-30} \times 30^{30}}{30!} \approx 0.073

比对与预处理

把一张写着“ACGTACGG……“的纸片放回蓝图上的正确位置,靠的不是肉眼看,而是比对算法:它先为参考基因组建立索引,再为每条读段快速寻找最相似的位置并给出比对分数,常用的 BWA 就是干这个的。比对结果存放在 SAM/BAM 文件中,相当于每张纸片背面盖上了”页码批注”,还附有比对质量 MAPQ 等元数据,供后续判断使用。

比对完成后还不能急着查错别字,得先解决两个“复印机”问题。第一,PCR 扩增会把同一个小碎片复制成千上万份,它们其实来自同一个 DNA 分子,如果不标记去除,一个真实变异的支持数会被虚高放大——这叫做 PCR 重复(duplicates)。第二,测序仪的错误并非完全随机,不同位置、不同碱基环境存在系统性偏差,需要用已知数据库做碱基质量值重校准(BQSR),相当于给复印机建立一份“错误习惯档案”,再据此修正每张纸片的质量评分。

这时侦探开始逐列查看:某参考位点共有 $n_{\text{total}}$ 条读段覆盖,其中 $n_{\text{alt}}$ 条读到非参考碱基,则变异等位基因频率 VAF 为如下公式。如果 VAF≈0.5,高度提示杂合变异;VAF≈1.0 提示纯合变异;VAF 只有 0.01 则可能是测序噪声——但在几千×深度的肿瘤样本中,也可能是真实的低频突变。同样的 VAF 在不同深度下,含义完全不同。

现在每张纸片各归其位,证据也完成了清洗。侦探坐在按页码排好的复印件前,深吸一口气——接下来开始正式的“逐字校勘”,判断每一处差异到底是不是真错别字。

VAF=naltntotal\displaystyle \text{VAF} = \frac{n_{\text{alt}}}{n_{\text{total}}}
VAF 解开了“杂合 vs 纯合 vs 噪声”的密码:一半支持是杂合,全部支持是纯合,少量支持要看深度。
  1. $n_{\text{alt}}$支撑变异等位基因的读段数,也就是“指认错别字的纸片数”。
    nalt=20n_{\text{alt}} = 20
  2. $n_{\text{total}}$覆盖该位点的总读段数(深度),也就是“参与投票的纸片总数”。
    ntotal=40n_{\text{total}} = 40
  3. 相除得到 0 到 1 的比例,0.5 表示一半纸片指认变异、一半纸片支持参考。
    VAF=2040=0.5\text{VAF} = \frac{20}{40} = 0.5

变异识别方法

校勘的核心问题:某个位置支持变异的纸片有 20 张、支持参考的有 20 张,这到底是“真杂合变异”,还是“复印机恰好在这里洒了 20 个墨点”?传统变异 caller 用贝叶斯统计回答这个问题:先验上,人类基因组绝大多数位点是参考型;似然上,每种基因型(纯合参考、杂合、纯合变异)产生当前读段观测的概率各不相同;两者结合得到后验概率,取最可能的基因型作为判定结果。

GATK 的 HaplotypeCaller 是行业标杆:它会先在局部区域重构可能的单倍型(相当于把多张纸片拼成候选句子),再计算每个候选句子解释数据的概率,最后输出每个位点的基因型与质量值 QUAL。所有变异集合在 VCF 文件中,每行一个变异,包含位置、参考碱基、替代碱基、质量值、基因型等字段。变异注释工具会把变异与基因、人群频率、已知数据库关联起来,让侦探知道“这个错别字出现在哪个基因的哪个功能区”。

贝叶斯公式如下:分子是“在基因型 G 假设下看到数据 D 的概率”乘以“基因型 G 的先验概率”,分母是数据的边缘概率,只起归一化作用。实际计算中常只比较不同 G 的相对后验大小,于是分母可以省去。

传统侦探虽可靠,但规则和阈值需要大量人工经验。这时,一位“老侦探”登场了——见多识广的深度学习模型,它用成千上万起案件训练出的直觉,让变异识别更上一层楼。

P(G∣D)=P(D∣G) P(G)P(D)\displaystyle P(G|D) = \frac{P(D|G)\,P(G)}{P(D)}
贝叶斯让侦探把“事前预期”与“现场证据”结合,既不被罕见事件误导,也不忽视有说服力的证据。
  1. $P(G)$基因型先验,未看数据前我们认为 G 出现的概率,例如杂合变异约万分之一。
    P(Ghet)=10−4P(G_{\text{het}}) = 10^{-4}
  2. $P(D|G)$似然,假设基因型是杂合时,当前“20 条 alt / 20 条 ref”读段分布出现的概率。
    P(D∣Ghet)=0.8P(D|G_{\text{het}}) = 0.8
  3. $P(D)$所有可能基因型下产生数据的加权总概率,充当归一化常数。
    P(D)=∑G′P(D∣G′) P(G′)P(D) = \sum_{G'} P(D|G')\,P(G')
  4. $P(G|D)$后验——看完数据后我们相信 G 成立的概率,取最大者为最终基因型。
    P(Ghet∣D)=0.8×10−4P(D)P(G_{\text{het}}|D) = \frac{0.8 \times 10^{-4}}{P(D)}

深度学习增强

老侦探为什么厉害?他看过的案件(训练样本)足够多,能从一堆互相矛盾的证据里一下子抓住关键特征。DeepVariant 就是这样一位老侦探:它把每个候选变异位点附近的比对区域“画”成一幅多通道图像——每一行是一条读段,每一列是一个碱基位点,通道分别编码碱基类型、碱基质量、正负链方向。参考基因组位于图像正中,变异就是图像中“破坏条纹规律的异样色块”。

图像交给卷积神经网络 CNN 处理:卷积核层层扫描,自动学习“什么样的小色块模式代表真实变异、什么样代表测序噪声”,最后的全连接层用 softmax 输出三类概率:纯合参考、杂合变异、纯合变异。与手工特征相比,CNN 不需要专家预先定义“深度要多少、VAF 要多少”的规则,而是从标注数据中自己学出最优判断。

softmax 公式如下:把网络输出的原始分数 $z_i$ 转成和为 1 的概率分布。训练时以权威变异集作为监督标签,评估时与 GATK 等传统方法对比,DeepVariant 在 Indel 检测和低复杂度区域上的灵敏度显著提升。

老侦探也有失手的时候——他可能被“全场都是墨点的案发现场”(高噪声、低深度区域)迷惑。所以无论谁判案,最后都要经过一道“线索甄别”环节:过滤假阳性。

σ(z)i=ezi∑jezj\displaystyle \sigma(\mathbf{z})_i = \frac{e^{z_i}}{\sum_{j} e^{z_j}}
softmax 把“谁更可能”转成“各自多少概率”,三者加起来恒等于 1。
  1. $z_i$CNN 最后一层对类别 i(参考/杂合/纯合变异)的原始打分,可能是任意实数。
    z=[1.2,  3.5,  −0.6]\mathbf{z} = [1.2,\; 3.5,\; -0.6]
  2. $e^{z_i}$指数变换把打分变成正数并放大差距,3.5 对应的权重远超 -0.6。
    e3.5≈33.1,e−0.6≈0.55e^{3.5} \approx 33.1,\quad e^{-0.6} \approx 0.55
  3. 除以总和归一化使三类输出之和为 1,变成可解释的“概率”;此时杂合类别得分占比约 90%。
    σ(z)1=33.13.32+33.1+0.55≈0.90\sigma(\mathbf{z})_1 = \frac{33.1}{3.32 + 33.1 + 0.55} \approx 0.90

假阳性过滤

侦探组会上,助手提交了厚厚一叠候选错别字,里面混着大量假线索:复印机墨点(测序错误)、纸张褶皱(低复杂度区域如 poly-A 重复)、装订错位(读段比对到同源序列的错误位置)、同一页被反复复印(PCR 重复)。这些假线索的特征可以被量化:支持读段数太少、VAF 异常偏移、比对质量 MAPQ 低、正负链支持严重不平衡、离读段末端太近等。

常见的处理有两类:硬过滤和软过滤。硬过滤简单粗暴——直接设定阈值,比如“QUAL<30 的丢弃”,适合小规模快速分析。软过滤以 VQSR 为代表:用已知高可信变异集训练高斯混合模型,学习“真变异”和“假变异”在特征空间中的分布,再给每个候选变异重新打分,在假阳性率与灵敏度之间选择最优切点。

过滤的本质是概率判断:假设某位点深度为 n,其中 k 条读段支持变异,若每条读段测序错误概率为 e,那么这 k 条错误读段“恰好同时指向同一替代碱基”的概率服从二项分布。当这个概率极低时,才值得把该位点亮为候选变异——这就是深度越高、低频变异越可信的数学原因。

过滤之后,候选名单从几千个缩到几十个。但侦探们知道,案件要真正“结案”,还得经过法庭质证——最后一关是临床验证。

P(k∣n,e)=(nk)ek(1−e)n−k\displaystyle P(k|n,e) = \binom{n}{k} e^{k} (1-e)^{n-k}
二项分布量化了“纯属偶然”的可能性:概率越低,假阳性嫌疑越小。
  1. $\binom{n}{k}$从 n 条读段中选出 k 条的组合数,对应“哪些位置的读段出错”的选择方式。
    (404)=91390\binom{40}{4} = 91390
  2. $e^{k}$这 k 条读段恰好都读错且指向同一替代碱基的概率(含等位随机因素)。
    ek=0.014=10−8e^{k} = 0.01^{4} = 10^{-8}
  3. $(1-e)^{n-k}$其余 n-k 条读段都读对的概率。
    (1−0.01)36≈0.70(1-0.01)^{36} \approx 0.70
  4. 整体概率全公式给出“纯属偶然凑出 4 条变异支持”的概率,越小越说明变异真实。
    P≈91390×10−8×0.70≈6.4×10−4P \approx 91390 \times 10^{-8} \times 0.70 \approx 6.4 \times 10^{-4}

临床验证流程

法庭上,侦探的结论必须由独立证据交叉验证。在临床基因组学中,最经典的“独立证据”是 Sanger 测序:用毛细管电泳一代测序对候选位点逐一“手抄核对”。它不依赖高通量测序仪的“复印机”,精度极高,但成本也高,适合验证少数关键位点。凡是写进临床报告的变异,几乎都要经过这轮质证。

验证体系需要量化的质量指标:灵敏度(真变异被检出的比例)、特异度(非变异被正确排除的比例)、阳性预测值 PPV(被报告的变异中真实的比例)。临床实验室必须证明整个流程达到一定标准(如 PPV≥99%),才能用于报告。美国医学遗传学与基因组学学会(ACMG)还要求对变异进行致病性分级:致病、可能致病、意义未明、可能良性、良性,依据人群频率、功能实验、家系共分离等证据综合评判。

PPV 公式如下:TP 是被 Sanger 复核确认的真阳性,FP 是复核后证伪的假阳性。不同检测场景对 PPV 要求不同:种系检测允许较低深度但要求极高特异性;肿瘤体细胞检测面对低 VAF,更依赖深度与正交验证。

质证通过的变异,才被郑重写进临床报告,送到医生手里。现在,让我们把镜头拉远,看看这些“破获的案件”如何真正改变了世界。

PPV=TPTP+FP\displaystyle \text{PPV} = \frac{TP}{TP + FP}
PPV 回答“报告的变异有多少是真的”,是临床实验室的核心质量指标。
  1. TP复核确认的候选变异数,即“法庭上证实的真错别字”。
    TP=98TP = 98
  2. FP复核证伪的候选变异数,即“被洗清的冤假错案”。
    FP=2FP = 2
  3. PPV报告变异中真实变异所占比例,98% 以上才算稳固。
    PPV=9898+2=0.98\text{PPV} = \frac{98}{98+2} = 0.98

应用与展望

《生命之书》的错别字侦探们在无数领域立下了汗马功劳。在罕见病诊断中,病因不明的患儿通过全外显子组测序和深度学习变异检测,几天内锁定致病变异,确诊遗传综合征,医生随之调整治疗与随访方案。在肿瘤领域,液体活检从血液中捕获肿瘤释放的 ctDNA,在万分之一级别的背景噪声中检出耐药突变,指导靶向药更换。

在群体层面,几十万人的外显子组/全基因组数据被汇总成人群等位基因频率数据库(如 gnomAD),每个位点的等位基因频率 p 计算如下。有了人群频率基线,临床解读时就能判断一个变异是“常见多态”还是“罕见致病变异”。大规模数据也让 AI 模型越训越强,形成数据飞轮。

展望未来,长读段测序让结构变异检测变得更直接,多组学(转录组、表观组)与变异数据的融合、联邦学习框架下的跨机构模型训练,正在把侦探工具推向新高度。而这一切的核心,仍然是那个朴素的问题:在 32 亿个字母中,分辨真正的错别字。

从档案馆的复印纸到法庭质证,从深度学习老侦探到人群数据库,变异检测的故事告诉我们:AI 不是取代科学,而是让科学家在更浩瀚的数据中看得更远。学好这套“破案流程”,就是握住了通向精准医学的一把钥匙。

p=2nhom+nhet2N\displaystyle p = \frac{2n_{\text{hom}} + n_{\text{het}}}{2N}
等位基因频率是“这个错别字在人群里常见吗”的数字答案——频率过高就基本排除致病性。
  1. $n_{\text{hom}}$携带纯合变异等位基因的个体数,每个个体贡献 2 个该等位基因。
    nhom=5n_{\text{hom}} = 5
  2. $n_{\text{het}}$携带杂合变异等位基因的个体数,每个个体贡献 1 个该等位基因。
    nhet=40n_{\text{het}} = 40
  3. $2N$总等位基因数,N 为个体数,每个人都有 2 条同源染色体。
    2N=2×1000=20002N = 2 \times 1000 = 2000
  4. 相除得到等位基因频率,p=2.5% 说明这是一个常见变异。
    p=2×5+402000=0.025p = \frac{2 \times 5 + 40}{2000} = 0.025

AI 应用场景

罕见病临床诊断中的全外显子组分析

阶段:模型应用与结果验证

解决的问题:传统变异检测需要生物信息专家花费数周手工调参,Indel 区域灵敏度低、假阳性多。引入 DeepVariant 等深度学习方法后,比对区域被自动编码为图像特征,无需人工设计阈值,单样本变异识别时间从数天缩短到数小时,灵敏度显著提升。

具体案例:某三甲医院儿科收治一名不明原因发育迟缓的 4 岁患儿,家长经历了三年求医无果。团队对患儿做全外显子组测序(30×),经过 BWA 比对、去重复、BQSR 预处理后,用 DeepVariant 调用变异,在 KMT2A 基因上检出一个新发截断变异,Sanger 测序独立复核确认,最终确诊 Kabuki 综合征,医生据此制定心脏超声与免疫随访计划。

肿瘤液体活检中的低频突变检测

阶段:特征学习与信号增强

解决的问题:晚期肺癌患者血液中 ctDNA 含量极低,耐药突变频率常低于 0.5%,传统 caller 难以与测序噪声区分。深度学习方法借助超高深度(上万×)和上下文特征,把突变信号从背景噪声中剥离出来。

具体案例:一名 EGFR 敏感突变肺癌患者靶向治疗两年后进展,液体活检测序数据中 T790M 突变 VAF 仅 0.3%。深度学习增强的变异检测流水线在高错误率区域仍准确检出该突变,医生据此将治疗方案切换为三代 EGFR-TKI,患者病情再次稳定。

人群基因组计划中的大规模变异过滤

阶段:数据规模化处理与质控

解决的问题:数十万样本的联合分析会产生海量候选变异,其中混杂大量测序与比对体系性假阳性。需要自动化过滤与质控流程,建立可靠的人群等位基因频率基线,供临床实验室查询。

具体案例:某国家人群基因组计划汇总 10 万人外显子组,团队构建自动化流水线,对每个位点计算深度、VAF、哈迪-温伯格平衡检验等指标,用 VQSR 和深度模型双层过滤,最终产出包含 1.2 亿个变异、频率注释完善的人群数据库,成为全国临床解读的基础设施。

Python 演示

python88 行
"""Toy SNP caller: pileup-based variant detection on simulated reads."""import random REF = "ACGTACGTACGGATCGTACGTACGTACGTACGT"TRUTH = {12: "T", 19: "A", 27: "T"}     # 真实变异位点: 位置->替代碱基 def simulate_reads(depth=40, error_rate=0.03, seed=42):    """模拟测序读段: 随机起点, 15-20bp片段, 真实变异与随机错误混合"""    random.seed(seed)    reads = []    for _ in range(depth):        start = random.randint(0, len(REF) - 20)        length = random.randint(15, 20)        seq = []        for i in range(length):            pos = start + i            if pos in TRUTH:                seq.append(TRUTH[pos] if random.random() < 0.5 else REF[pos])            elif random.random() < error_rate:                seq.append(random.choice("ACGT"))   # 测序错误            else:                seq.append(REF[pos])        reads.append((start, "".join(seq)))    return reads def pileup(reads):    """把读段堆叠成每个参考位置的碱基列表"""    cols = []    for pos in range(len(REF)):        bases = []        for start, seq in reads:            off = pos - start            if 0 <= off < len(seq):                bases.append(seq[off])        if bases:            cols.append((pos, bases))    return cols def genotype(ref_base, alt_base, alt_n, depth):    """按VAF粗略判定基因型: >=0.65纯合变异, >=0.20杂合, 其余参考纯合"""    vaf = alt_n / depth if depth else 0.0    if vaf >= 0.65:        return alt_base * 2    if vaf >= 0.20:        return ref_base + alt_base    return ref_base * 2 def call_variants(cols, min_depth=8, min_vaf=0.20):    """候选变异判定: 深度与VAF达标, 且计算错误读段偶然凑数的概率"""    calls = []    for pos, bases in cols:        ref_base = REF[pos]        cnt = {}        for b in bases:            if b != ref_base:                cnt[b] = cnt.get(b, 0) + 1        for alt, alt_n in cnt.items():            depth = len(bases)            if depth < min_depth or alt_n / depth < min_vaf:                continue            gt = genotype(ref_base, alt, alt_n, depth)            p_err = 0.25 ** alt_n   # 错误碱基恰好都指向同一替代碱基的概率            calls.append((pos + 1, ref_base, alt, alt_n, depth,                          alt_n / depth, gt, p_err))    return calls def evaluate(calls):    """与真实变异对比, 输出精确率与召回率"""    called = {(p, a) for p, _, a, *_ in calls}    truth = {(p + 1, a) for p, a in TRUTH.items()}    tp = called & truth    fp = called - truth    fn = truth - called    precision = len(tp) / len(called) if called else 0.0    recall = len(tp) / len(truth) if truth else 0.0    return precision, recall, tp, fp, fn if __name__ == "__main__":    reads = simulate_reads(depth=40, error_rate=0.03, seed=42)    cols = pileup(reads)    calls = call_variants(cols)    print("Candidate variants (pos ref>alt alt_n/depth VAF genotype p_err)")    for c in calls:        print(f"  chr1:{c[0]:>3} {c[1]}>{c[2]}  {c[3]:>2}/{c[4]:>2}  "              f"VAF={c[5]:.2f}  {c[6]}  P={c[7]:.2e}")    precision, recall, tp, fp, fn = evaluate(calls)    print(f"\nPrecision={precision:.2f}  Recall={recall:.2f}")    print(f"TP={sorted(tp)}  FP={sorted(fp)}  FN={sorted(fn)}")
目的:用堆叠法(pileup)从模拟测序读段中识别 SNP 并判定基因型,最后与真实变异对比,计算精确率与召回率。
  1. seq.append(TRUTH[pos] if random.random() < 0.5 else REF[pos])在真实变异位点以一半概率写入替代碱基,模拟杂合变异;另一半保持参考型。
  2. elif random.random() < error_rate:以低概率写入随机碱基,模拟复印机式测序错误。
  3. off = pos - start计算参考位置在读段内的偏移,只有 0 <= off < len(seq) 才说明该读段覆盖此位点。
  4. cnt[b] = cnt.get(b, 0) + 1统计每个非参考碱基的出现次数,即变异支持的“证词数”。
  5. if depth < min_depth or alt_n / depth < min_vaf:深度或 VAF 不达标的候选直接出局,对应正文的假阳性过滤。
  6. vaf = alt_n / depth计算等位基因频率,VAF 约 0.5 为杂合,约 1.0 为纯合。
  7. precision = len(tp) / len(called) if called else 0.0精确率是“报告的变异中真正正确的比例”,召回率是“真实变异被找到的比例”。

常见误区

误区测序仪给出 Q30 质量值,错误率只有千分之一,所以测完比对之后,只要参考基因组和读段不一样的位点,就一定是真变异。

正解人类基因组有约 32 亿个位点,单碱基错误率再低,乘以庞大的位点数量也会产生巨量“墨点”;而且 PCR 扩增、比对错位会放大错误。真实变异必须被多条独立读段支持、有合理 VAF,并经概率模型判定。就像侦探不会因为一张复印纸上的墨点就给人定罪,必须有多份独立复印本相互印证。

为何常见:直观上“一个位点不一样就是变异”,忽略了测序是抽样过程而非精确复制——每个位点被测到多少次、每次是否可靠,都需要统计建模。

误区测序深度越高越保险,干脆做 1000× 深度,一定能避免所有假阳性和漏检。

正解深度增加确实提升低频变异灵敏度,但 PCR 重复会制造系统性偏差——同一个分子的多份拷贝被反复测到,深度再高也只是重复证实同一份“证词”。需要用去重复或唯一分子标签(UMI)来校正。就像多台复印机用同一张有墨点的底片复印,复印得再多,墨点依然顽固存在。

为何常见:“样本量越大越可靠”的直觉在独立抽样时成立,但 PCR 扩增产生的重复并非独立抽样,反而会制造假置信。

误区深度学习模型 DeepVariant 太强了,只要把测序数据丢进去跑一下,就能替代整个变异检测流程,不需要预处理和过滤。

正解DeepVariant 只负责把比对区域“图像”分类成变异或参考,输入仍然需要高质量比对与预处理;在低深度、多倍体、同源序列区域等场景表现可能下降,输出仍需过滤和临床验证。老侦探再厉害,也需要可靠的现场取证和法庭质证。

为何常见:深度学习在图像识别领域的大成功,让人误以为端到端模型可以解决一切,忽略了生物数据中物理、化学噪声的复杂性。

误区假阳性太可怕了,过滤条件设得越严格,临床报告就越可信。

正解严格过滤会大幅提升精确率,但会牺牲召回率,漏掉低频真实变异——比如肿瘤早期突变只有 1% 的 VAF,过严的阈值会直接漏诊。临床实验室会设定明确的灵敏度下限,并针对种系/体细胞等不同场景单独调参。

为何常见:人们只担心“假阳性坑人”,却忽略了“假阴性延误病情”。过滤是灵敏度与特异度之间的天平,不是越严越好。

误区临床报告里写了一个基因变异,那这个变异就一定是致病的,可以直接按说明书用药。

正解变异需要按 ACMG/AMP 指南做致病性分级:致病、可能致病、意义未明(VUS)、可能良性、良性。要结合人群频率、功能实验、家系共分离等证据综合评判,意义未明变异不能直接用于临床决策。就像侦探找到线索还不够,必须形成完整的证据链才能定罪。

为何常见:媒体上“基因突变→靶向药”的简化叙事,让人们以为变异等于确诊、等于用药,忽略了临床证据分级的严谨流程。

面试题

Q1. SNP 指的是哪一种基因组变异?

单选题 · easy

  • A.单个碱基被另一个碱基替换← 正确答案
  • B.一段 DNA 序列的插入或删除
  • C.染色体片段复制数目增加
  • D.染色体大片段发生倒位

答案:A。SNP 是单核苷酸多态性,指单个碱基被另一个碱基替换,A 正确。B 是 Indel,C 是拷贝数变异,D 是结构变异中的倒位,都不属于 SNP。

Q2. 测序数据 FASTQ 文件中,碱基质量值通常用什么表示?

单选题 · easy

  • A.一个连续递增的整数
  • B.单个可打印 ASCII 字符← 正确答案
  • C.一个浮点数小数形式
  • D.两位十六进制数字

答案:B。FASTQ 第四行为质量字符串,每个字符对应该碱基的 Phred 质量分数。ASCII 字符本质是整数编码的映射,像"IIIII"就代表一串高质量碱基,因此 B 正确。

Q3. 一个碱基的 Phred 质量值 Q=20,对应的测序错误概率约为?

单选题 · easy

  • A.十分之一左右
  • B.百分之一左右← 正确答案
  • C.千分之一左右
  • D.万分之一左右

答案:B。由 Q = -10·log10(P) 反推,Q=20 时 P = 10^(-2) = 0.01,即百分之一。Q=30 对应千分之一,Q=40 对应万分之一。记住“每加 10,错误率降一个数量级”即可。

Q4. “测序深度 30×”的含义是?

单选题 · easy

  • A.基因组平均被覆盖三十次← 正确答案
  • B.一共测序了三十个样本
  • C.读段平均长度三十个碱基
  • D.参考基因组长度三十亿碱基

答案:A。测序深度指参考基因组每个位点被测序读段覆盖的平均次数,30× 表示平均每个位点有 30 条读段覆盖。它是决定低频变异检测能力的关键参数,与样本数、读段长度无关。

Q5. DeepVariant 相对于传统 callers 的核心优势是?

单选题 · mid

  • A.用深度学习自动提取比对特征← 正确答案
  • B.完全不需要参考基因组序列
  • C.只依赖质量值做阈值判断
  • D.不需要训练数据和计算资源

答案:A。DeepVariant 把比对区域编码成多通道图像,用 CNN 自动学习“哪些模式是真变异”,无需人工设计 VAF、深度等规则。它仍然需要参考基因组、训练数据和 GPU 资源,B/C/D 均错误。

Q6. 下列哪项最可能是变异检测中的假阳性来源?

单选题 · mid

  • A.PCR 重复导致的等位基因偏差← 正确答案
  • B.参考基因组本身的真实变异
  • C.测序只覆盖了编码区序列
  • D.样本 DNA 浓度过高产生溢出

答案:A。PCR 重复会让同一 DNA 分子的错误被反复测到,造成 VAF 虚高和等位基因偏差,是典型假阳性来源。B 是参考本身的问题,C 是覆盖问题,D 是实验操作问题,都不是“候选变异被错误报告”的直接来源。

Q7. 下列哪些属于结构变异 SV?

多选题 · mid

  • A.拷贝数变异 CNV← 正确答案
  • B.染色体大片倒位← 正确答案
  • C.单核苷酸替换 SNP
  • D.大片段缺失 DEL← 正确答案

答案:ABD。结构变异指影响大片段 DNA 的改变,包括拷贝数变异、倒位、易位、大片段插入/缺失,A/B/D 正确。SNP 只涉及单个碱基替换,属于小规模变异,不属于 SV。

Q8. DeepVariant 将比对区域编码为图像时,使用的特征通道包括?

多选题 · mid

  • A.碱基类型通道← 正确答案
  • B.碱基质量分数通道← 正确答案
  • C.正负链方向特征← 正确答案
  • D.蛋白质三维结构通道

答案:ABC。DeepVariant 的图像每个像素含三个通道:碱基类型(A/C/G/T)、碱基质量分数、正负链方向。它处理的是 DNA 序列比对信息,不需要蛋白质三维结构,D 错误。

Q9. 临床变异检测中,Sanger 测序验证的主要作用是?

单选题 · hard

  • A.用正交独立技术复核变异← 正确答案
  • B.替代整个测序建库流程
  • C.提高参考基因组组装质量
  • D.计算全体位点的等位频率

答案:A。Sanger 测序用一代测序对候选位点逐一高精度复核,与高通量测序原理正交,能独立确认变异是否存在,是临床验证金标准。它成本高、通量低,无法替代建库流程,也不用于组装或全基因组频率计算。

Q10. 降低变异检测假阳性的常用策略包括?

多选题 · hard

  • A.标记并去除 PCR 重复读段← 正确答案
  • B.对碱基质量做系统校正← 正确答案
  • C.用 VQSR 或硬过滤筛选← 正确答案
  • D.忽略所有深度不足百的位点

答案:ABC。去重复消除等位基因偏差,BQSR 修正系统性质量错误,VQSR/硬过滤按质量阈值筛选,都是标准策略。D 过于激进——全基因组大量位点深度不足 100×,全部丢弃会造成严重假阴性,不是合理做法。