第一章 RNA-seq 数据基础:测序原理与常见数据类型
做模型训练,第一件事不是调参数,而是搞清楚你手里那碗数据到底是怎么来的。RNA-seq 数据看着简单——一个矩阵、几万行基因、几百个样本,但背后藏着不少坑。我刚开始做表达特征工程时,就因为在 FASTQ 阶段没注意质量,导致后面模型怎么调都过拟合。所以这一章我们先把地基打牢。
1.1 测序原理:从 RNA 到碱基序列
说白了,RNA-seq 就是用高通量测序仪把细胞里所有的 RNA 分子“读”成短小的碱基片段(reads)。目前最主流的是 Illumina 的边合成边测序技术,流程大致分四步:
- 建库:把 RNA 反转录成 cDNA,然后打断、加接头、PCR 扩增。
- 簇生成:把文库加载到 flow cell 上,桥式 PCR 形成一个个单克隆簇。
- 测序:用带有荧光标记的 dNTP 一个一个碱基合成,机器拍下每个簇的荧光信号。
- 碱基识别:软件把荧光信号转换成碱基序列,同时给出每个碱基的质量分数(Phred 分数)。
这一步输出就是你最原始的数据——FASTQ 文件。我见过不少团队直接拿 FASTQ 做归一化,这是不对的。FASTQ 还没经过比对,噪声很大。
1.2 常见数据类型:一路从原始读到特征矩阵
RNA-seq 的数据类型按处理阶段分为四层。我习惯把它们画成一条流水线,这样以后你看到某个文件就知道它处在哪个环节。
1.3 各数据类型详解
FASTQ — 原始读取
每一段 read 占 4 行:标识符、碱基序列、分隔符(+)、质量字符串。质量分数用 ASCII 码表示,Phred+33 编码。数值越高越可靠。
@EAS139:136:FC706VJ:2:2104:15343:197393
GATTTGGGGTTCAAAGCAGTATCGATCAAATAGTAAATCCATTTGTTCAACTCACAGTTT
+
!''*((((***+))%%%++)(%%%%).1***-+*''))**55CCF>>>>>>CCCCCCC65
实用技巧: 拿到 FASTQ 先跑 FastQC,看一下每个碱基位置的质量分布。如果尾部质量低于 Q20,直接截短或过滤掉。我一般用 Trimmomatic 或 fastp 做清洗,参数参考:
fastp -i sample_R1.fastq -I sample_R2.fastq -o clean_R1.fastq -O clean_R2.fastq \
--cut_front --cut_tail --cut_window_size 4 --cut_mean_quality 20
SAM / BAM — 比对结果
SAM(Sequence Alignment/Map)是比对后的文本格式,每行一个 read 的比对信息,包含 11 个必选字段和若干可选字段。BAM 是同样的数据但用 bgzip 压缩成二进制,体积大约只有 SAM 的 1/7。读取 BAM 必须用 samtools。
| 字段 | 说明 | 我常看的值 |
|---|---|---|
| QNAME | read 名字 | — |
| FLAG | 比对标志(二进制位掩码) | 0x4 = unmapped, 0x10 = reverse complement |
| RNAME | 参考序列名(染色体) | chr1, chr2, … |
| POS | 左端比对位置(1-based) | — |
| MAPQ | 比对质量 | >30 的 read 相对可靠 |
| CIGAR | 比对模式(M、I、D、S 等) | 100M 表示完全匹配 100 bp |
| RNEXT | 双端中另一 read 的染色体 | = 表示同一染色体 |
| PNEXT | 另一端位置 | — |
| TLEN | 插入片段长度 | 负值表示在另一侧 |
| SEQ | 碱基序列 | — |
| QUAL | 质量值(ASCII-33) | 与 FASTQ 相同 |
避坑: 我曾在做表达定量时,直接用 featureCounts 读原始 BAM 文件而忘了排序。结果 featureCounts 报了一堆“skip unmapped pair”的警告,实际上它要求 BAM 必须按染色体坐标排序。解决办法:
samtools sort -o sorted.bam unsorted.bam
samtools index sorted.bam
Count Matrix — 表达特征矩阵
最后得到的行是一基因、列是一样本、值是基因比对到该样本的 read 计数(整数)。这个矩阵就是我们模型训练的输入特征。格式通常很简单:
Geneid Sample1 Sample2 Sample3
ENSG000001 100 150 98
ENSG000002 200 180 210
ENSG000003 50 60 55
用 Python 读取时,我习惯把第一列设为 index:
import pandas as pd
counts = pd.read_csv('counts.txt', sep='\t', index_col=0)
print(counts.shape) # (基因数, 样本数)
关键点: Count Matrix 的值是整数,且分布极度偏斜(大部分基因低表达)。直接扔进神经网络?不行的。后面我们会讲多种归一化方法(TPM、FPKM、log2(CPM) 等)。现在你只要记住:千万别把原始 count 直接当特征,模型会崩溃的。
1.4 小结:数据流各阶段你应该关心什么
- FASTQ 阶段:关注测序质量、接头污染、GC 含量。质量不好就重新测或过滤。
- SAM / BAM 阶段:关注比对率(通常 >70% 算合格)、唯一比对比例、双端映射一致性。
- Count Matrix 阶段:关注基因覆盖度(有多少基因 count > 0)、是否有批次效应、样本间总 read 数是否差异过大。
我个人经验:花 70% 的时间在数据清洗和质控上,后面模型调参才会顺。否则你调出来的参数可能只是过拟合了噪声。