1️⃣ 为什么使用的是 LOESS 回归?

理由一:非线性趋势建模

基因表达熵(entropy)与平均表达量(mean expression)之间的关系不是线性的,例如:

  • 低表达时,熵通常更小(噪声大但波动小);
  • 中等表达时,熵最大(表达分布更不确定);
  • 高表达时,熵可能趋于稳定(如 housekeeping genes 表达稳定);

LOESS 是局部加权回归(Locally Weighted Regression)

  • 它不假设全局函数形式;
  • 而是通过局部加权平均拟合每个点的趋势;
  • 适合高波动、局部结构复杂的生物数据(比如 gene expression)。

理由三:对异常值鲁棒

在一定参数(如 span)下,LOESS 的局部拟合对于一些全局异常基因不会过度受影响,和 spline 或 polynomial regression 相比更稳定。


2️⃣ 为什么要多次过滤后再次 LOESS 回归?

这是一种 “迭代去极值(refitting after denoising)” 策略,目的:得到更鲁棒、更可信的背景趋势。


背景:你最开始拟合的是所有基因,但其中很多可能是异常点!

比如:

  • 有些基因是真正的 marker gene,在某些细胞中特异表达;
  • 有些是技术噪声或 dropout artifacts;
  • 它们偏离趋势,可能会严重影响首次拟合的曲线(尤其 LOESS 是局部加权,会受点密度影响)。

✅ 过滤再拟合的动机是:

  • 第一次拟合只是粗略趋势;
  • 将显著偏离曲线(p > 0.1)的点去除;
  • 用剩下的“背景点”再次拟合,得到更稳定的期望表达熵曲线;
  • 这样你最后计算的 ds = fit - entropy 就能更真实地反映“异常偏差”。

❓如果只拟合一次会怎样?

如果只做第一次回归,会带来几个潜在问题:

问题类型说明
📉 偏差高熵或低熵的极端基因可能拉动局部拟合,使 trend 曲线不真实
🧪 错误识别一些正常基因被误判为显著偏离(False Positive)
🪃 不稳定性trend 曲线可能在低表达区域剧烈抖动,影响 ds 精度
问题回答
为什么用 LOESS?因为 entropy ~ mean.expr 是非线性关系,LOESS 灵活拟合,不强加函数形式,适合表达数据
为什么要多次过滤回归?为了排除“异常基因”对背景趋势的干扰,得到更可信的表达期望曲线
只回归一次会怎样?会引入偏差、误判异常基因、降低 ds 准确性,最终影响 Rogue 值或 marker 判断

利用 表达熵的拟合期望值与真实值之间的差异 (ds),衡量一组基因是否“表达有序”,再通过一个惩罚系数 k 平衡这个偏差,最终得到一个不纯度的反指标 Rogue。


🔍 我们来看这个表达式的数学结构:

其中:

  • 是 显著偏离的基因的总偏差量;
  • 是 平台相关的噪声/惩罚项;
  • Rogue 就是一个 基于“偏离程度”的归一化得分,值 ∈ (0, 1)。

数学思想背后是什么?

这个形式来源于 归一化惩罚 和 信噪比评分思想,它属于以下几种经典思想的混合:


① 比例抵消思想(Softpenalization)

形式:

常用于:

  • 信号强度归一化;
  • 距离函数平滑处理;
  • 惩罚项的比率缩放。

在这里:

  • 是偏差值,越大表示越“不纯”;
  • 是常数惩罚项,越大越“宽容”;
  • 所以 是一个不纯度量;
  • 最后再 1 - ... 就成了一个**“纯度评分”**。

② 类似 F-score 或 Mutual Information 的结构

这种形式也和下列思想相似:

  • F-score 中有:

  • KL 散度或 Mutual Information 也用对比项做归一化;

  • 精神是:相对比较 而不是绝对值。


③ 在生物信息学中类似的思想:

  • Gini impurity:衡量群体中的“杂乱度”;
  • Shannon entropy:表示不确定性;
  • Noise score:衡量某一组基因的噪声含量;
  • LISI (Local Inverse Simpson Index):衡量细胞混合度;
  • Silhouette score:衡量聚类边界清晰程度。

这些方法大多使用类似:


✳️ 为什么要用这个形式?

  1. 有界(Bounded):保证 Rogue ∈ (0,1)
  • 保证输出具有可解释性;
  • 可以比较不同样本或基因组。
  1. 可调节:通过 k 灵活调节灵敏度
  • k 大 → 偏差容忍高(比如 full-length 测序噪声大);
  • k 小 → 偏差敏感(适合噪声小的如 UMI);
  1. 非线性收敛:偏差越大,分数越快速下降
  • 一开始偏差小,Rogue 几乎是 1;
  • 偏差累加越多,Rogue 下降越快,体现“异常富集”。

Rogue 值就像一个“表达行为是否出格”的评分:

  • 偏差越多、越离谱 → Rogue 越低(越叛逆);
  • 表达越一致、越接近背景期望 → Rogue 越高(越正常);
  • k 就像你容忍别人出格的程度。

非常好的问题!这关乎你整个分析流程中对 “显著偏离” 的定义,以及如何计算最终的 Rogue 值。我们来严谨地分析下。

你指的是最后计算 Rogue 指标的这段代码逻辑:

sig_value <- abs(.x$ds[.x$p.adj < cutoff & .x$p.value < cutoff])
sig_value <- sum(sig_value)
Rogue <- 1 - sig_value / (sig_value + k)

也就是说:

  • 默认只统计 padj < 0.05 且 p < 0.05 的基因的 ds 值;
  • 然后再计算 Rogue;
  • 你现在问:如果不筛选 padj,而是对所有基因都计算 ds 的绝对值之和,会有什么区别?

✅ 先看结果上会发生什么

情况影响
使用 padj 过滤只关注“真正显著”的异常基因,Rogue 更保守(更容易接近 1)
不过滤,使用所有 ds所有大大小小的偏差都会累积,Rogue 值通常更小(更敏感)

🔬 为什么这会发生?

2️⃣ 不过滤 = 把“背景噪声”也计入 Rogue

这样做的影响是:

  • 你把很多“小的、可能只是技术波动”的 ds 也算了进去;
  • sig_value 会变得更大;
  • Rogue 分数会变得更小(看起来更“乱”);
  • 可能会高估样本的不纯度,甚至误判。

🔁 什么时候该用全体 ds?

这取决于你的目标:

目标策略
✅ 想要找到 biologically meaningful 的表达异常使用 padj 过滤(更可信)
🧪 想要做敏感度分析或 noise profiling可以考虑不做过滤(但要注明)
📊 对不同数据做比较(如两个平台)推荐使用 padj 过滤保持一致性

可以将 ds 看作“每个基因的行为是否偏离预期”,而 p.adj 是这个偏离是否显著:

  • ✔️ padj 过滤 → 只看“真正叛逆”的人(有效行为);
  • ❌ 不过滤 → 所有人都算进去,包括只是轻微出格但无实际意义的行为(噪声);
问题回答
如果不过滤 padj,而是对所有 ds 取绝对值求和,会怎样?Rogue 会变得更小,更敏感,但可能被噪声放大,误判不纯度
为什么原始方法要用 padj 过滤?因为只保留显著偏差基因可以避免技术噪声干扰,更有生物解释力
是否可以用全体 ds?可以作为敏感性分析使用,但主分析建议仍保留 padj 过滤来保证稳健性