【发布时间】:2010-12-05 11:03:18
【问题描述】:
我正在寻找 k-means 算法的 Python 实现以及用于集群和缓存我的坐标数据库的示例。
【问题讨论】:
-
我对图像做了类似的实现。您可以使用二维数组而不是 RGB 值。这很天真,但对我有用github.com/keremgocen/pattern-recog-notes。
标签: python algorithm cluster-analysis k-means
我正在寻找 k-means 算法的 Python 实现以及用于集群和缓存我的坐标数据库的示例。
【问题讨论】:
标签: python algorithm cluster-analysis k-means
来自wikipedia,你可以使用scipy,K-means clustering an vector quantization
或者,您可以为 OpenCV 使用 Python 包装器,ctypes-opencv。
或者您可以OpenCV's new Python interface,以及他们的kmeans 实现。
【讨论】:
您也可以使用 GDAL,它有很多功能可以处理空间数据。
【讨论】:
更新:(在这个原始答案发布 11 年后,可能是时候更新了。)
首先,您确定要使用 k-means 吗? This page 对一些不同的聚类算法进行了出色的图形总结。我建议在图形之外,特别查看每种方法所需的参数并决定是否可以提供所需的参数(例如,k-means 需要集群的数量,但在开始之前您可能不知道聚类)。
这里有一些资源:
旧答案:
Scipy's clustering 实现运行良好,它们包括k-means 实现。
还有scipy-cluster,它做凝聚聚类;这样做的好处是您不需要提前决定集群的数量。
【讨论】:
SciPy 的 kmeans2() 存在一些数值问题:其他人在 0.6.0 版本中出现 reported 错误消息,例如“矩阵不是正定的 - 无法计算 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
【讨论】:
numpy.vstack([points[labels == i].mean(0) for i in range(labels.max() + 1)]) 获取集群的中心。
对于连续数据,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”辅音有一致的类别。奇怪!
【讨论】:
(多年后)is-it-possible-to-specify-your-own-distance-function-using-scikits-learn-k-means 下的这个 kmeans.py 非常简单且相当快;它使用 scipy.spatial.distance 中 20 多个指标中的任何一个。
【讨论】:
Python 的 Pycluster 和 pyplot 可用于 k-means 聚类和二维数据的可视化。最近的一篇博文 Stock Price/Volume Analysis Using Python and PyCluster 给出了一个使用 PyCluster 对股票数据进行聚类的示例。
【讨论】:
SciKit Learn 的 KMeans() 是在 Python 中应用 k-means 聚类的最简单方法。拟合集群很简单:
kmeans = KMeans(n_clusters=2, random_state=0).fit(X).
这段代码 sn-p 展示了如何存储质心坐标并预测坐标数组的聚类。
>>> 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 的文档提供)
【讨论】: