是否可以基于曲线形状进行时间序列聚类?


47

我具有一系列网点的销售数据,并希望根据其随时间变化的曲线形状对其进行分类。数据大致如下所示(但显然不是随机的,并且有一些丢失的数据):

n.quarters <- 100
n.stores <- 20
if (exists("test.data")){
  rm(test.data)
}
for (i in 1:n.stores){
  interval <- runif(1, 1, 200)
  new.df <- data.frame(              
    var0 = interval + c(0, cumsum(runif(49, -5, 5))),
    date = seq.Date(as.Date("1990-03-30"), by="3 month", length.out=n.quarters),
    store = rep(paste("Store", i, sep=""), n.quarters))
  if (exists("test.data")){
    test.data <- rbind(test.data, new.df)    
  } else {
    test.data <- new.df
  }
}
test.data$store <- factor(test.data$store)

我想知道如何根据R中的曲线形状进行聚类。我考虑过以下方法:

  1. 通过在整个时间序列中将每个商店的var0线性变换为0.0到1.0之间的值来创建新列。
  2. 使用R中的kml对这些变换后的曲线进行聚类。

我有两个问题:

  1. 这是一种合理的探索方法吗?
  2. 如何将数据转换为kml可以理解的纵向数据格式?任何R代码片段将不胜感激!

2
您可能会从一个较早的关于聚类单个纵向数据轨迹stats.stackexchange.com/questions/2777/…的
Jeromy Anglim 2010年

1
@Jeromy Anglin感谢您的链接。你有运气kml吗?
fmark 2010年

我快速浏览了一下,但是目前,我正在使用基于各个时间序列的选定特征(例如,均值,初始,最终,可变性,突变的存在等)的自定义聚类分析。
Jeromy Anglim


@Rob这个问题似乎没有假定不规则的时间间隔,但实际上它们彼此接近(我在撰写本文时没有想起另一个问题)。
chl

Answers:


26

@Jeromy提供的链接中讨论了分析纵向数据的几个方向,所以我建议您仔细阅读它们,尤其是有关功能数据分析的那些方向。尝试对“纵向数据的功能性聚类”或PACE Matlab工具箱进行谷歌搜索,该工具箱专门关注基于模型的不规则采样轨迹的聚类(Peng和Müller,稀疏观察到的随机过程的基于距离的聚类,以及在线拍卖的应用应用统计年鉴 2008:2:1056)。我可以想象对于财务时间序列可能会有一个很好的统计框架,但是我对此一无所知。

kml软件包基本上依赖于k均值,默认情况下以个体观察到的测量之间的欧几里得距离为基础。所谓的轨迹只是单个的观测值序列,和n i y i = y i 1y i 2y i td y iy j= tniyi=(yi1,yi2,,yit)d(yi,yj)=t1k=1t(yikyjk)2。通过对与最近的类似邻居的插补方案(用于计算Calinski准则)相关联的先前距离度量(Gower调整)进行轻微修改,可以处理丢失的数据。由于我不代表自己,您的真实数据看起来像什么,所以我不能说它是否有效。至少,它可以处理纵向增长曲线(“多项式”形状),但是我怀疑它是否可以通过翻译来检测非常特定的模式(例如,在特定时间点的局部最小值/最大值,在不同簇之间的时间点有所不同)例)。如果您对可能未对齐的曲线聚类感兴趣,则必须确定其他解决方案。Sangalli等人的功能聚类和比对以及其中的参考文献可以提供一个很好的起点。

下面,我向您展示一些可能有助于进行实验的代码(如果您想重现结果,我的种子通常设置为101)。基本上,要使用kmlclusterizLongData对象,只需构造一个对象(id第一列为数字,下一列为度量)。t

library(lattice)
xyplot(var0 ~ date, data=test.data, groups=store, type=c("l","g"))

tw <- reshape(test.data, timevar="date", idvar="store", direction="wide")
parallel(tw[,-1], horizontal.axis=F, 
         scales=list(x=list(rot=45, 
                            at=seq(1,ncol(tw)-1,by=2), 
                            labels=substr(names(tw[,-1])[seq(1,ncol(tw)-1,by=2)],6,100), 
                            cex=.5)))

library(kml)
names(tw) <- c("id", paste("t", 1:(ncol(tw)-1)))
tw.cld <- as.cld(tw)
cld.res <- kml(tw.cld,nbRedrawing=5)
plot(tw.cld)

接下来的两个数字是原始模拟数据和五群集解决方案(根据Calpcski准则,也用于fpc软件包)。我没有显示缩放版本

替代文字

替代文字


1
感谢您非常详细的回答。我已经在kml运行我的数据,但是正如您所建议的,它主要基于幅度而不是曲线形状进行聚类,因此,我正在尝试一些预处理步骤,以查看是否可以改善问题。Sangalli等人的工作。对于我想做的事情看起来非常有希望-但是我找不到他们的方法的实现。但是,我可能没有时间为此项目创建自己的工作实现。您是否知道任何FOSS实施?
fmark

@fmark据我所知,没有OSS的实现(尽管这项工作是最近的);他们使用R中都可用的k-means和k-medoids。在我看来,最关键的部分是生成模板曲线并实现翘曲功能。为此,您可以通过观察形态分析/过程分析或查找Matlab PACE工具箱的代码来查找其他信息(但这应该包含EM或类似内容)。我最好的建议是:要求作者免费实施其算法。
chl

2
如果得到肯定的话,我会报告:)他们的曲线聚类的纸质k均值对齐具有更多的实现细节,这些细节对于想要自己做这个的人也可能有用。
fmark

1
为什么不删除均值(也许除以标准偏差),然后这样做呢?那么结果将更多地与形状有关,而与幅度
无关

9

stats.se的常客在Wang,Xiazhe,Kate Smith和Rob Hyndman中发布了另一种方法。

“基于时间序列数据的基于特征的聚类”。数据挖掘和知识发现13,否。3(2006):335–364

他们写:

根据时间序列的结构特点,提出了一种时间序列的聚类方法。与其他替代方法不同,此方法不使用距离度量对点值进行聚类,而是基于从时间序列中提取的全局特征进行聚类。从每个单独的序列中获取特征量度,并将其用于任意聚类算法,包括无监督神经网络算法,自组织图或分层聚类算法。通过应用能够最好地捕获以下基本特征的统计操作来获得描述时间序列的全局度量:趋势,季节性,周期性,序列相关性,偏度,峰度,混沌,非线性和自相似性。由于该方法使用提取的全局度量进行聚类,它减少了时间序列的维数,并且对丢失或嘈杂的数据不那么敏感。我们进一步提供了一种搜索机制,可以从功能集中找到最佳选择,并将其用作聚类输入。

R代码可在Rob的博客上获得


6

您可以查看Eamonn Keogh(加州大学河滨分校)在时间序列聚类方面的工作。他的网站上有很多资源。我认为他提供了Matlab代码示例,因此您必须将其转换为R。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.