单细胞流程

10X单细胞数据整合分析Seurat之rpca(large da

2021-04-23  本文已影响0人  单细胞空间交响乐

不知道大家在研究单细胞数据整合函数FindIntegrationAnchors的时候没有发现一个很有意思的参数,那就是reduction,有两个选项,一个是cca,一个是rpca,其中关于FindIntegrationAnchors大家可参考我的文章Seurat包其中的FindIntegrationAnchors函数解析,有关CCA的算法,我之前也分享过,文章深入解析Seurat整合单细胞数据函数FindIntegrationAnchors 2(CCA和L2正则化算法),而我们今天就是要来深入探讨一下有关rpca的内容,知道rpca首先要知道pca,关于pca的降维算法文章在单细胞PCA分析的降维原理,其中包括两个问题,什么是rpca?为什么在处理large data(超过20万)的时候要选择rpca??

简单回顾一下PCA

PCA(Principal Component Analysis),即主成分分析方法,是一种使用最广泛的数据降维算法。PCA的主要思想是将n维特征映射到k维上,这k维是全新的正交特征也被称为主成分,是在原有n维特征的基础上重新构造出来的k维特征。PCA的工作就是从原始的空间中顺序地找一组相互正交的坐标轴,新的坐标轴的选择与数据本身是密切相关的。其中,第一个新坐标轴选择是原始数据中方差最大的方向,第二个新坐标轴选取是与第一个坐标轴正交的平面中使得方差最大的,第三个轴是与第1,2个轴正交的平面中方差最大的。依次类推,可以得到n个这样的坐标轴。通过这种方式获得的新的坐标轴,我们发现,大部分方差都包含在前面k个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面k个含有绝大部分方差的坐标轴。事实上,这相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,实现对数据特征的降维处理。
思考:我们如何得到这些包含最大差异性的主成分方向呢?
答案:事实上,通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值特征向量,选择特征值最大(即方差最大)的k个特征所对应的特征向量组成的矩阵。这样就可以将数据矩阵转换到新的空间当中,实现数据特征的降维。
由于得到协方差矩阵的特征值特征向量有两种方法:特征值分解协方差矩阵、奇异值分解协方差矩阵,所以PCA算法有两种实现方法:基于特征值分解协方差矩阵实现PCA算法、基于SVD分解协方差矩阵实现PCA算法。
算法的话大家自行学习一下把,可参考上述文章。

rpca(鲁棒主成分分析)

Robust PCA考虑的是这样一个问题:一般的数据矩阵D包含结构信息,也包含噪声。那么可以将这个矩阵分解为两个矩阵相加:D = A + EA是低秩的(由于内部有一定的结构信息造成各行或列间是线性相关的),E是稀疏的(含有噪声,则是稀疏的)
首先阐述低秩和稀疏的区别和联系
稀疏和低秩的相同点在于都表明矩阵的信息冗余比较大。具体来说,稀疏意味着有很多零,即可以压缩(10X单细胞数据的特点);低秩意味着矩阵有很多行(列)是线性相关的(单细胞数据PCA的前提)。
秩可以理解为图像所包含的信息的丰富程度,秩越低表示数据冗余性越大,因为用很少几个基就可以表达所有数据了。相反,秩越大表示数据冗余性越小。
与经典PCA一样,Robust PCA(鲁棒主成分分析)本质上也是寻找数据在低维空间上的最佳投影问题。当观测数据较大和数据含有噪声时,PCA无法给出理想的结果,而Robust PCA能够从较大的且稀疏噪声污染的观测数据中恢复出本质上低秩的数据(这一点厉害了)。

图片.png
RPCA与PCA区别 Robust PCA与经典PCA问题一样,Robust PCA本质上也是寻找数据在低维空间上的最佳投影问题。对于低秩数据观测矩阵D,假如D受到随机(稀疏)噪声的影响,则D的低秩性就会破坏,使D变成满秩的。所以就需要将D分解成包含其真实结构的低秩矩阵A和稀疏噪声矩阵E之和。找到了低秩矩阵,实际上就找到了数据的本质低维空间,那么Robust PCA的Robust在哪呢?因为PCA前提假设的数据的噪声是高斯的,对于大的噪声或者严重的离群点,PCA会被它影响,导致其无法正常工作。而Robust PCA则不存在这个假设(Robust PCA假设噪声是稀疏的,而不管噪声的强弱)。

当然,这个过程跟PCA一样,充满了数学公式和算法,需要数学界的大牛来为我们解惑了,但是我们基本的内容我们需要知道,单细胞的数据矩阵分解为两个矩阵,低秩矩阵和噪声矩阵,而噪声矩阵具有很强的稀疏性(很符合单细胞数据的特点)

rpca在Seurat中整合分析的运用

其实知道了rpca的基础运用之后,不难理解rpca为什么用在large data的整合分析了,我们来看看:
数据过大Seurat给出了优化的方法:
For very large datasets, the standard integration workflow can sometimes be prohibitively computationally expensive. In this workflow, we employ two options that can improve efficiency and runtimes:

我们需要关注一下函数FindIntegrationAnchors的参数reference:
reference: A vector specifying the object/s to be used as a reference
          during integration. If NULL (default), all pairwise anchors
          are found (no reference/s). If not NULL, the corresponding
          objects in ‘object.list’ will be used as references. When
          using a set of specified references, anchors are first found
          between each query and each reference. The references are
          then integrated through pairwise integration. Each query is
          then mapped to the integrated reference.

也就是说,没有指定的情况下(默认情况),成对样本的anchors都会去发现,如果指定了ref,anchors are first found between each query and each reference. The references are then integrated through pairwise integration. Each query is then mapped to the integrated reference.当然,数据量小的前提下不需要指定ref,我们再往下分析:

首先来看rpca

The main efficiency improvements are gained in FindIntegrationAnchors(),rpca取代了cca,to identify an effective space in which to find anchors. 在使用rPCA确定任意两个数据集之间的锚点时,我们将每个数据集投影到其他PCA空间中,并通过相同的相互邻域要求约束锚点,All downstream integration steps remain the same and we are able to ‘correct’ (or harmonize) the datasets.

再来看指定ref

Additionally, we use reference-based integration. In the standard workflow, we identify anchors between all pairs of datasets. While this gives datasets equal weight in downstream integration, it can also become computationally intensive. For example when integrating 10 different datasets, we perform 45 different pairwise comparisons(计算量确实很夸张). As an alternative, we introduce here the possibility of specifying one or more of the datasets as the ‘reference’ for integrated analysis, with the remainder designated as ‘query’ datasets. In this workflow, we do not identify anchors between pairs of query datasets(这个地方需要注意一下), reducing the number of comparisons. For example, when integrating 10 datasets with one specified as a reference, we perform only 9 comparisons(计算量大大减少). Reference-based integration can be applied to either log-normalized or SCTransform-normalized datasets.(前期处理也必不可少)。
This alternative workflow consists of the following steps:

分享一下基础代码:

library(Seurat)
bm280k.data <- Read10X_h5("../data/ica_bone_marrow_h5.h5")
bm280k <- CreateSeuratObject(counts = bm280k.data, min.cells = 100, min.features = 500)
bm280k.list <- SplitObject(bm280k, split.by = "orig.ident")
bm280k.list <- lapply(X = bm280k.list, FUN = function(x) {
    x <- NormalizeData(x, verbose = FALSE)
    x <- FindVariableFeatures(x, verbose = FALSE)
})
features <- SelectIntegrationFeatures(object.list = bm280k.list)
bm280k.list <- lapply(X = bm280k.list, FUN = function(x) {
    x <- ScaleData(x, features = features, verbose = FALSE)
    x <- RunPCA(x, features = features, verbose = FALSE)
})

注意这里的重点:

anchors <- FindIntegrationAnchors(object.list = bm280k.list, reference = c(1, 2), reduction = "rpca", 
    dims = 1:50)
bm280k.integrated <- IntegrateData(anchorset = anchors, dims = 1:50)

下面的就简单了

bm280k.integrated <- ScaleData(bm280k.integrated, verbose = FALSE)
bm280k.integrated <- RunPCA(bm280k.integrated, verbose = FALSE)
bm280k.integrated <- RunUMAP(bm280k.integrated, dims = 1:50)
DimPlot(bm280k.integrated, group.by = "orig.ident")
图片.png

当我们的细胞数量超过10万,这个方法很好,值得学习

生活很好,有你更好

上一篇 下一篇

猜你喜欢

热点阅读