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

时间:2014-06-13 02:42:57

标签: r macos bigdata cluster-analysis distance

我的意图是在r中集中零售数据以进行客户细分。

我需要完整的聚类数据集,但在评估模型时会分成训练/测试。该数据集对36个变量的133,153个观测值进行了数值,分类和缺失值(14.1 MB)。

如何使用混合和大型数据集在r中进行聚类?

我的机器:

  

sessionInfo()   R版本3.1.0(2014-04-10)   平台:x86_64-apple-darwin13.1.0(64位)

Mac OSX版本10.9.3 4GB RAM

这是一个线程,建议在使用聚类算法(如k-means)之前将daisy()包用于混合数据类型:  implementation of the Gower distance function

由于无法分配矢量的错误,我无法使用菊花。在传统的聚类方法(如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

另一个帖子建议将bigmemory包用于r:R memory management / cannot allocate vector of size n Mb中的内存管理。

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

如果我能提供更多信息,请告诉我。

1 个答案:

答案 0 :(得分:2)

我一直坚持同样的问题。对于计算距离的方式,您可能希望使用Gower转换。如果你没有连续数据,你可以使用重叠函数,我还没有在R上找到它(this paper)。这是我发现的计算问题:

要计算具有太多N个观测值的非常大的数据集上的距离,以便计算可行,可以应用本文最近的论文(this one)中使用的解决方案。他们提出了一种明智的方法:他们创建一个新的数据集,其中每个新行都是原始数据集中d个属性的值的可能组合。因此,这将给出具有M < N osbervations的新矩阵,其中距离矩阵在计算上是可行的。他们“创建一个包含所有可能案例的网格,其相应的距离(每个案例来自每个案例)并使用此网格创建我们的集群,我们随后将这些集群分配给我们的观察

我尝试在R中使用此answerlibrary(plyr)重现这一点。在下文中,我将仅使用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 columnd

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

如果您不是一般的话,这个过程会将计算距离矩阵所需的内存量减少到可行的水平。