
文章目录背景从修改 TPM 值这一步开始一步一步逆向操作到 FASTQ核心流程图逆向工程第一步修改 TPM 值假设原始数据假设你想画成的样子修改 TPM第二步TPM → Count最关键的一步为什么需要这一步公式具体计算第三步Count → 带噪声的计数矩阵NB分布登场为什么需要噪声NB分布抽样gene/转录本i样本j第四步计数矩阵 → FASTQ物理模拟对每个基因i、每个重复j执行第五步送去重新分析为什么 FastQC 查不出来更深一步隐变量结构与EM算法的适用性RNA-seq确实存在多层隐变量结构经典RNA-seq工具确实在用类似EM的思想逆向合成场景其实有其特殊性正向 vs 逆向问题的隐变量角色不同逆向合成时隐变量被显式控制了那么EM在哪里或者说需要在哪里如果要让伪造数据更真实确实可以引入更深层的隐变量这种深层模型下EM/变分推断的价值一个更深刻的视角总结至于吗背景最近看到一篇公众号推文讲的是“转录组原始数据修改软件”据称能够随意调节转录组原始数据某个基因的表达大肆吹嘘有多有用仅供科学教研使用。我一看这不就是精细一点的NGS simulator吗十多年前搞NGS模拟数据分析的时候就有人开发过类似idea的软件了当然不是说RNA-seq。然后涉及到其他的测序技术时代往后一点搞这种人工合成仿真的也不少起码也是五六年前起步了这种玩意居然还能拉出来炒作一波还能搞个收费服务(─.─|||。我这里简单总结一下从 RNA-seq 的 TPM或者 Count表达矩阵“逆向”生成 FASTQ 原始测序文件在生物信息学中是一项非常成熟的技术。它不需要用到 diffusion、VAE、flow matching 等那种复杂的深度学习“生成模型Generative Models”而是基于统计学抽样和确定性的序列拼接算法从修改 TPM 值这一步开始一步一步逆向操作到 FASTQ⚠️ 本文中涉及到RNA-seq分析操作具体细节的我这里模糊处理用粗糙例子演示毕竟好久不做组学分析了以原理演示为准顺带找了一个例子软件作为参考polyester核心流程图逆向工程目标火山图你想长什么样 ↓ 修改 TPM 值某些基因上调/下调 ↓ TPM → Count逆向标准化 ↓ Count → 负二项分布抽样加噪声 ↓ 得到伪造的计数矩阵 ↓ 从参考基因组切序列 → 片段化 → 加错误 → FASTQ ↓ 送去重新分析 → 得到你想要的火山图 ✓第一步修改 TPM 值假设原始数据基因对照组 TPM处理组 TPMlog2FCA10100B20200C550火山图所有点都在中间无聊。假设你想画成的样子基因目标状态目标 log2FCA显著上调3B显著下调-2C不变0修改 TPM对照组 TPM 不变处理组 TPM 改 - 基因A: 对照10, 处理10 × 2^3 80 (上调8倍) - 基因B: 对照20, 处理20 × 2^(-2) 5 (下调到1/4) - 基因C: 对照5, 处理5 (不变)第二步TPM → Count最关键的一步为什么需要这一步TPM 是相对值总和10^6仅作演示Count 是绝对 reads 数。测序仪只认识绝对数。公式TPM i Count i / L i ∑ j ( Count j / L j ) × 10 6 \text{TPM}_i \frac{\text{Count}_i / L_i}{\sum_j (\text{Count}_j / L_j)} \times 10^6TPMi∑j(Countj/Lj)Counti/Li×106逆向求解 CountCount i TPM i × L i × N 10 6 \text{Count}_i \text{TPM}_i \times L_i \times \frac{N}{10^6}CountiTPMi×Li×106N其中L i L_iLi 转录本长度N NN 总 reads 数你设定的测序深度比如 1000万条具体计算假设总 readsN 10 , 000 , 000 N 10,000,000N10,000,000基因A长度L A 3000 L_A 3000LA3000bp基因对照组 TPM处理组 TPM长度对照 Count处理 CountA108030003002400B205150030075C552000100100验证对照组总 Count 700处理组总 Count 2575。不完美等于N NN因为 TPM 已经归一化过了需要缩放让总和合理。实际代码中会更复杂考虑有效长度、library文库大小因子但核心就是把相对 TPM 变回绝对 Count。第三步Count → 带噪声的计数矩阵NB分布登场为什么需要噪声真实数据有生物学重复间的波动。如果每个重复都恰好是 2400太假了。这里说的重复的意思是指样本的重复前面我们演示的是两个样本1个对照1个处理其实真实测序之类大家应该都是做多个重复的所以比如说3组重复就是3个对照 vs 3个处理那么比如说我处理组前面算出来 2400 这个是绝对数值的count这个count一般是均值意义但是我们如果3个处理组的样本都是 2400、2400、2400就太假了。总而言之这里说的是从tpm求得到的count的绝对值是作为1个均值然后需要在多个重复样本之间做采样还原分布。负二项分布的原理我们就不讲了NB分布抽样gene/转录本i样本jCount i j observed ∼ NB ( μ Count i j target , size ) \text{Count}_{ij}^{\text{observed}} \sim \text{NB}(\mu \text{Count}_{ij}^{\text{target}}, \text{size})Countijobserved∼NB(μCountijtarget,size)对基因A处理组目标均值 2400重复1: NB(2400, size800) → 抽得 2356 重复2: NB(2400, size800) → 抽得 2489 重复3: NB(2400, size800) → 抽得 2210size 参数控制方差size 大 → 方差小重复间很接近太假size 小 → 方差大重复间波动大像真实实验前面举例说的 Polyester默认 用 size μ/3即 800属于偏小的方差理想化数据。当然仅作为演示示例参考真实数据不表。⚠️ 再次强调我们只是模糊演示对于真实的 差异表达分析经典软件中的NB分布采样实现比如说edgeR、DESeq2它们的真实假设是否是“同一个条件下重复来自同一个分布有共同的均值和离散度”这里没有细究。总而言之NB 抽样就是制造符合这个假设的假数据让下游分析工具以为这是真实的生物学重复。第四步计数矩阵 → FASTQ物理模拟现在你有哪些东西呢比如说处理组基因重复1 Count重复2 Count重复3 CountA235624892210B788265C10298101对每个基因i、每个重复j执行基因A重复1需要造 2356 条 reads ↓ 转录本A序列3000bp从参考基因组GTF拼接 ↓ 循环 2356 次 抽片段长度 F ~ N(250, 25) → 比如 F248 抽起始位置 S ~ Uniform(1, 3000-2481) → 比如 S500 切片段 [500:747] 左端 read [500:649]150bp正向 右端 read reverse_complement([598:747])150bp 逐碱基加错误Bernoulli 0.5% 赋质量值 写入 sample_01_1.fasta, sample_01_2.fasta⚠️ 我们耳熟能详的NB分布也就是RNA-seq 涉及到的原理部分发挥作用的主要地方就在于从前面 相对tpm值反推绝对count值然后从这个count的绝对值这个均值中采样多个重复组的各自count中。说白了就是只用于计数矩阵的生成。然后上面的循环中说到的另外两个采样也就是 reads片段的采样、reads测序位置的采样这两个是和NB分布无关的完全是为了模拟一个物理测序过程。当然物理测序过程也是比较复杂的我们这里是用简单的正态分布和均匀分布来演示。至于为什么这里还需要这些抽样来模拟是因为真实测序不是从基因头测到尾是随机打断后测两段的。也就是说前面NB分布是数的问题后面是造序列的问题。这里稍微提一下碱基质量值如何模拟也就是Phred质量值这里也不赘述质量值和错误率的数学关系了要如何模拟Q值其实就是要模拟碱基测序的一个错误率分布关系最粗暴的方法就是均匀模型也就是设置1个全局错误率比如说p0.005也就是0.5%就是位置无关的均匀分布大家错误率一致那么这个时候对于每一个碱基决定是否出错就是一个非常简单的伯努利分布了如果是测错了那么就把这个碱基替换成其他三个碱基即可random.choice 的replace总而言之fastq这4行都能凑起来第五步送去重新分析伪造的 FASTQ ↓ [质控 FastQC] → 通过因为错误率、质量分布都是按真实模型造的 ↓ [比对 HISAT2/STAR] → 比对到参考基因组 ↓ [定量 Salmon/RSEM] → 得到新的 TPM/Count ↓ [差异分析 DESeq2/edgeR] → 火山图 ↓ 基因A: log2FC ≈ 3, p 0.001 ✓ 基因B: log2FC ≈ -2, p 0.001 ✓ 基因C: log2FC ≈ 0, p 0.05 ✓完美符合我们预设的火山图当然了偷懒一点的做法就是修改好tpm值然后按照前面说的逆向生成fastq测序数据做的话直接按照修改之后的目标tpm去做各种下游分析为什么 FastQC 查不出来FastQC 检查什么Polyester 怎么应对碱基质量分布按 Illumina 模型生成符合GC 含量按转录本真实序列计算符合序列重复度因为是从真实基因组切的符合接头污染不加接头所以没有k-mer 异常随机抽样无异常FastQC 只能查数据质量是否像真的不能查这些 reads 是否真的从某个细胞里测出来的。更深一步这里简单涉及一下EM因为话题和朋友聊的时候扯到了隐变量结构与EM算法的适用性RNA-seq确实存在多层隐变量结构真实生物学状态 (θ) ← 我们真正关心的 ↓ 泊松/伽马抽样 表达强度 (λ) ← 不可直接观测 ↓ NB抽样 (size参数控制过散) 观测Count (x) ← 实际测到的 ↓ 测序深度/长度标准化 TPM/FPKM ← 相对丰度估计经典RNA-seq工具确实在用类似EM的思想软件隐变量处理核心方法RSEM转录本-读段分配不确定EM算法迭代估计isoform表达Salmon/Kallisto读段来源转录本在线EM / 变分推断BitSeq转录本比例Gibbs采样MCMCeXpress片段-转录本匹配EM-like在线更新RSEM是最典型的例子一个读段可能比对到多个转录本EM迭代E步计算读段属于各转录本的后验概率M步更新各转录本表达量逆向合成场景其实有其特殊性正向 vs 逆向问题的隐变量角色不同方向问题类型隐变量角色正向分析从FASTQ推断表达reads读段来源、真实表达强度都是未知的逆向合成从目标TPM生成FASTQ我们设定了真实值隐变量被解耦了逆向合成时隐变量被显式控制了目标TPM (人为设定) ↓ 确定性计算 目标Count f(TPM, L, N) ← 没有随机性是计算不是估计 ↓ NB抽样 (μ目标Count) 观测Count ~ NB(μ, size) ← 这里引入随机性但μ已知 ↓ 物理模拟 FASTQ ← 完全可控的生成过程关键点逆向合成中真实值是我们人为指定的不需要从数据中推断。EM算法解决的是不知道真实值要从观测推断的问题。那么EM在哪里或者说需要在哪里如果要让伪造数据更真实确实可以引入更深层的隐变量当前polyester类工具的简化假设给定μ → NB抽样 → Count更真实的层次模型可用变分推断或MCMC样本条件效应 β ~ Normal(0, σ²_条件) ← 批次/处理效应 基因特异性效应 α_g ~ Normal(0, σ²_g) ← 基因间差异 样本-基因交互 γ_{sg} ~ Normal(0, σ²_γ) ← 真实生物学变异 log(μ_{sg}) 偏移 β_s α_g γ_{sg} ← 对数线性模型 Count_{sg} ~ NB(μ_{sg}, size_g) ← 观测这种深层模型下EM/变分推断的价值场景方法目的从真实数据学习参数EM / 随机EM估计σ²_条件, σ²_g, size_g等生成逼真伪造数据从拟合模型前向采样让假数据的协变结构更真实伪造数据质量检验后验预测检验看生成的数据是否与真实数据不可区分问题答案当前polyester式逆向合成需要EM吗不需要——因为目标值是人为设定的不是从数据估计的要让伪造数据更逼真需要吗可以要——先从大量真实数据学习深层生成模型再采样EM/变分推断在这里的角色模型学习阶段而非数据生成阶段一个更深刻的视角我们前面描述的修改TPM→逆向生成FASTQ本质上是确定性反演随机前向模拟的混合确定性部分: TPM → Count (可精确反解) 随机部分: Count → 带噪Count → FASTQ (需要合理的生成模型)如果要从数学原理上最严谨地伪造数据应该用真实数据集训练一个深度生成模型如VAE、扩散模型、或层次贝叶斯模型隐空间插值/条件生成得到看似真实但表达被调控的数据这比手工调TPM更不易被检测因为协方差结构、基因间相关性都是真实的目标表达变化是伪造者自己定的让变化看起来自然的噪声结构才是需要从真实数据学习的——EM/变分推断学的是后者不是前者。总结至于吗总而言之根本不需要什么生成模型就是看你组学测序背后的统计学原理了解的有多少。那么回过头来怎么评价这件事1个简单的NGS simulator实现原理本身不难写code的话有了AI更是直接工程化一键走起就这玩意还有人吹捧还有人打着幌子搞收费分析怎么搞无非是对那些半吊子做计算生物的新手、菜鸟忽悠一下比如说“哎呀你是不是不愿意学RNA-seq是不是原理搞不清楚这些通通不用管哎呀你跑网上的/ai给的脚本是不是拿不到你想要的差异结果哎呀你是不是想要这个gene高一点那个gene低一点。没事用我的软件保准出图让你满意甚至连上游fastq都能以假乱真”。一句话能被菜鸟割技术韭菜的本身也差不多是菜鸟都是不好好静下心来学原理所背技术债的锅。