富集分析

说到富集分析,做生信的童鞋立刻就会想到基于差异基因数目的普通富集分析基于基因排名的GSEA这两大类功能富集分析方法。但这只是富集分析的两种常见形式,富集分析的概念要更广。基于差异基因数目 这一类富集分析是最简单的富集方法,只关心基因集的富集比例,我们一般称为ORA(Over-Representation Analysis,过表达分析);GSEA类方法更进一层,还关心基因集在打分排序中的分布情况,这类方法一般称为FCS(Functional Class Scoring,功能集打分)。我们经常使用富集分析的p值以及FDR值,判断是否富集显著。然而对应的统计量如何计算?富集分析能否在其他情形使用,如何使用?最简单的情形是,如何检验一个biomarker在某个模型中是显著富集的。本文将对此进行解析。

所谓富集分析,本质上就是对分布的检验,如果分布集中在某一个区域,则认为富集。比如正态分布就是一种富集在均值附近的分布。常用的分布检验方法有卡方检验、Fisher精确检验以及KS检验等方法。ORA类方法用的是离散分布的检验(Fisher精确检验,依据超几何分布的原理),网上有一些资料对此解释(浅探富集分析中的超几何分布),但笔者认为ORA类方法有个问题就是,同一个基因集里相反方向的差异基因该如何处理?首先需要明确的是,不同方向的差异基因应当分开进行富集分析。但是这样相当于把反方向的基因当成中性基因对待,实际上是否应当“抵消”处理呢?笔者倾向于是有必要“抵消校正”的,合理的传统富集分析,应当等价于将logFC值处理成1、0、-1(上调为1,下调为-1,中性为0),然后扔进GSEA;或者说,分布检验的时候,应当是三分布问题,而不是简单的二分布问题。当然也有人构建了补充变量,比如通过计算基因集内上调基因数和下调基因数的差值,构建新的统计量,与ORA的p值结合一起分析(GOplot的z-score)。个人认为,除了上述校正方法以外,还有一个思路就是反方向“稀疏分析”,就是说,一个基因集如果出现某个表型的显著富集,那么同时也要求其在相反表型中出现“显著稀疏”(也就是两个方向分开分析要同时具有显著性)。即使各种补充方法的提出,ORA类方法本身的弊病无法解决,将连续变量转成分类变量进行统计都是下下策(忽略了FC值和p值的连续性),统计效能势必大打折扣,关于ORA类方法,此处不作过多累述。本文重点关注连续分布的富集(GSEA)。

 

1- 统计学原理

1.1 Kolmogorov distribution

独立增量过程,指其增量是相互独立的。以下截图摘自百度百科:

      

从独立增量过程到Kolmogorov分布,再过渡到KS检验,需进一步补充(有空补充)。

 

1.2 Kolmogorov–Smirnov test

