要安装软件包,请使用以下方法。
if (!requireNamespace("BiocManager")) install.packages("BiocManager") BiocManager::install("mbkmeans")
这个小插图提供了一个介绍性的示例,介绍如何使用mbkmeans
包中提出的小批k-means算法的实现(2010年斯卡利)用于大型单细胞测序数据。该算法在数据的小、随机子样本(“小批量”)上运行_k_means迭代,而不是整个数据集。这既加快了计算速度,又减少了必须包含在内存中的数据量。
用户使用的主要功能是mbkmeans
.这是作为S4泛型实现的,方法是为矩阵
,矩阵
,HDF5Matrix
,DelayedMatrix
,SummarizedExperiment
,SingleCellExperiment
.
这些作品的灵感大多来自于MiniBatchKmeans ()
中实现的函数ClusterR
我们重用了其中实现的许多c++函数。
我们在这里的主要贡献是提供一个接口DelayedArray
和HDF5Array
包,所以mbkmeans
算法只在任何时候将当前迭代所需的“小批量”放入内存中,而从不需要将整个数据集加载到内存中。这允许用户运行小批处理k-means算法在不能完全装入内存的非常大的数据集上。mbkmeans
还可以在用户提供的内存矩阵上无缝地运行,与标准算法相比,这样做显著提高了算法的速度k-均值算法((希克斯等人,2020年)).完整的比较mbkmeans
与其他实现可以在(希克斯等人,2020年).
这项工作的动机是聚集大型单细胞rna测序(scRNA-seq)数据集,因此主要关注Bioconductor的SingleCellExperiment
和SummarizedExperiment
数据的容器。因此,mbkmeans
假设基因组数据的典型数据表示,其中基因(变量)在行中,细胞(观察值)在列中。这与大多数其他统计应用相反,特别是与统计数据::kmeans ()
和ClusterR: MiniBatchKmeans ()
假设按行进行观察的函数。
我们提供一个较低级别的mini_batch ()
的函数,该函数期望行中的观察结果并期望直接替换ClusterR: MiniBatchKmeans ()
对于磁盘上的数据表示,例如HDF5
文件。本文档的其余部分通过mbkmeans ()
接口;有兴趣的用户mini_batch ()
功能应参考其手册页。
为了说明一个典型的用例,我们使用pbmc4k
的数据集TENxPBMCData
包.该数据集包含一组来自健康捐献者外周血的约4000个细胞,预计将包含多种类型或细胞群。
我们会注意到mbkmeans
专为非常大的数据集设计,特别是大到无法将全部数据矩阵保存在内存中,或者无法计算所需的计算的数据集。这个小插图使用一个小数据集,允许用户快速跟随和理解命令。(希克斯等人,2020年)显示了使用的示例mbkmeans
使用具有130万单元格的数据集,这是观察内存使用改进和速度改进的更合适的大小。
首先,我们加载所需的包。
库(TENxPBMCData)库(scater)库(singlecellexperexperiment)库(mbkmeans)库(DelayedMatrixStats)
请注意,在这个小插图中,我们的目标不是识别生物学上有意义的集群(这将需要更复杂的数据规范化和降维),相反,我们的目标只是展示如何运行小批处理k-表示在hdf5支持的矩阵上。
我们简单地通过缩放计数的总数来规范化数据嘘
然后选择1000个最易变的基因和随机的100个细胞来加速计算。
tenx_pbmc4k <- TENxPBMCData(dataset = "pbmc4k") set.seed(1034) idx <- sample(seq_len(NCOL(tenx_pbmc4k)), 100) sce <- tenx_pbmc4k[, idx] #normalization sce <- logNormCounts(sce) vars <- rowVars(logcounts(sce)) names(vars) <- sort(vars, reduced = TRUE) sce1000 <- sce[names(vars)[1:1000],] sce1000 . #
## class: singlecellexperexperiment ## dim: 1000 100 # metadata(0): ## assays(2): counts logcounts ## rownames(1000): ENSG00000090382 ENSG00000204287…ENSG00000117748 ## ENSG00000135968 ## rowData名称(3):ENSEMBL_ID Symbol_TENx Symbol ## colnames: NULL ## colData名称(12):Sample Barcode…Date_published sizeFactor ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(0):
mbkmeans
主要功能,mbkmeans ()
返回一个列表对象,包括重心
,WCSS_per_cluster
(其中WCSS表示在-cluster-sum-of-squares内),best_initialization
,iters_per_initiazation
和集群
.
它接受任何类似矩阵的对象作为输入,比如SummarizedExperiment
,SingleCellExperiment
,矩阵
,DelayedMatrix
和HDF5Matrix
.
在本例中,输入是aSingleCellExperiment
对象。
res <- mbkmeans(sce1000, clusters = 5, reduceMethod = NA, whenassay = "logcounts")
集群的数量(如k在k-means算法)通过集群
论点。在这种情况下,我们设集群= 5
没有特别的原因。为SingleCellExperiment
对象时,函数提供reduceMethod
和whichAssay
参数。的reduceMethod
参数应该指定用于聚类的降维槽,默认为“PCA”。请注意不能执行但只查看一个名为“PCA”的槽位,该槽位已经存储在对象中。或者,也可以指定whichAssay
作为小批次输入的检测方法k则。这只在以下情况下使用reduceMethod
选择是NA
.看到mbkmeans ?
了解更多细节。
还有其他的论点mbkmeans ()
使功能更加灵活,适用于更多的情况。
小批量的大小是通过batch_size
论点。这个参数给出了在任何时间放入内存的数据样本的大小,从而限制了算法的内存使用。
的blocksize ()
函数可用于将批处理大小设置为可用内存所允许的最大值。它考虑数据集中的列数和当前matchine上的RAM数量,以计算会话可用RAM的合理批处理大小。计算使用get_ram ()
函数benchmarkme
包中。看到benchmarkme
更多细节请参见插图。
Batchsize <- blocksize(sce1000) Batchsize
## [1] 100
在这个简单的例子中,因为整个数据都适合内存,默认批处理大小将是一个大小为100的单个批处理。
(希克斯等人,2020年)为大型数据集(即不能将全部数据存储在内存中)提供批处理大小的效果比较。他们的结果表明,该算法在大范围的批处理大小(1000 -10,000个单元)下都是稳健的:如果批处理大小超过500-1000个单元,结果的准确性是相同的,只要批处理小于大约10,000个单元(对应于完整数据矩阵的子样本,其内存占用在大多数现代计算机上不明显),在内存使用或速度上没有明显的优势。由于这个原因,我们可能会在建议的较大的批大小范围上出错(希克斯等人,2020年)- 10000个细胞。此外,由于初始化默认使用与批处理大小相同的单元数,这为确定初始起点提供了一个健壮的样本。
我们要注意的是,最好在选择的基础上对批大小进行选择绝对批处理中的单元数,而不是根据总体样本量的百分比来选择批处理大小。如果批处理大小是根据单元格的百分比来选择的,那么非常大的数据集将使用非常大的单元格批次,从而抵消了内存和速度的提高。此外,算法的良好性能不需要如此大的批量。批次的连续重采样工作类似于随机梯度下降,并允许(局部)最小化目标函数(2010年斯卡利)以相对较小的批处理规模,在单细胞数据的工作中证明(希克斯等人,2020年).如果有什么区别的话,批处理的大小应该更多地取决于问题的复杂性(例如,底层真正的集群或子类型的数量),而不是数据集中的整体单元的数量。
小批量的性能k-means在很大程度上取决于初始化过程。我们实现了两种不同的初始化方法:
kmeans + +
,如(Arthur和Vassilvitskii 2007).默认为“kmeans++”。用于初始化质心的数据百分比是通过init_fraction
参数,它应该大于0小于1。给出了默认值,以便比例与的值匹配batch_size
,转换为数据的一个比例。
res_random <- mbkmeans(sce1000, clusters = 5, reduceMethod = NA, whenassay = "logcounts", initializer = "random")表(res$ clusters, res_random$ clusters)
## ## 1 23 4 5 ## 1 0 0 0 0 1 ## 2 0 0 1 0 0 0 ## 3 4 0 23 0 0 ## 4 0 0 0 0 4 ## 5 0 5 0 14 48
的大值init_fraction
将导致该比例的数据保存在内存中并用于kmeans + +
算法。因此,大的值init_fraction
将需要大量的内存—可能比实际的聚类算法使用的内存还要多。事实上,对于越来越大的数据集,保持使用的比例不变将导致初始化中使用的单元数很少,并增加内存使用(类似于上面讨论的批处理大小问题)。因此,我们建议用户保持默认值,并对batch_size
参数,确保算法的初始化阶段和实际聚类阶段的内存使用一致。正如上面所提到的讨论batch_size
因此,我们推荐batch_size
在较大的范围内建议为合理(希克斯等人,2020年)从而改进初始化。
mbkmeans
的多个值\ (k \)设置的主要参数\ (k \)-means及其变体为簇数\ (k \).mbkmeans
足够快,即使在非常大的数据集中,也可以对不同数量的簇重新运行聚类算法。
这里,我们应用mbkmeans
与\ (k \)从5到15,使用弯头法(即曲线上的拐点对应的值)选择簇数。我们注意到,这只是选择集群数量的经验法则,存在许多不同的方法来确定的适当值\ (k \).
为了加快计算速度,我们将集中在前20台pc上。
sce1000 <- runPCA(sce1000, ncomponents=20) ks <- seq(5,15) res <- lapply(ks, function(k) {mbkmeans(sce1000, clusters = k, reduceMethod = "PCA", calc_wcss = TRUE, num_init=10)}) wcss <- sapply(res, function(x) sum(x$WCSS_per_cluster)) plot(ks, wcss, type = "b")
从剧情来看,似乎K = 12
可能是一个合理的值。
注意,如果我们设置Init_fraction = 1
,初始化器= "random"
,批量大小= ncol(x)
,我们恢复了经典k则算法。
res_full <- mbkmeans(sce1000, clusters = 5, reduceMethod = NA, which = "logcounts", initializer = "random", batch_size = ncol(sce1000)) res_classic <- kmeans(t(logcounts(sce1000)), centers = 5)表(res_full$ clusters, res_classic$cluster)
## ## 1 2 3 4 5 ## 10 7 0 7 0 ## 2 0 0 14 43 0 ## 3 2 0 0 0 0 0 ## 4 16 0 0 0 10 ## 5 0 0 0 10
但是请注意,由于这两种算法从不同的随机初始化开始,它们不会总是收敛到相同的解。此外,如果算法使用的批小于完整数据集(batch_size < ncol (x)
),然后mbkmeans
不会收敛到和kmeans
即使有相同的初始化。这是因为kmeans
和mbkmeans
有不同的最优搜索路径,问题是非凸的。
的内存使用情况、速度和准确性的比较mbkmeans
与kmeans
对于算法使用批处理的非平凡情况,请参见(希克斯等人,2020年),其中证明mbkmeans
提供了显著的速度改进和使用更少的内存kmeans
,而不丧失准确性。
的咆哮包为在Bioconductor包/工作流中进行集群提供了一个灵活和可扩展的框架。的clusterRows ()
函数控制调度到不同的聚类算法。在本例中,我们将使用小批处理k-means算法,根据其主成分分析(PCA)坐标将细胞聚类为细胞群。
- reducedDim(sce1000, "PCA") dim(mat)
## [1] 100 20
在以下三个场景中,我们将集群中心的数量作为数字传递中心= 5
论点。此外,我们还可以通过其他mbkmeans
参数(如。batch_size = 10
).在前两种情况下,我们只返回集群标签。然而,在第三种情况下,我们要求完整的mbkmeans
输出。
库(bluster) clusterRows(mat, MbkmeansParam(centers=5))
# #[1] 2 5 5 5 4 3 1 1 3 5 1 2 5 1 1 1 3 5 3 2 1 5 5 1 3 1 1 5 1 3 4 5 1 2 1 4 # #[38] 5 5 5 4 5 4 5 4 3 2 1 3 5 5 5 1 3 2 5 4 1 3 5 4 1 1 3 5 2 4 5 4 1 5 4 1 # #[75] 5 3 1 5 3 1 2 1 4 1 2 5 4 5 1 1 5 1 4 2 4 2 5 1 2 # #级别:1 2 3 4 5
clusterRows(mat, MbkmeansParam(centers=5, batch_size=10))
# #[1] 5 5 3 3 3 3 3 3 3 3 3 1 3 5 5 5 5 3 3 3 4 5 3 3 5 5 5 3 3 3 4 5 1 5 4 # #[38] 3 3 3 3 3 3 3 3 3 3 3 3 3 1 5 1 3 5 4 3 3 4 5 5 3 2 3 3 3 3 3 3 3 5 # #[75] 3 3 3 3 5 4 5 3 5 1 3 4 5 5 5 3 3 3 3 3 3 5 4 # #级别:1 2 3 4 5
clusterRows(mat, MbkmeansParam(centers=5, batch_size=10), full = TRUE)
# # # # $集群[1]1 1 5 5 5 5 5 5 5 5 5 2 5 3 1 1 1 5 5 5 5 5 5 1 5 1 1 5 5 5 5 1 2 1 5 # #[38]5 5 5 5 5 5 5 5 5 5 5 5 5 2 1 5 1 2 5 5 5 5 5 5 1 1 5 5 5 5 5 5 5 5 1 # #[75]5 5 5 5 1 5 1 5 1 2 1 1 5 5 5 5 5 5 5 5 4 5 1 5 # #级别:12 34 5 ## ## $objects ## $objects$mbkmeans ## $mbkmeans$centroids ## [,1] [,2] [,3] [,4] [,4] [,5] [,4] [,5] [,4] [,4] ## [1,] -15.010417 -0.7962079 4.968180 [,5] [,] 2.7679840 0.605855 -0.2194566 -1.4958129 ## [2,] 1.398788 15.2268393 -4.914318 8.7031508 0.624902 -2.6562225 -0.8620272 ## [3,] -17.543300 -0.3406707 6.138011 4.3145411 -1.079512 0.6588221 ## [4,] 3.505305 9.0542211 -5.7764435 -3.4572454 ## [5,] 4.953126 -5.2662492 -1.303848 -0.6517419-0.3327930 ## [,8] [,9] [,10] [,11] [,12] [,13] ## [1,] 0.6686381 0.7806568 -1.1359341 1.1528491 -1.407013 -1.5457278 ## [2,] 3.2219319 -3.0456175 -0.2216553 -1.8928053 5.403923 2.9907297 ## [3,] -8.2619290 -4.0679099 -3.2909212 5.7171778 8.625866 -4.8241775 ## [4,] 3.3455593 -2.0061982 -1.3108509 -9.4799142 1.971986 -9.3333830 ## [5,] 0.4513868 -1.7769361 -1.2359026 0.4449523 0.151892 0.9781383 ## [,14] [,15] [,16] [,17] [,18] [,19] ## [1,] 1.6981873 -3.2334236 -0.7828917 -0.11174807 0.7921814 -2.0950737 ## [2,] -1.0326219 0.3752647 2.2624371 -2.48013345 2.6617969 2.6872741 ## [3,] 0.2712364 1.0289170 -5.9773702 2.34843262 1.5557200 3.6983167 ## [4,] 0.8668148 -1.5455810 -1.8839526 4.15320464 2.9828209 -2.4133479 ## [5,] 2.0870510 1.4041611 -0.3987755 0.06157393 0.6216171 0.4357754 ## [,20] ## [1,] 0.12192702 ## [2,] 2.21400473 ## [3,] -2.67676140 ## [4,] -0.06365159 ## [5,] 0.77074762 ## ## $objects$mbkmeans$WCSS_per_cluster ## numeric(0) ## ## $objects$mbkmeans$best_initialization ## [1] 1 ## ## $objects$mbkmeans$iters_per_initialization ## [,1] ## [1,] 17 ## ## $objects$mbkmeans$Clusters ## [1] 5 5 5 5 5 5 5 1 1 5 5 2 5 1 1 1 5 5 3 5 5 1 5 5 1 5 1 1 5 1 5 5 5 1 2 1 5 ## [38] 5 5 5 5 5 5 5 5 5 1 5 5 5 5 2 1 5 2 5 5 1 5 5 5 5 1 1 5 5 5 5 5 5 1 5 5 1 ## [75] 5 5 1 5 5 1 5 1 5 1 2 5 5 5 1 1 5 1 5 5 5 5 4 5 1 5
虽然很多时候群集将在内存中的数据上执行(例如在PCA之后),但是clusterRows
函数还接受任何类似矩阵的对象(内存中或磁盘上的数据表示)mbkmeans
接受。
例如,我们可以使用mbkmeans
在logcounts
试验sce1000
对象(类似于上面),它是一个DelayedMatrix
对象中的DelayedArray包中。
请注意:我们将矩阵转置为clusterRows
函数期望行上的观察值和列上的变量。
logcounts (sce1000)
## <1000 x 100>稀疏矩阵类DelayedMatrix和类型“double”:##[,1][,2][,3]…[,99] [,100] ## ensg00000090382 0.000000 1.482992 0.000000。5.4330604 0.0000000 ## ensg00000204287 2.198815 0.000000 0.000000。5.3387971 0.0000000 ## ensg00000163220 1.762993 1.482992 0.000000。2.1176311 2.0642508 ## ensg00000143546 0.000000 1.135438 1.113099。0.3825221 0.0000000 ## ensg00000019582 3.402730 1.762861 1.733874。6.2009459 2.0642508 ## ... ... ...## ensg00000145779 0.0000000 0.6766523 0.0000000。0.9342195 0.0000000 ## ensg00000106948 0.0000000 1.1354382 0.0000000。0.9342195 1.3735556 ## ensg00000155660 0.0000000 0.6766523 0.0000000。 0.3825221 1.3735556 ## ENSG00000117748 0.0000000 0.0000000 0.0000000 . 0.0000000 0.0000000 ## ENSG00000135968 0.0000000 0.0000000 0.0000000 . 0.3825221 0.0000000
clusterRows (t (logcounts (sce1000)), MbkmeansParam(中心= 4))
# #[1] 2 2 2 1 2 2 1 3 3 1 2 2 2 3 3 3 1 2 3 1 2 3 2 2 3 1 2 3 3 3 1 2 2 3 2 3 2 # #[38] 2 2 2 2 2 2 2 2 1 3 1 2 2 2 2 3 1 2 4 2 3 2 1 2 2 3 3 1 2 2 2 2 2 3 2 2 3 # #[75] 2 1 3 2 1 3 2 3 2 3 2 2 2 2 3 3 2 3 2 2 2 2 2 2 3 2 # #级别:1 2 3 4
这篇小短文主要讲的是mbkmeans
包中。针对有兴趣了解更多使用的用户HDF5
文件和磁盘上的数据,我们推荐优秀的DelayedArray车间,由Peter Hickey主持Bioc2020.
阿瑟,大卫,谢尔盖·瓦西里维茨基,2007。《k - means++:谨慎播种的优势》在第18届离散算法ac - siam年会论文集1027 - 35。工业协会;应用数学。
希克斯,斯蒂芬妮·C,刘若希,倪宇伟,伊丽莎白·普多姆,达维德·里索。Mbkmeans:使用小批量K-Means快速聚类单细胞数据。bioRxiv.https://doi.org/10.1101/2020.05.27.119438.
大卫·斯卡利,2010年。“网络规模的K-Means集群。”在第19届国际万维网会议论文集1177 - 8。ACM。