我一直卡在同一个问题上。关于计算距离的方法,您可能想使用Gower转换。如果您没有连续的数据,您可以使用重叠函数,但我还没有在R中找到(这篇论文)。以下是我找到的解决方案:
为了在具有太多观测值(N
)的非常大的数据集上计算距离,可以应用此最新论文中提出的解决方案(此处)。他们提出了一种智能的方法:创建一个新数据集,其中每行是原始数据集中d
个属性值的可能组合。因此,这将生成一个新矩阵,其M < N
osbervations可进行计算。他们“创建了一个所有可能情况及其相应距离(从每个其他观测值到达)的网格,并使用该网格创建了我们的聚类,随后将我们的观测分配给这些聚类”
我尝试使用这个答案和library(plyr)
在R中进行复制。在下面的示例中,我只使用4个观测值,但是如果您生产的组合将减少内存需求,则应适用于N
观测值。
id <- c(1,2,3,4)
a <- c(1,1,0,1)
b <- c(0,1,0,0)
c <- c(3,2,1,3)
d <- c(1,0,1,1)
Mydata <- as.data.frame(cbind(id, a,b,c,d))
Mydata
id a b c d
1 1 0 3 1
2 1 1 2 0
3 0 0 1 1
4 1 0 3 1
require(plyr)
Mydata_grid <- count(Mydata[,-1])
Mydata_grid
a b c d freq
1 0 3 1 2
1 1 2 0 1
0 0 1 1 1
其中freq
是组合在原始的Mydata
中出现的频率。然后我只需将我更喜欢的距离度量应用于Mydata_grid
。在这种情况下,我的数据是分类的,因此我应用jaccard(我不知道它是否适用于示例数据。也许我应该使用一个overlap
匹配函数,但我还没有在R中找到)。
require(vegan)
dist_grid <- vegdist(Mydata_grid, method="jaccard")
d_matrix <- as.matrix(dist_grid)
d_matrix
1 2 3
1 0.0000000 0.5714286 0.6666667
2 0.5714286 0.0000000 0.5000000
3 0.6666667 0.5000000 0.0000000
这是我们的距离矩阵(distance_matrix)。现在直接对d_grid
进行聚类即可。
clusters_d <- hclust(dist_grid, method="ward.D2")
cluster <- cutree(clusters_d, k = 2) # k= number of clusters
cluster
1 2 1
这个向量将每个组合分配到每个聚类中。现在只需要回到原始样本,就完成了。要做到这一点,只需执行以下操作:
Mydata_cluster <- cbind(Mydata_grid, cluster, Mydata_grid$freq)
然后使用rep
将样本扩展到原始维度。
Mydata_cluster_full <- Mydata_cluster[rep(row.names(Mydata_cluster), Mydata_cluster$freq), 1:(dim(Mydata_cluster)[2]-1)]
Mydata_cluster_full
a b c d freq cluster
0 0 1 1 1 1
1 0 3 1 2 2
1 0 3 1 2 2
1 1 2 0 1 1
您也可以添加原始的
id
向量并删除
freq
列。
Mydata_cluster_full$id <- id
Mydata_cluster_full$freq <- NULL
a b c d freq cluster id
0 0 1 1 1 1 1
1 0 3 1 2 2 2
1 0 3 1 2 2 3
1 1 2 0 1 2 4
如果你运气不错的话,这个过程将会减少计算距离矩阵所需的内存量,使其达到可行的水平。