我的意图是将零售数据聚类以在r中进行客户细分。
我需要完整的数据集进行聚类,但是在评估模型时将分为训练/测试。该数据集包含133,153个观测值,包含36个具有数字,分类和缺失值的变量(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
另一个线程建议在r:R memory management / cannot allocate vector of size n Mb中使用bigmemory软件包进行内存管理。
我无法使用read.big.matrix()函数将数据存储在矩阵中,因为bigmemory程序包不允许使用混合数据类型。
如果可以提供更多信息,请告诉我。
最佳答案
我一直被困在同一问题上。对于计算距离的方式,您可能需要使用Gower变换。如果没有连续数据,则可以使用重叠函数,而我在R上还找不到(this paper)。这是我发现的计算问题:
为了在具有太多N
观测值的非常大的数据集上计算距离,以致于计算上不可行,有可能应用本文中使用的解决方案(this one)。他们提出了一种明智的处理方法:创建一个新数据集,其中每个新行都是原始数据集中d
属性上值的可能组合。因此,这将给出具有M < N
振荡的新矩阵,对于该矩阵,距离矩阵在计算上是可行的。他们“创建一个所有可能情况的网格,以及它们各自的距离(每个到另一个的距离),并使用该网格来创建我们的聚类,随后我们将其加入我们的观察中”
我试图通过在library(plyr)
中将此answer与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
matching函数,但我尚未在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
如果您不是很幸运,那么此过程会将计算距离矩阵所需的内存量减少到可行的水平。