前言
tslearn和sklearn一样,是一款优秀的机器学习框架,tslearn更偏向于处理时间序列问题,如其聚类模块就包含了DTW(Dynamic Time Warping)等算法及变种,也提供了轮廓系数对聚类效果评估,十分方便。但可惜,tslearn似乎没有提供对KShape聚类的评估方法,而且tslearn用的人也不多,官方文档也是很 “简洁”,网上也搜不到多少相关文章,所以这里也就记录下自己的踩坑过程
轮廓系数评估接口调用
先看官方例子,这里X是一个三维的numpy数组,代表20段时间序列,每段序列16个时间点。labels代表每段时间序列(每条时间曲线)的聚类结果,metric是每条时间曲线之间相似度度量方法,可以看到官方提供了dtw-dba、softdtw以及欧氏距离三种相似度度量方法,但没有关于KShape聚类的。
注意到最后一行,metric=“precomputed”,说明官方提供了用户自定义的距离度量方法,很好,那么使用silhouette_score评估KShape的关键就在此了。又注意到precomputed的时候,参数传的是cdist_dtw(X),而其他传的是X,有什么区别?
打印
醒目的零对角线告诉我们这是X与X自身的距离矩阵,相同时间曲线的距离为零。这样其实也就对了,轮廓系数的计算本来就需要比较当前元素到同簇下其他元素的距离,以及与其他簇下的距离,因此需要得到每个元素之间的距离,X与X自身的距离矩阵恰好解决了这点,而计算其他簇就需要labels标签指明哪些元素属于哪些类
问题来了,那我怎么知道KShape聚类用什么方法度量相似度?不清楚其用的方法,就得不到距离矩阵,也就无法使用precomputed。自己看论文仿写一个?仿写的若与源码的实现不同,细节上的差距也可能会导致轮廓系数的评估不准
源码找突破口
我们现在想要的是KShape对时间序列相似度、也就是距离的计算方法,而且要原封不动,不能仿写,所以只能去KShape源码里寻找结果。点进KShape,大概是一千多行的位置
既然是距离,就在KShape行数往后搜索dist,看看能否找到相关线索
一个醒目的函数名引起了我的注意,cross_dist,交叉距离,似乎有点距离矩阵的味道。于是我查阅了KShape官方文档,看到有这么一条引用:
说明tslearn里的KShape源码是按该论文实现的。在论文k-Shape: Efficient and Accurate Clustering of Time Series中,看到了这样一个公式:
表达式 1 - max(xxx),这不正好和_cross_dist函数的结构一样?就差一个max。
继续点进 cdist_normalized_cc