Kolmogorov–Smirnov检验(KS检验)的基本介绍,我再偷个懒,引用一个比较喜欢的讲解(Kolmogorov–Smirnov test

      

      

 

KS检验临界值表:www.cust.edu.tw/mathmet/KS-critical.docx

KS检验的不错的介绍:KS-检验(Kolmogorov-Smirnov test) -- 检验数据是否符合某种分布

KS检验的应用:检验数据是否符合某种分布,如正态分布。

KS检验的优点:作为分布检验的方法(或者说拟合优度检验),该检验不依赖于要测试的累积分布函数,相比于卡方拟合检验(卡方检验需要50个以上的样本),不需要大量的样本。

KS检验的缺点:只适用于连续分布(只能用于连续或定量数据);在分布中间敏感,在两端不够敏感;最大的局限在于整个分布需要完全确定,如果位置,形状等参数都是从数据中估计的,判定区间不再有效,因此这些参数一般只能通过模拟得到。

分布检验的比较:R语言 Shapiro-Wilk检验

不错的资料:

Kolmogorov-Smirnov Goodness-of-Fit Test

Kolmogorov-Smirnov检验

柯尔莫可洛夫-斯米洛夫检验

 

当数据服从正态分布时,KS检验比 t 检验效能低,但有的时候这种更严格也有好处。KS检验与 t 检验的对比:

      

因为样本的平均值和标准差非常相似,所以学生T检验最后给出了非常高的P值。KS测试却可以检测出方差。在这个案例中,KS测试发现了红色的分布中一点点的二项分布。

 

2- KS类富集分析的应用

GSEA采用了KS检验的思想,但是采用的是加权的近似KS检验方法。

GSEA的介绍可参考:一文掌握GSEA富集分析-最详细教程, 还比较详细的。注意,GSEA还用了置换检验来评估结果的可靠性。GSEA的数学原理还需要好好读读原论文!比如如何加权,为何最后曲线能回到0值处等等。

特征在模型中的富集

可以直接借助GSEA软件计算富集程度,也可以使用原始的KS检验计算。

比如某个分类指标与模型的关系,可以看看某个类是否富集到模型得分的某一端(以模型得分对样本排序,原假设是该类别在排序后的分布中是均匀分布的)。

但连续性指标与模型的关系,如何计算富集程度呢?一篇cell的OCLR干性文献里竟然对连续变量也计算量NES,神奇。实际上,任何类型的指标都可以计算NES,只需要事先算出rank即可。

(本部分待继续完善)

 

3-基因集打分方法概述

基因集打分(signature score,geneset score 或 metagene score)、构建功能指数(signature index),是生信分析中常见的分析策略,是一种特殊的建模方法。大致来讲,基因集打分主要分为两大类:基于富集打分、基于权重打分。

基于富集打分

基因集内部基因无差别对待,是FCS富集分析的特点之一(指普遍无差别,注意不要和排名的“有差别”混淆理解,因为不同样本的排名顺序不同)。无差别对待有弊有利,优势在于打分建模不容易过拟合(比较稳定),劣势在于建模欠拟合(不同基因的影响力不同,应当有权重)。这类方法包括:ssGSEA、GSVA、combined-zscore、PLAGE等。

combined-zscore 比较简单,并采取了 t-score排名法逐步构建核心基因子集。这个方法忽略了基因集的“分布”特征,打分比较粗略(可参考:Inferring Pathway Activity toward Precise Disease Classification)。

      

 

ssGSEA就是将GSEA算法应用于单样本,巧妙而简单。

GSVA和ssGSEA类似,也是基于KS类随机游走算法,但富集得分统计方式有些区别。

PLAGE基于SVD,方法比较古老,笔者对此未曾研究。

基于权重打分

最大的难点在于,权重如何确定。基因集内的基因表达往往共线性,直接建模来获取权重系数,有些不妥。但也有一些技巧可以使用。比如单变量建模后所得系数构建signature权重矩阵,然后直接建模或相关系数法计算得分;比如直接计算每个基因与基因集之间的相关系数(即平均相关系数),作为权重;比如计算Mutual Information(MI),作为基因间的相关程度,然后迭代计算基因与基因集之间的MI,从而作为权重(可参考:Biomolecular Events in Cancer Revealed by Attractor Metagenes)。

另外,还有解卷积类的方法也常用来构建权重矩阵(免疫浸润中经常使用这类方法),这部分内容本文不作介绍,可参考:转录组分析中的免疫浸润的评估方法

 

4-其他富集分析方法

可以参考这篇文献:Ten Years of Pathway Analysis: Current Approaches and Outstanding Challenges

或者参考这篇博客解读:功能富集分析概述

      

 

  • 3
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
SSGSEA(Single-sample Gene Set Enrichment Analysis)是一种基于基因集富集分析的方法,可以对单个样本进行基因表达谱的分析。以下是一个Python实现的SSGSEA富集分析代码示例: ```python import numpy as np from scipy.stats import norm def ssgsea(gene_exp, gene_sets, nperm=1000, weighted_score_type=1, permutation=True, min_size=1, max_size=5000, verbose=False, seed=None): """ :param gene_exp: array-like, shape (n_samples, n_features) Gene expression matrix (rows are samples and columns are features). :param gene_sets: dict Gene sets in the format of dictionary. Keys are pathway names and values are gene lists. :param nperm: int, optional The number of permutations for calculating the p-value. Default is 1000. :param weighted_score_type: int, optional The weighting score type. Default is 1. :param permutation: bool, optional Whether to do permutation for calculating the p-value. Default is True. :param min_size: int, optional The minimum number of genes in a gene set to be considered. Default is 1. :param max_size: int, optional The maximum number of genes in a gene set to be considered. Default is 5000. :param verbose: bool, optional Whether to print the progress. Default is False. :param seed: int, optional The seed for the random number generator. Default is None. :return: dict A dictionary of pathway names and enrichment scores. """ # Initialize the random number generator if seed is not None: np.random.seed(seed) # Prepare the gene expression matrix gene_exp = np.array(gene_exp) # Prepare the gene set list gene_sets = {k: v for k, v in gene_sets.items() if min_size <= len(v) <= max_size} # Compute the gene set scores pathways = {} for pathway, genes in gene_sets.items(): # Compute the gene set score for each sample gss = [] for i in range(gene_exp.shape[0]): # Get the gene expression values for the pathway genes pathway_exp = gene_exp[i, np.isin(gene_exp.columns, genes)] # Compute the gene set score if weighted_score_type == 0: gss.append(pathway_exp.sum()) elif weighted_score_type == 1: gss.append(pathway_exp.mean()) elif weighted_score_type == -1: gss.append(pathway_exp.abs().mean()) # Compute the enrichment score and p-value if permutation: null_gss = [] for i in range(nperm): # Shuffle the gene expression values shuffle_exp = gene_exp.apply(np.random.permutation, axis=1) # Compute the gene set score for each sample null_gss.append(shuffle_exp.apply(lambda x: x[np.isin(gene_exp.columns, genes)].mean(), axis=1)) null_gss = pd.concat(null_gss, axis=1) null_es = null_gss.apply(lambda x: (x > gss).mean() - (x < gss).mean()) es = (gss - null_es.mean()) / null_es.std() pval = (null_es < gss).mean() else: es = (gss - gss.mean()) / gss.std() pval = 1 - norm.cdf(es) pathways[pathway] = {'es': es, 'pval': pval} if verbose: print('%s: ES = %.3f, p-value = %.3f' % (pathway, es, pval)) return pathways ``` 该代码使用了NumPy和SciPy库进行计算。在使用时,需要将基因表达谱和基因集传递给`ssgsea`函数。此外,还可以设置其他参数,例如是否进行置换和置换次数等。函数返回一个包含富集分析结果的字典。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FarmerJohn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值