R 基于邻域策略的空间聚类三维阵列
我需要使用邻域策略在3d阵列中执行空间聚类。更清楚地说:我有一个3d图像,它表示为一个稀疏的3d数组。某些实例为1,而大多数实例为0。我希望将彼此相邻的等于1的实例聚集在一起(即,如果我们将每个实例想象为一个立方体,我希望将共享一个面、一条边或一个角且等于1的实例聚集在一起) 我需要在R中这样做,因为这一步是机器学习较长管道的一部分,我正在尝试在单个环境中实现整个管道,以尽量减少头痛。 我找到了一个与当前问题稍有关联的答案。然而,在这种情况下,集群的数量是事先知道的,而在我的情况下,集群的数量可以是从1到实例数量等于1的任何值(前提是没有实例与另一个实例相邻) 我可以为此目的编写一个函数,但这将非常耗时,而且可能效率不高,因为我认为除了寻找非零实例之外,没有其他策略可以使用,检查每个邻居实例,如果其中任何一个是非零的,那么检查它的邻居等等 由于集群步骤包含在嵌套的交叉验证循环中,您可以自己看到,我需要更高效的东西(或者可能只是用C编写的同样的东西,以便更快) 你们中有人知道有什么功能或软件包可以帮助我吗 更新 为了回答评论,我的“稀疏”数组是稀疏的,因为大多数元素都是零,而不是以稀疏格式保存。 这里是一个玩具示例(它确实是我原始数组中非零元素的裁剪,具有dim(91109,91)) 更新2 我在一台Windowsx64机器上工作,RStudio 1.0.153和R版本3.4.2(短暂的夏季) 更新3 我已经尝试了@gdkrmr给出的答案,虽然它对给定的示例很有效,但它无法推广到更大、更复杂的图像。具体来说,它过度分离了我的图像中的簇,这意味着确实相互接触的体素有时会被分割成不同的簇。 您可以自己将其可视化下载并运行以下代码 读取三维图像R 基于邻域策略的空间聚类三维阵列,r,multidimensional-array,cluster-analysis,spatial,R,Multidimensional Array,Cluster Analysis,Spatial,我需要使用邻域策略在3d阵列中执行空间聚类。更清楚地说:我有一个3d图像,它表示为一个稀疏的3d数组。某些实例为1,而大多数实例为0。我希望将彼此相邻的等于1的实例聚集在一起(即,如果我们将每个实例想象为一个立方体,我希望将共享一个面、一条边或一个角且等于1的实例聚集在一起) 我需要在R中这样做,因为这一步是机器学习较长管道的一部分,我正在尝试在单个环境中实现整个管道,以尽量减少头痛。 我找到了一个与当前问题稍有关联的答案。然而,在这种情况下,集群的数量是事先知道的,而在我的情况下,集群的数量可
library(oro.nifti)
roi <- readNIfTI("image_to_cluster.nii")
roi_img <- cal_img(roi)
库(oro.nifti)
投资回报率%
{. < 2}
指定簇标签
cluster <- 1:nrow(sparse_format)
for (i in 1:nrow(sparse_format)) {
cl_idx <- cluster[i]
cluster[neighborhoods[, i]] <- cl_idx
}
sparse_format <- sparse_format %>%
as_data_frame(.) %>%
mutate(cluster_id = cluster)
cluster
您可以使用spatstat
包来执行此操作。你需要新的
已从github创建分支connected.pp3
,如果需要,可以安装该分支
加载devtools
或remotes
包(这里我使用
遥控器
):
库(远程)
安装github(“spatstat/spatstat”)
图书馆(spatstat)
网格和边界框
网格36 0 2 1 36
#> 102 1 0 4 102
#> 78 2 0 3 78
#> 63 2 2 2 63
#> 88 2 2 3 88
#> 16 0 3 0 16
#> 77 1 0 3 77
#> 82 1 1 3 82
#> 53 2 0 2 53
#> 116 0 3 4 116
#> 106 0 1 4 106
#> 29 3 0 1 29
#> 52 1 0 2 52
#> 104 3 0 4 104
#> 107 1 1 4 107
#> 13 2 2 0 13
#> 51 0 0 2 51
#> 60 4 1 2 60
转换为三维点模式并查找连接的零部件(返回为
所谓的点标记)。正如@gdkrmr所指出的,任何一点
距离小于2表示邻居(这里我们使用1.8,但不使用任何值)
在sqrt(3)和2之间(应起作用)
x1429
#> 19 2 51
#> 15 2 52
#> 11 2 53
#> 20 2 60
#> 6 2 63
#> 9 2 77
#> 5 2 78
#> 10 2 82
#> 7 2 88
#> 4 2 102
#> 16 2 104
#> 13 2 106
#> 17 2 107
#> 12 2 116
#> 2 2 117
#> 8 3 16
#> 3 3 36
#> 18 4 13
这是一个纯R解决方案,它利用了相邻体素的最大距离sqrt(d)<2
如果d%
其中(,arr.ind=TRUE)
社区%
距离%>%
as.matrix%>%
{. < 2}
n 1)如果性能对您很重要,您可以使用Rcpp
软件包。2) 使用索引上的dist
功能应在3d阵列中工作,距离<2
的每两个点应为相邻点,但这将停止对d>3
工作。3) 我还猜想,如果对3d数组的索引进行排序,您的算法可以快几个数量级。谢谢您的评论。你对我来说有点太快了:1-我看了Rcpp软件包,我不确定如何将其用于我的目标。2 -感谢提示3 -你是什么意思3点?1)你将使用RCPP实现自己的算法在C/C++ + RCPP只是使接口C++和R更容易。3) 如果您实现自己的算法并知道索引已排序,则无需将所有点与所有点进行比较,即在1D情况下:如果索引或您的索引为:c(1,3,4,5)
,在只检查前两个元素后,前两个元素不是邻居。一个问题:数组是以稀疏格式保存的,还是一个密集的数组,在很大程度上是由零组成的稀疏数组?这就是为什么您应该始终提供一个可复制的示例。我已经更新了问题以回答@gdkrmr问题,并添加了一个可复制的示例谢谢您的回答。安装spatstat
的开发人员版本时遇到问题。我已经安装了remotes
软件包,但是当我运行comandinstall\u github(“spatstat/spatstat”,ref=“connected.pp3”时
array_img <- roi@.Data
sparse_format <- (array_img > 0) %>%
which(., arr.ind = TRUE)
neighborhoods <- sparse_format %>%
dist %>%
as.matrix %>%
{. < 2}
cluster <- 1:nrow(sparse_format)
for (i in 1:nrow(sparse_format)) {
cl_idx <- cluster[i]
cluster[neighborhoods[, i]] <- cl_idx
}
sparse_format <- sparse_format %>%
as_data_frame(.) %>%
mutate(cluster_id = cluster)
new_img <- roi
new_img@.Data <- array(0,c(74,92,78))
for (cl in cluster) {
new_img@.Data[sparse_format %>% filter(., cluster_id == cl) %>% select(dim1,dim2,dim3) %>% as.matrix] <- cl
}
writeNIfTI(new_img, "test", verbose=TRUE)
library(rgl)
library(magrittr)
sparse_format <- (sparse_array > 0) %>%
which(., arr.ind = TRUE)
neighborhoods <- sparse_format %>%
dist %>%
as.matrix %>%
{. < 2}
n <- nrow(sparse_format)
perm <- 1:n
for (i in 1:n) {
perm[i:n] <- perm[i:n][
order(neighborhoods[perm[i], perm][i:n],
decreasing = TRUE)
]
}
neighborhoods <- neighborhoods[perm, perm]
sparse_format <- sparse_format[perm, ]
cluster <- 1:n
for (i in 1:n) {
cl_idx <- cluster[i]
cluster[neighborhoods[, i]] <- cl_idx
}
plot3d(sparse_format, col = cluster)