【问题标题】:How can i partition market basket items into clusters?如何将市场篮子项目划分为集群?
【发布时间】:2018-09-06 21:14:13
【问题描述】:

我有一个数据集如下:(我举了一个简单的例子,但真实的数据集要大得多)

     V1 V2 V3 V4
1    1  0  0  1
2    0  1  1  0 
3    0  0  1  0 
4    1  1  1  1
5    0  1  1  0
6    1  0  0  1 
7    0  0  0  1
8    0  1  1  1
9    1  0  1  0 
10   0  1  1  0 
...

其中 V1、V2、V3...Vn 是项目,1、2、3、4...1000 是交易。我想将这些项目划分为 k 个集群,以便在每个集群中,我拥有在同一事务中最常一起出现的项目。 为了确定每对项目一起出现的次数,我尝试了交叉表,我得到了以下结果:

   V1 V2 V3 V4
V1  4  1  2  3
V2  1  5  5  2
V3  2  5  7  2
V4  3  2  2  5

对于这个小例子,如果我想创建 2 个集群 (k=2),使得一个集群必须包含 2 个项目(以保持集群之间的平衡),我将得到:

Cluster1={V1,V4}

Cluster2={V2,V3}

因为:

1) V1 出现频率更高,V4 (V1,V4)=3 > (V1,V3) > (V1,V2) 和 V4 相同。

2) V2 (V2,V3)=5 > (V2,V4) > (V2, V1) 时 V2 出现频率更高,V3 也是如此。

如何使用 R 和更大的数据集进行此分区?

【问题讨论】:

  • 请将所需结果添加到您的问题中。
  • 好吧,我刚刚完成了。谢谢!

标签: r cluster-analysis partitioning market-basket-analysis


【解决方案1】:
library(data.table)

数据:

df<-
fread("
    V1 V2 V3
1    1  0  0
2    0  0  1
3    0  0  1
4    1  1  1
5    0  0  1
6    1  0  0
7    0  0  0
8    0  1  1
9    1  0  1
10   0  1  1
")[,-1]

代码:

setDT(df)
sapply(names(df),function(x){
    df[get(x)==1,lapply(.SD,sum,na.rm=T),.SDcols=names(df)]
    })

结果:

   V2 V3 V4
V2 4  1  2 
V3 1  3  3 
V4 2  3  7 

【讨论】:

  • 谢谢,但我认为您误解了我的问题。实际上,我已经建立了该表,并且基于它我想对项目进行聚类。例如,如果项目 V1 和 V2 一起出现在 5 个事务中,而项目 V1 和 V3 一起出现在 1 个事务中,则 V2 和 V3 出现在 2 个事务中,我会将 V1 和 V2 放在同一个集群中。所以我已经知道了它们一起出现的次数,但我不知道如何根据这些将项目划分为集群。
【解决方案2】:
df <- read.table(text="
ID V1 V2 V3 
1    1  0  0
2    0  0  1
3    0  0  1
4    1  1  1
5    0  0  1
6    1  0  0
7    0  0  0
8    0  1  1
9    1  0  1
10   0  1  1
", header = TRUE) 

k = 3 # number of clusters

library(dplyr)
df %>% 
  # group and count on all except the first id column
  group_by_at(2:ncol(df)) %>%
  # get the counts, and collect all the transaction ids
  summarize(n = n(), tran_ids = paste(ID, collapse = ',')) %>%
  ungroup() %>%
  # grab the top k summarizations
  top_n(k, n)

# V1    V2    V3     n tran_ids
# <int> <int> <int> <int> <chr>   
# 1     0     0     1     3 2,3,5   
# 2     0     1     1     2 8,10    
# 3     1     0     0     2 1,6  

【讨论】:

  • 谢谢,但这不是重点。如果我有例如 k=2 并且每个集群应该包含最多 2 个项目,我会将 V2 和 V3 放在一起,因为它们一起出现最多(=3)。所以我会得到集群 1={V1} 和集群 2 ={V2, V3}
【解决方案3】:

我想你是在问关于集群的问题。它与您在上面所做的不太一样,但您可以使用hclust 来寻找具有合适距离度量的变量之间的相似性。

例如

plot(hclust(dist(t(df),method="binary")))

产生以下...

您应该查看 ?dist 以了解此距离度量在您的上下文中是否有意义,并查看 ?hclust 以了解您在获得树状图后可以做的其他事情(例如识别集群)。

或者您可以使用交叉表作为距离矩阵(也许取值的倒数,然后是 as.dist)。

【讨论】:

  • 谢谢,但在我的情况下,重要的是每两个产品一起出现的次数,并且集群应该是独立的。
  • @BS.Mira 我已经更新了树状图,它给出了你所期望的相同的集群。如果您有很多列,这种方法可能值得考虑。
  • 非常感谢,但是如何使用这种方法修复所需的集群数量和每个集群的项目数量?有可能吗?
  • 是的,你可以在任何你想要的水平上切割树状图(想象一条水平线),以获得你认为合适的集群数量。请参阅hclustprune 的帮助以获取有关如何执行此操作的指示。固定每个集群的项目数可能更难。
【解决方案4】:

您可以转置表格并使用标准聚类方法。因此,您将对项目进行聚类。特征是交易。

几何方法可以像 kmeans 一样使用。或者,您可以使用提供信息标准(如 BIC)的混合模型来选择集群的数量。这是一个 R 脚本

require(VarSelLCM)

my.data <- as.data.frame(t(df))
# To consider Gaussian mixture
# Alternatively Poisson mixture can be considered by converting each column into integer.
for (j in 1:ncol(my.data)) my.data[,j] <- as.numeric(my.data[,j])

## Clustering by considering all the variables as discriminative
# Number of clusters is between 1 and 6
res.all <- VarSelCluster(my.data, 1:6, vbleSelec = FALSE)

# partition
res.all@partitions@zMAP

# shiny application
VarSelShiny(res.all)


## Clustering with variable selection
# Number of clusters is between 1 and 6
res.selec <- VarSelCluster(my.data, 1:6, vbleSelec = TRUE)

# partition
res.selec@partitions@zMAP

# shiny application
VarSelShiny(res.selec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 2020-10-18
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多