混合和大型数据集的R距离矩阵和聚类?

4

我的目的是在 R 中对零售数据进行聚类以进行客户细分。

我需要完整的数据集进行聚类,但在评估模型时将其拆分为训练/测试。该数据集具有133,153个观测值和36个变量,其中包含数值,分类和缺失值(14.1 MB)。

如何在R中处理混合和大型数据集进行聚类?

我的计算机:

sessionInfo() R version 3.1.0 (2014-04-10) Platform: x86_64-apple-darwin13.1.0 (64-bit)

Mac OSX 版本 10.9.3 4GB RAM

这里有一篇帖子建议在使用聚类算法(如 k-means)之前使用 daisy() 包处理混合数据类型:

implementation of the Gower distance function.

由于无法分配向量而不能使用daisy。在传统聚类方法(如 k-means)之前的面向矩阵的方法存在可扩展性问题。

错误:

#Load Data
Store1 <- read.csv("/Users/scdavis6/Documents/Work/TowerData/TowerData/Client1.csv", head=FALSE)
#Convert csv to data.frame
df <-as.data.frame(Store1)
#Create dissimilarity matrix
daisy1 <- daisy(df)
Error: cannot allocate vector of size 66.0 Gb

有一个帖子建议在R中使用bigmemory软件包进行内存管理:R memory management / cannot allocate vector of size n Mb

我无法使用read.big.matrix()函数将数据存储在矩阵中,因为bigmemory软件包不允许混合数据类型。

如果需要更多信息,请告诉我。


@joran 我描述了问题并链接了来自stackoverflow.com的相关文章。我正在继续讨论混合变量聚类的问题,因为r由于可扩展性问题而无法胜任。在另一个链接中,评论者建议使用r中的bigmemory包,但它无法处理混合数据类型。我没有看到其他人在stackoverflow.com上对这个问题进行彻底的研究。我尝试了一种基于矩阵的方法,配合一个内存共享包,但它并没有解决问题。到目前为止,在该网站上讨论就止步于此!请让帖子活跃起来。 - Scott Davis
1个回答

4

我一直卡在同一个问题上。关于计算距离的方法,您可能想使用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

如果你运气不错的话,这个过程将会减少计算距离矩阵所需的内存量,使其达到可行的水平。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接