python - 使用具有余弦相似度的 K 均值 - Python

标签 python scikit-learn k-means cosine-similarity sklearn-pandas

我正在尝试实现 Kmeans python中的算法将使用cosine distance而不是欧几里得距离作为距离度量。
我知道使用不同的距离函数可能是致命的,应该小心使用。使用余弦距离作为度量迫使我改变平均函数(根据余弦距离的平均值必须是归一化向量的逐个元素平均值)。
我见过this手动覆盖 sklearn 的距离函数的优雅解决方案,我想使用相同的技术来覆盖代码的平均部分,但我找不到它。
有谁知道怎么做?
距离度量不满足三角不等式有多重要?
如果有人知道我使用余弦度量或满足距离和平均函数的 kmeans 的不同有效实现,那也将非常有帮助。

非常感谢!

编辑:
使用角距离而不是余弦距离后,代码看起来像这样:

def KMeans_cosine_fit(sparse_data, nclust = 10, njobs=-1, randomstate=None):
    # Manually override euclidean
    def euc_dist(X, Y = None, Y_norm_squared = None, squared = False):
        #return pairwise_distances(X, Y, metric = 'cosine', n_jobs = 10)
        return np.arccos(cosine_similarity(X, Y))/np.pi
    k_means_.euclidean_distances = euc_dist
    kmeans = k_means_.KMeans(n_clusters = nclust, n_jobs = njobs, random_state = randomstate)
    _ = kmeans.fit(sparse_data)
    return kmeans

我注意到(通过数学计算)如果向量被归一化,则标准平均值适用于角度度量。据我了解,必须改_mini_batch_step()k_means_.py .但是这个功能很复杂,我不明白怎么做。

有谁知道替代解决方案?
或者,有谁知道我如何用一个总是强制质心归一化的函数来编辑这个函数?

最佳答案

所以事实证明,您可以将 X 归一化为单位长度,并正常使用 K 均值。原因是如果 X1 和 X2 是单位向量,看下面的等式,最后一行括号内的项是余弦距离。
vect_dist

因此,在使用 k-means 方面,只需执行以下操作:

length = np.sqrt((X**2).sum(axis=1))[:,None]
X = X / length

kmeans = KMeans(n_clusters=10, random_state=0).fit(X)

如果您需要质心和距离矩阵,请执行以下操作:

len_ = np.sqrt(np.square(kmeans.cluster_centers_).sum(axis=1)[:,None])
centers = kmeans.cluster_centers_ / len_
dist = 1 - np.dot(centers, X.T) # K x N matrix of cosine distances

笔记:
  • 刚刚意识到您正在尝试最小化集群的平均向量与其组成部分之间的距离。当您简单地平均向量时,平均向量的长度小于 1。但在实践中,仍然值得运行正常的 sklearn 算法并检查均值向量的长度。在我的情况下,平均向量接近单位长度(平均约为 0.9,但这取决于数据的密度)。
    TLDR:使用 spherecluster @σηγ 指出的包。
  • 关于python - 使用具有余弦相似度的 K 均值 - Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46409846/

    相关文章:

    python - Django 中不同组织的管理员、用户和组

    python - 更快更简洁地反转字符串中的句子?

    python - 实现 scikit-learn 机器学习算法

    algorithm - 在大小相等的 k 个簇中分组 n 个点

    python - 存储函数的参数以供以后评估

    python - 为什么 Python informixdb 包抛出错误!

    python - CountVectorizer().fit in scikit-learn Python 给出内存错误

    machine-learning - Hyperopt 探索/利用策略

    python - 如何使用 sklearn k-means 聚类根据特征之间的相关性对特征进行聚类

    opencv - 如何使用 kmeans2 估计用于颜色量化的簇数