48

我正在寻找 k-means 算法的 Python 实现以及集群和缓存我的坐标数据库的示例。

4

8 回答 8

56

更新:(在这个原始答案十一年后,可能是时候更新了。)

首先,你确定你想要k-means吗? 此页面对一些不同的聚类算法进行了出色的图形总结。我建议在图形之外,特别查看每种方法所需的参数并决定是否可以提供所需的参数(例如,k-means 需要集群的数量,但在开始之前您可能不知道聚类)。

以下是一些资源:

老答案:

Scipy 的集群实现运行良好,它们包括一个k-means实现。

还有scipy-cluster,它进行凝聚聚类;这样做的好处是您不需要提前决定集群的数量。

于 2009-10-09T22:10:57.093 回答
29

SciPy 的kmeans2()存在一些数值问题:其他人在 0.6.0 版本中报告了错误消息,例如“矩阵不是正定的 - 无法计算 Cholesky 分解”,而我在 0.7.1 版本中也遇到了同样的问题。

现在,我建议改用PyCluster。示例用法:

>>> import numpy
>>> import Pycluster
>>> points = numpy.vstack([numpy.random.multivariate_normal(mean, 
                                                            0.03 * numpy.diag([1,1]),
                                                            20) 
                           for mean in [(1, 1), (2, 4), (3, 2)]])
>>> labels, error, nfound = Pycluster.kcluster(points, 3)
>>> labels  # Cluster number for each point
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], dtype=int32)
>>> error   # The within-cluster sum of distances for the solution
1.7721661785401261
>>> nfound  # Number of times this solution was found
1
于 2010-02-08T20:03:43.783 回答
21

对于连续数据,k-means 非常简单。

您需要一个平均值列表,对于每个数据点,找到最接近的平均值并将新数据点平均到它。您的均值将代表输入数据中最近的显着点簇。

我不断地做平均,所以不需要旧数据来获得新的平均值。给定旧平均值k、下一个数据点x和一个常数n,即保持平均值的过去数据点的数量,新平均值为

k*(1-(1/n)) + n*(1/n)

这是Python中的完整代码

from __future__ import division
from random import random

# init means and data to random values
# use real data in your code
means = [random() for i in range(10)]
data = [random() for i in range(1000)]

param = 0.01 # bigger numbers make the means change faster
# must be between 0 and 1

for x in data:
    closest_k = 0;
    smallest_error = 9999; # this should really be positive infinity
    for k in enumerate(means):
        error = abs(x-k[1])
        if error < smallest_error:
            smallest_error = error
            closest_k = k[0]
        means[closest_k] = means[closest_k]*(1-param) + x*(param)

您可以在所有数据都通过后打印平均值,但是实时观察它的变化会更有趣。我在 20ms 位声音的频率包络上使用了它,在与它交谈一两分钟后,它对短“a”元音、长“o”元音和“s”辅音有一致的类别。奇怪!

于 2010-04-09T05:21:50.143 回答
6

(多年后)is-it-possible-to-specify-your-own-distance-function-using-scikits-learn-k-means下的这个 kmeans.py简单且相当快;它使用 scipy.spatial.distance 中的 20 多个指标中的任何一个。

于 2011-07-04T14:43:41.447 回答
5

wikipedia,您可以使用 scipy、 K-means 聚类矢量量化

或者,您可以为 OpenCV 使用 Python 包装器ctypes-opencv

或者你可以使用 OpenCV 的新 Python 接口,以及他们的kmeans实现。

于 2009-10-09T19:21:30.063 回答
1

SciKit Learn 的KMeans()是在 Python 中应用 k-means 聚类的最简单方法。拟合集群很简单 kmeans = KMeans(n_clusters=2, random_state=0).fit(X)

此代码片段显示了如何存储质心坐标并预测坐标数组的聚类。

>>> from sklearn.cluster import KMeans
>>> import numpy as np
>>> X = np.array([[1, 2], [1, 4], [1, 0],
...               [4, 2], [4, 4], [4, 0]])
>>> kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
>>> kmeans.labels_
array([0, 0, 0, 1, 1, 1], dtype=int32)
>>> kmeans.predict([[0, 0], [4, 4]])
array([0, 1], dtype=int32)
>>> kmeans.cluster_centers_
array([[ 1.,  2.],
       [ 4.,  2.]])

(由 SciKit Learn 的文档提供,上面链接)

于 2017-02-12T12:45:48.453 回答
0

您还可以使用 GDAL,它具有许多处理空间数据的功能。

于 2009-10-09T19:35:19.320 回答
0

Python 的 Pycluster 和 pyplot 可用于 k-means 聚类和 2D 数据的可视化。最近的一篇博客文章使用 Python 和 PyCluster 进行股票价格/成交量分析给出了一个使用 PyCluster 对股票数据进行聚类的示例。

于 2014-09-14T20:47:16.640 回答