如何在tslearn soft-dtw/dtw聚类中计算各簇centroid
解决方法
tslearn的TimeSeriesKMeans实现里,文档提到的**barycenter(时间序列重心)**就是非欧氏度量(DTW/soft-DTW)空间下的聚类簇centroid(质心),不需要额外找独立的centroid计算接口,模型训练完成后可以直接读取内置属性获取。
具体使用方式
- 训练完成的
TimeSeriesKMeans实例自带cluster_centers_属性,直接访问即可得到所有簇的质心,返回数组形状为(n_clusters, 序列长度, 特征维度),数组索引和簇标签一一对应:km.cluster_centers_[i]就是标签为i的簇对应的质心时间序列。 - 如果需要手动对某一组时间序列计算对应度量下的barycenter,可以直接导入tslearn内置的barycenter计算函数:使用soft-DTW度量时调用
softdtw_barycenter,使用普通DTW度量时调用dtw_barycenter_average即可,注意计算时的参数要和聚类时传入的参数保持一致,结果会和模型内置的质心完全匹配。
适配后的代码示例
在你原有代码基础上增加质心读取逻辑即可,参考如下:
from tslearn.clustering import TimeSeriesKMeans from tslearn.metrics import silhouette_score # 若需要手动计算barycenter可按需导入 # from tslearn.barycenters import softdtw_barycenter num_of_clusters_list = [] silhouetteScore_list = [] for j in [2, 3]: # 分别尝试2、3个簇的聚类效果 km = TimeSeriesKMeans(n_clusters=j, metric="softdtw", random_state=42) labels = km.fit_predict(ts_intention_list) silhouetteScore = silhouette_score(ts_intention_list, labels, metric="softdtw") print(f"\nLabels for {j} clusters: {labels}") # 读取所有聚类簇的质心 centroids = km.cluster_centers_ for cid in range(j): print(f"簇{cid}的质心序列维度:{centroids[cid].shape}") # 手动计算barycenter的验证逻辑(可选) # gamma_val = km.gamma # for cid in range(j): # cluster_samples = [ts_intention_list[idx] for idx in range(len(labels)) if labels[idx] == cid] # manual_cal_centroid = softdtw_barycenter(cluster_samples, gamma=gamma_val) num_of_clusters_list.append(j) silhouetteScore_list.append(silhouetteScore) print(f"{j} clusters, score is {silhouetteScore}")
注意点
- 初始化
TimeSeriesKMeans时建议传入固定的random_state参数,避免每次运行聚类结果随机浮动,保证质心结果可复现。 - 不管使用
softdtw还是dtw作为聚类度量,cluster_centers_属性都会返回对应度量下计算得到的barycenter作为簇质心,调用逻辑没有区别。 - 手动调用barycenter函数计算时,要保证度量相关参数(比如soft-DTW的gamma值)和聚类时使用的参数完全一致,否则计算结果会和模型输出的质心存在偏差。
内容的提问来源于stack exchange,提问作者Paul726
相关产品推荐
相关产品推荐

