在计算k-means距离时的环绕问题

我在尝试使用sklearn对某个数据集进行K-means聚类。问题在于其中一个维度是小时数:从0到23的数字,因此距离算法认为0和23之间的距离非常远,因为从绝对值上看确实如此。但实际上,对于我的目的来说,0点和23点非常接近。有没有办法让距离算法进行某种形式的环绕计算,从而计算出更‘真实’的时间差?我在做一些简单的事情,类似于以下内容:

from sklearn.cluster import KMeansclusters = KMeans(n_clusters = 2)data = vstack(data)fit = clusters.fit(data)classes = fit.predict(data)

data元素看起来像[22, 418, 192],其中第一个元素是小时数。

有什么想法吗?


回答:

为什么k-means不适用于任意距离

K-means不是基于距离的算法。

K-means最小化簇内平方和,这是一种方差(它大致是所有簇的加权平均方差,其中每个对象和维度都被赋予相同的权重)。

为了让Lloyd算法收敛,你需要让两个步骤优化同一个函数:

  • 重新分配步骤
  • 质心更新步骤

现在,“均值”函数是一个最小二乘估计器。也就是说,在步骤2中选择均值对于WCSS目标是最优的。在步骤1中通过最小二乘偏差(=平方欧几里得距离,与欧几里得距离单调)分配对象,同样保证了收敛。均值正是你的环绕想法会失效的地方

如果你像@elyase建议的那样插入一个随机的其他距离函数,k-means可能不再收敛

适当的解决方案

对此有各种解决方案:

  • 使用K-medoids(PAM)。通过选择中位数而不是均值,你可以保证使用任意距离时收敛。然而,计算中位数相当昂贵。
  • 将数据转换到一个核空间,在那里你可以接受最小化平方和。例如,你可以将小时数转换为sin(hour / 12 * pi), cos(hour / 12 * pi),这对于SSQ可能是可以接受的。
  • 使用其他基于距离的聚类算法。K-means已经很老了,自那以后在聚类方面已经进行了大量研究。你可以从层次聚类开始(实际上它和k-means一样老),然后尝试DBSCAN及其变体。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注