如何对时间序列数据执行 K-means 聚类?

Posted

技术标签:

【中文标题】如何对时间序列数据执行 K-means 聚类?【英文标题】:How can I perform K-means clustering on time series data? 【发布时间】:2011-03-31 00:58:35 【问题描述】:

如何对时间序列数据进行 K 均值聚类? 我理解当输入数据是一组点时这是如何工作的,但我不知道如何用 1XM 对时间序列进行聚类,其中 M 是数据长度。特别是,我不确定如何更新时间序列数据的集群平均值。

我有一组带标签的时间序列,我想使用 K-means 算法来检查我是否会得到类似的标签。我的 X 矩阵将是 N X M,其中 N 是时间序列的数量,M 是上面提到的数据长度。

有人知道怎么做吗?例如,我如何修改 this k-means MATLAB code 使其适用于时间序列数据?此外,我希望能够使用欧几里得距离以外的不同距离度量。

为了更好地说明我的疑惑,下面是我为时间序列数据修改的代码:


% Check if second input is centroids
if ~isscalar(k) 
    c=k;
    k=size(c,1);
else
    c=X(ceil(rand(k,1)*n),:); % assign centroid randomly at start
end

% allocating variables
g0=ones(n,1); 
gIdx=zeros(n,1);
D=zeros(n,k);

% Main loop converge if previous partition is the same as current
while any(g0~=gIdx)
%     disp(sum(g0~=gIdx))
    g0=gIdx;
    % Loop for each centroid
    for t=1:k
        %  d=zeros(n,1);
        % Loop for each dimension
        for s=1:n
            D(s,t) = sqrt(sum((X(s,:)-c(t,:)).^2)); 
        end
    end
    % Partition data to closest centroids
    [z,gIdx]=min(D,[],2);
    % Update centroids using means of partitions
    for t=1:k

        % Is this how we calculate new mean of the time series?
        c(t,:)=mean(X(gIdx==t,:));

    end
end

【问题讨论】:

【参考方案1】:

我也不认为 k-means 是正确的方法。正如@Anony-Mousse 建议的那样,您可以使用DTW。事实上,我的一个项目也遇到了同样的问题,我用 Python 编写了自己的类。逻辑是;

    创建所有集群组合。 k 代表簇数,n 代表系列数。返回的项目数应为n! / k! / (n-k)!。这些可能类似于潜在的中心。 对于每个系列,计算每个集群组中每个中心的距离并将其分配给最小值。 对于每个集群组,计算各个集群内的总距离。 选择最小值。

如果您有兴趣,Python 实现是here。

【讨论】:

【参考方案2】:

我最近遇到了kml R 包,它声称对纵向数据实施 k-means 聚类。我自己没有试过。

另外,S. Aghabozorgi、A. S. Shirkhorshidi 和 T. Ying Wah 的 Time-series clustering - A decade review 论文可能对您寻找替代方案有用。另一篇不错的论文虽然有些过时了,但它是由 T. Warren Liao 撰写的Clustering of time series data-a survey。

【讨论】:

【参考方案3】:

如果您确实想使用聚类,那么根据您的应用程序,您可以为每个时间序列生成一个低维特征向量。例如,使用时间序列均值、标准偏差、傅里叶变换的主频率等。这适用于 k 均值,但它是否会给您带来有用的结果取决于您的具体应用和您的时间内容系列。

【讨论】:

【参考方案4】:

现在回答可能为时已晚,但是:

k-means 可用于cluster longitudinal data Anony-Mousse 是对的,DWT distance is the way to go for time series

上述方法使用 R。您可以通过查找找到更多方法,例如“Iterative Incremental Clustering of Time Series”。

【讨论】:

【参考方案5】:

时间序列通常是高维的。您需要专门的距离函数来比较它们的相似性。另外,可能存在异常值。

k-means 是为具有(有意义的)欧几里得距离的低维空间而设计的。它对异常值不是很稳健,因为它会对它们施加平方权重。

对我来说,在时间序列数据上使用 k-means 听起来不是一个好主意。尝试研究更现代、更强大的聚类算法。许多将允许您使用任意距离函数,包括时间序列距离,例如 DTW。

【讨论】:

能否请您推荐一些强大的聚类算法。什么是DTW?谢谢。 拿一本关于时间序列的书,它会教你DTW。或谷歌“时间序列DTW”。这是最先进的。至于聚类,请在 Wikipedia 上查找 DBSCAN 和 OPTICS。它们可以与 DTW 一起使用,k-means 不能。

以上是关于如何对时间序列数据执行 K-means 聚类?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 KNN /K-means 在数据框中对时间序列进行聚类

如何在 r 中对充满字符串变量的数据集进行 K-means 聚类

我可以改变啥来让 k-means 以 Python 中预期的方式对我的数据进行聚类?

如何使用 sklearn k-means 聚类根据彼此的相关性对 * 特征 * 进行聚类

K-Means 聚类 超参数调优

如何在 Python 中使用 K-Means 聚类找到最佳的聚类数量