logo

时间序列聚类

wangzf / 2022-04-25


目录

时间序列聚类算法简介

时间序列的聚类在工业生产生活中非常常见,大到工业运维中面对海量 KPI 曲线的隐含关联关系的挖掘, 小到股票收益曲线中的增长模式归类,都要用到时序聚类的方法帮助发现数据样本中一些隐含的、深层的信息

根据对时间序列的距离度量方法,可以采用机器学习中很多聚类算法

时间序列聚类算法

K-Means DBA 聚类

时间序列的 K 均值聚类需要时间序列的平均策略。一种可能性是 DTW 重心平均(Barycenter Average DBA)

model = KMeans(
    k = 4, 
    max_it = 10, 
    max_dba_it = 10, 
    dists_options = {
        "window": 40
    }
)
cluster_idx, performed_it = model.fit(
    series, 
    use_c = True, 
    use_parallel = False
)

对于上面的 Trace 示例,聚类并不完美,因为不同系列的基线略有不同,无法通过归一化进行校正。 这会导致累积误差大于其中一种系列中的细微正弦波。一种可能的解决方案是对信号应用差分以关注序列中的变化。 此外,还应用低通滤波器来避免噪声累积

import dtaidistance
from dtaidistance.clustering.kmeans import KMeans

series = dtaidistance.preprocessing.differencing(
    series, 
    smooth = 0.1
)
model = KMeans(
    k = 4, 
    max_it = 10, 
    max_dba_it = 10, 
    dists_options = {
        "window": 40
    }
)
cluster_idx, performed_it = model.fit(
    series, 
    use_c = True, 
    use_parallel = False
)

DTW Barycenter Averaging:

from diaidistance import dtw_barycenter

new_center = dtw_barycenter.dba(series, center, use_c = True)
new_center = dtw_barycenter.dba_loop(
    series, 
    center, 
    max_it = 10, 
    thr = 0.0001, 
    use_c = True
)

K-Medoids 聚类

from dtaidistance import dtw, clustering

s = np.array([
    [0., 0, 1, 2, 1, 0, 1, 0, 0],
    [0., 1, 2, 0, 0, 0, 0, 0, 0],
    [1., 2, 0, 0, 0, 0, 0, 1, 1],
    [0., 0, 1, 2, 1, 0, 1, 0, 0],
    [0., 1, 2, 0, 0, 0, 0, 0, 0],
    [1., 2, 0, 0, 0, 0, 0, 1, 1],
    [1., 2, 0, 0, 0, 0, 0, 1, 1]
])

model = clustering.KMedoids(
    dtw.distance_matrix_fast, 
    {}, 
    k = 3
)
cluster_idx = model.fit(s)
model.plot("kmedoids.png")

层次聚类

层次聚类是一种很直观的方法,就是一层一层的对数据进行聚类操作,可以自低向上进行合并聚类、也可以自顶向下进行分裂聚类

所谓凝聚,其大体思想就是在一开始的时候,把点集集合中的每个元素都当做一类, 然后计算每两个类之前的相似度,也就是元素与元素之间的距离; 然后计算集合与集合之前的距离,把相似的集合放在一起,不相似的集合就不需要合并; 不停地重复以上操作,直到达到某个限制条件或者不能够继续合并集合为止

所谓分裂,正好与聚合方法相反。其大体思想就是在刚开始的时候把所有元素都放在一类里面, 然后计算两个元素之间的相似性,把不相似元素或者集合进行划分, 直到达到某个限制条件或者不能够继续分裂集合为止

在层次聚类里面,相似度的计算函数就是关键所在。在这种情况下,可以设置两个元素之间的距离公式, 距离越小表示两者之间越相似,距离越大则表示两者之间越不相似。 除此之外,还可以设置两个元素之间的相似度

分层凝聚聚类

Hierarchical Agglomerative clustering

from dtaidistance import dtw, clustering

# Custom Hierarchical clustering
model1 = clustering.Hierarchical(dtw.distance_matrix_fast, {})
cluster_idx = model1.fit(timeseries)

# Keep track of full tree by using the HierarchicalTree wrapper class
model2 = clustering.HierarchicalTree(model1)
cluster_idx = model2.fit(timeseries)

# pass keyword arguments identical to instantiate a Hierarchical object
model2 = clustering.HierarchicalTree(
    dists_fun = dtw.distance_matrix_fast, 
    dists_options = {}
)
cluster_idx = model2.fit(timeseries)

# SciPy linkage clustering
model3 = clustering.LinkageTree(
    dtw.distance_matrix_fast, 
    {}
)
cluster_idx = model3.fit(timeseries)

聚类结果可视化:

fig, ax = plt.subplots(nrows = 1, ncols = 2, figsize = (10, 10))
show_ts_label = lambda idx: "ts-" + str(idx)
model.plot(
    "hierarchy.png", 
    axes = ax, 
    show_ts_label = show_ts_label,
    show_tr_label = True, 
    ts_label_margin = -10,
    ts_left_margin = 10, 
    ts_sample_length = 1
)

主动半监督聚类

Active semi-supervised clustering

使用 DTAIDistance 执行主动半监督聚类的推荐方法是使用 COBRAS 进行时间序列聚类。 COBRAS 是一个使用成对约束进行半监督时间序列聚类的库,它本身支持 dtaidistance.dtwkshape

参考