第一章 RNA-seq 数据基础:测序原理与常见数据类型

做模型训练,第一件事不是调参数,而是搞清楚你手里那碗数据到底是怎么来的。RNA-seq 数据看着简单——一个矩阵、几万行基因、几百个样本,但背后藏着不少坑。我刚开始做表达特征工程时,就因为在 FASTQ 阶段没注意质量,导致后面模型怎么调都过拟合。所以这一章我们先把地基打牢。

1.1 测序原理:从 RNA 到碱基序列

说白了,RNA-seq 就是用高通量测序仪把细胞里所有的 RNA 分子“读”成短小的碱基片段(reads)。目前最主流的是 Illumina 的边合成边测序技术,流程大致分四步:

  1. 建库:把 RNA 反转录成 cDNA,然后打断、加接头、PCR 扩增。
  2. 簇生成:把文库加载到 flow cell 上,桥式 PCR 形成一个个单克隆簇。
  3. 测序:用带有荧光标记的 dNTP 一个一个碱基合成,机器拍下每个簇的荧光信号。
  4. 碱基识别:软件把荧光信号转换成碱基序列,同时给出每个碱基的质量分数(Phred 分数)。

这一步输出就是你最原始的数据——FASTQ 文件。我见过不少团队直接拿 FASTQ 做归一化,这是不对的。FASTQ 还没经过比对,噪声很大。

1.2 常见数据类型:一路从原始读到特征矩阵

RNA-seq 的数据类型按处理阶段分为四层。我习惯把它们画成一条流水线,这样以后你看到某个文件就知道它处在哪个环节。

RNA-seq 数据流水线:从原始读到表达矩阵 FASTQ 原始 reads + 质量 SAM 比对结果(文本) BAM 压缩二进制 Count Matrix 基因×样本 核心操作与工具 • FASTQ → SAM:比对器(STAR / HISAT2 / BWA) • SAM → BAM:samtools view -bS(压缩+排序) • BAM → Count Matrix:featureCounts / HTSeq-count • 注意:SAM 文件极大(通常数十 GB), 生产环境几乎只用 BAM 存储。我曾在服务器上 不小心解压了一个 SAM,直接撑爆硬盘……

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。

字段说明我常看的值
QNAMEread 名字—
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% 的时间在数据清洗和质控上,后面模型调参才会顺。否则你调出来的参数可能只是过拟合了噪声。