一、BLAST 概述:从何而来,解决什么问题
做生物信息学的人,几乎没人能绕过 BLAST。我第一次接触它还是读研的时候,导师扔给我一条未知序列,说「去比一下」。那时候我对 BLAST 的理解就是——把序列扔进去,点一下按钮,等结果。后来踩了不少坑,才慢慢摸清楚它的脾气。
BLAST 全称是 Basic Local Alignment Search Tool,基本局部比对搜索工具。别看它名字里带个「Basic」,背后的算法可一点都不基础。它解决的问题说白了就是:给定一条查询序列,能在海量数据库中快速找到与之相似的那些序列,并告诉你相似的程度有多高。
这里要注意一个关键词——局部。BLAST 做的是局部比对,不是全局比对。它只找序列之间最相似的片段,而不是把整条序列从头对齐到尾。这个设计非常聪明,因为很多生物序列的功能关键域就那么一小段,全局比对反而会稀释掉信号。
一句话记住 BLAST:用局部比对的方式,在大型序列数据库中快速搜索与查询序列相似的条目,并给出统计学显著性评估。
1.1 发展历史:从 FASTA 到 BLAST 的进化
上世纪 80 年代,序列比对还是一件相当奢侈的事。那时候 David Lipman 和 William Pearson 开发了 FASTA,算是早期最流行的比对工具。但 FASTA 在搜索大规模数据库时速度还是不够快,尤其是数据库越堆越大的时候。
1990 年,Altschul、Gish、Miller、Myers 和 Lipman 在 Journal of Molecular Biology 上发表了那篇经典文章——「Basic Local Alignment Search Tool」。这就是 BLAST 的诞生。它引入了一个核心思想:先用短「种子」匹配快速定位候选区域,再延伸出完整的比对。这个策略让搜索速度比 FASTA 提升了一个量级。
1997 年,升级版 Gapped BLAST 和 PSI-BLAST 推出。Gapped BLAST 允许在比对中引入空位,PSI-BLAST 则引入迭代搜索,构建位置特异性评分矩阵(PSSM),能捕捉到更远缘的同源关系。
2009 年,BLAST+ 发布,重写了底层代码,改善了多线程性能和内存管理。你现在用的 blastn、blastp 基本都是 BLAST+ 版本。NCBI 到今天还在维护和更新它,可以说它是序列搜索领域最长寿、最活跃的工具之一。
我个人习惯:在写管道脚本时,我一定指定 -version 参数把 BLAST 版本记录下来。不同版本之间输出格式有细微差异,曾经因为这个坑浪费了我一下午排查。
1.2 基本原理:BLAST 到底怎么工作的?
BLAST 的算法流程可以拆成四个阶段。我先用一句话概括:查表、延伸、打分、评估。
第一阶段:构建单词列表。 把查询序列拆成短片段,称为「种子」或「单词」。默认长度对于蛋白质是 3 个氨基酸,对于核苷酸是 11 个碱基。然后为每个单词在数据库中找匹配的条目。
第二阶段:命中延伸。 找到匹配的种子之后,向两侧延伸,同时用替换矩阵(比如 BLOSUM62 或 PAM250)计算得分。延伸过程中如果得分下降太多就会停止,这就是所谓的「高分段对」(HSP,High-Scoring Segment Pair)。
第三阶段:组合与优化。 如果一条数据库序列上有多个 HSP 落在合理范围内,BLAST 会尝试把它们拼接起来,用空位扩展算法做进一步优化。
第四阶段:统计评估。 最后给每个比对结果算一个 E-value(期望值),告诉你在随机情况下出现同样得分的概率有多大。E-value 越小,结果越可靠。
我曾经踩过的坑:E-value 的阈值不要一刀切。短序列的 E-value 天然偏高,我曾用默认 0.01 过滤,结果把不少真实的短肽同源序列给过滤掉了。后来我改成先不做 E-value 过滤,等下游分析再根据序列长度做动态截断。
1.3 主要变体:不同场景用不同的 BLAST
BLAST 不是单一工具,而是一个家族。你面对的问题不同,选用的变体也不同。我用一个表格把它们理清楚。
| 变体名称 | 查询序列类型 | 目标数据库类型 | 典型场景 |
|---|---|---|---|
| blastn | 核苷酸 | 核苷酸 | 比对 DNA/cDNA 序列,找基因同源 |
| blastp | 蛋白质 | 蛋白质 | 比对蛋白序列,找功能同源 |
| blastx | 核苷酸(6帧翻译) | 蛋白质 | 识别新转录本的编码潜力 |
| tblastn | 蛋白质 | 核苷酸(6帧翻译) | 在基因组中找蛋白同源区域 |
| tblastx | 核苷酸(6帧翻译) | 核苷酸(6帧翻译) | 跨物种比较远缘同源 |
| PSI-BLAST | 蛋白质 | 蛋白质 | 迭代搜索,捕捉远缘同源 |
| delta-blast | 蛋白质 | 蛋白质(含域信息) | 检测含有保守域的远源序列 |
这里我重点讲讲几个常用的变体,尤其是它们之间怎么选。
blastn 是最基本的核苷酸 vs 核苷酸比对。我常用于验证 PCR 产物序列与预期靶标是否匹配,或者在做基因组组装时检查 contig 之间的重叠区域。它的速度最快,因为核苷酸只有 4 种碱基,搜索空间小。
blastp 是蛋白质 vs 蛋白质比对。蛋白质有 20 种氨基酸,替换矩阵的语义信息更丰富,能捕捉到保守替换。我建议你在做功能注释时优先用 blastp,而不是通过 DNA 序列间接推断。
blastx 是个很实用的变体。它先把核苷酸序列按 6 个读码框翻译成蛋白质,再与蛋白数据库比对。使用场景:你手头有一段 mRNA 或 EST,但不知道它编码什么蛋白。blastx 直接告诉你这段序列能翻译出什么。
我建议:在做转录组注释时,先用 blastx 与 Swiss-Prot 比对,然后再用 blastn 与核苷酸数据库比对。这样既能找到已知蛋白的同源,又能捕获到非编码区域的保守性。我自己的项目里,这个组合策略的注释覆盖率比单用 blastx 高出约 15%。
PSI-BLAST 是我个人比较偏爱的工具,尤其是在找远缘同源的时候。它迭代地从比对结果中提取保守模式,构建位置特异性矩阵(PSSM),然后用这个矩阵去搜索下一轮。说白了,它像是一个「越搜越聪明」的工具。默认迭代 3 轮,但你可以根据自己的数据调整。
注意:PSI-BLAST 的迭代轮数不是越多越好。轮次过高容易引入假阳性,特别是数据库里含有低质量序列时。我一般控制在 3~5 轮,超出后明显看到 E-value 分布开始发散。
1.4 应用场景:BLAST 能帮你做什么
BLAST 的应用范围太广了,几乎贯穿了分子生物学的所有领域。我挑几个最典型的场景来聊。
场景一:物种鉴定。 拿到一条未知的 16S rRNA 或 COI 序列,用 blastn 比对 NCBI 的 nt 数据库,匹配到哪个物种基本就定了。环境微生物组数据里,这种用法最普遍。
场景二:基因功能注释。 新测序的基因组或转录组,用 blastp 或 blastx 比对 Swiss-Prot、TrEMBL 或 NR 数据库,根据同源基因的标注信息推断功能。我参与过一个植物转录组项目,就是用 blastx + GO 映射来做功能分类的。
场景三:同源搜索与进化分析。 在多个物种间找同一家族的同源基因,blastp 是标准入口。拿到比对结果后,再用多序列比对工具做进化树分析。
场景四:引物设计验证。 设计好的引物用 blastn 比对基因组数据库,检查是否有非特异性结合位点。尤其是做 qPCR 时,这一步不能省。
场景五:结构域与保守片段发现。 用 PSI-BLAST 或者 deltablast 搜索含有特定保守域的序列,可以在实验之前就预测蛋白可能的功能区域。
我总结的一个原则:用 BLAST 不要贪心。搜索结果里 E-value 最小的那几个往往是最可靠的,不要试图从排名靠后的一百条结果里「挖掘」出什么惊艳发现。BLAST 给出的统计评估已经很清楚地告诉你了——不显著的匹配,大概率就是随机的。
1.5 跑 BLAST 之前,先把数据准备好
这里分享一点我自己的操作习惯。跑 BLAST 之前,序列文件的格式整理干净,能省掉很多不必要的麻烦。
- 查询序列:必须是 FASTA 格式,头行以
>开头,不要含空格或特殊符号(我见过某实验室的数据里带着中文标点,结果 BLAST 直接报错)。 - 数据库:本地跑的话记得先
makeblastdb。NCBI 官方数据库可以直接下预构建的,省时间。 - 参数设置:根据你的序列长度和目的调整
-word_size、-evalue、-num_threads。短序列把小 word_size 调低一些,能提高灵敏。
# 构建本地 BLAST 数据库示例
makeblastdb -in refseq_protein.faa -dbtype prot -out my_prot_db
# 运行 blastp 示例
blastp -query query.faa -db my_prot_db -out blast_results.txt -outfmt 6 -evalue 1e-5 -num_threads 8
-outfmt 6 是表格格式,每行一条匹配,我一般默认用这个,方便下游脚本处理。如果你需要可视化查看比对细节,可以用 -outfmt 0 或者直接用 NCBI 网页版。
1.6 一个常见的误区:E-value 越小越好?
很多人觉得 E-value 到 1e-50 就比 1e-10 好,这个认知不完全对。E-value 受查询序列长度和数据库大小的影响很大。举个极端例子:一条 50 bp 的短序列,E-value 能到 1e-5 已经算高度保守了;而一条全长 16S rRNA(约 1500 bp),E-value 轻松到 1e-100 以上。
正确的做法:评估显著性时,要同时看 E-value、比对覆盖度和序列一致性三个维度。我内部定过一个规则——「E-value 小于 1e-5 + 覆盖度大于 70% + 一致性大于 60%」,三个条件同时满足才认为是有意义的同源。当然你可以根据自己的数据松紧调整。
小技巧:在 -outfmt 6 的输出里,第 3 列是序列一致性,第 4 列是比对长度,第 12 列是 E-value。你写脚本过滤时,可以直接用这三列做联合阈值判断。