按周对多个特征进行聚类
Posted
技术标签:
【中文标题】按周对多个特征进行聚类【英文标题】:Clustering with multiple features by week 【发布时间】:2016-12-30 01:42:38 【问题描述】:我有一组按商店按周列出的数据,其中包含 2 个特征 - 销售额和 pp。我想根据这些特征对它们进行聚类,理想情况下对全年交易模式最相似的数据进行分组。
是否可以使用我拥有的数据来做到这一点。我的理解是特征是列,行是根据集群分配标签的内容,但我有几周的时间要考虑,所以我不知道这些应该在行还是列中?
library(data.table)
dt <- data.table(weeks = rep(seq(1:5),5),
store = c(rep("a", 5), rep("b", 5), rep("c", 5),
rep("e", 5), rep("d", 5)),
sales = rep(rnorm(5), 5),
pp = rep(rnorm(5), 5))
dt <- dcast.data.table(dt, store ~ weeks, value.var = c("sales", "pp"))
谢谢
【问题讨论】:
您是否认为商店的集群相对于 (sales,pp) 每周都在变化。 是的,数据中有超过 1,000 家商店,其中一些将位于高旅游地点,因此当天气真的很热等时,他们商店的数据会出现峰值。所以我期待说在这很明显的商店中,可能还有一个基于 pp 指标的子集。通常我只是采用平均每周销售额/pp 并使用它,因此删除了各个周,但我希望也能够捕捉到全年每周的变化。 【参考方案1】:由于您拥有超过 1000 家商店,以下演示可能无法直接应用,但希望为您指明正确的方向。
您可以每周或任何其他周的变体分析商店集群(N=4,8,...)
在这里,我们以每周的频率查看商店集群:
测试数据
library(dplyr) #data manipulation
library(ggdendro) #extracting clusters
library(ggplot2) #plotting
library(gridExtra) #for arranging ggplot graphs in grids
set.seed(42)
DF <- data.frame(weeks = rep(seq(1:5),5),
store = c(rep("A", 5), rep("B", 5), rep("C", 5),
rep("E", 5), rep("D", 5)),
sales = rnorm(25),
pp = rnorm(25))
weekInput = unique(DF$weeks)
选择周频率:
在简单的情况下,我包括了离散的周,即 1、2、3、4 和 5。
假设您希望选择 N = 4 作为周频率,即周 1 到 4、5 到 8 等,您可以使用以下方法创建一年中的 weekInput 分区并根据您的要求进行修改。
#weekFreq = 4
#StartWeek = 1
#EndWeek = 52
#startPoints=seq(StartWeek,EndWeek,weekFreq)
#endPoints= c(tail(startPoints,-1)-1,EndWeek)
#
#freqDF = data.frame(cbind(startPoints,endPoints))
#weekInput = lapply(1:nrow(freqDF),function(x) z= freqDF[x,]; z=as.vector(as.matrix(z)) )
#head(weekInput)
#[[1]]
#[1] 1 4
#
#[[2]]
#[1] 5 8
#
#[[3]]
#[1] 9 12
#
#[[4]]
#[1] 13 16
#
#[[5]]
#[1] 17 20
#
#[[6]]
#[1] 21 24
绘制聚类
绘制各种树状图的好资源是here 和here
我们每周计算数值数据上的距离矩阵并创建层次聚类并使用 ggdendro 包进行绘图并输出绘图对象列表
plotList = lapply(weekInput,function(x)
subsetWeek=DF %>%
group_by(weeks) %>%
filter(weeks==x) %>% #you could change this to `weeks %in% c(x[1],x[2])`
as.data.frame() %>% # x[1] and x[2] are start and end points of weekInput
select(-weeks) %>%
as.data.frame()
#For numeric features of data, compute the distance matrix and form hierarchical cluster
numericDF= subsetWeek[,sapply(subsetWeek,is.numeric)]
clustDF = hclust(dist(numericDF))
#You can choose to limit the clusters to N = n, as per your discretion
#clustDF = cutree(clustDF, 4)
clustDF$labels = subsetWeek$store
#Use functions from ggdendro package for extracting clusters for ease in plotting
clustDendro = as.dendrogram(clustDF)
dendroData = dendro_data(clustDendro,type="rectangle")
Labels = label(dendroData)
Labels$group <- c(rep("Area1", 2), rep("Area2", 2), rep("Area3", 1))
gPlot = ggplot(segment(dendroData)) +
geom_segment(aes(x=x,y=y,xend=xend,yend=yend)) +
geom_label(data=Labels,aes(label=label,x=x,y=0,label.size=5,colour=Labels$group,fontface="bold")) +
ggtitle(paste0("Store Clusters for Week:",x)) +
labs(color="Area Names\n")
gPlot = gPlot + theme(legend.title = element_text(face = "bold"))
return(gPlot)
)
安排情节
上面的绘图对象列表可以根据需要排列。 有关更多详细信息的有用链接是here
grid::grid.newpage()
grid::grid.draw(do.call(rbind,lapply(plotList,function(x) ggplotGrob(x))))
单周:
所有周
由于单列排列,可读性略有影响
【讨论】:
以上是关于按周对多个特征进行聚类的主要内容,如果未能解决你的问题,请参考以下文章