Eey*_*ore 46 python algorithm cluster-analysis k-means
我正在寻找k-means算法的Python实现,并带有示例来聚类和缓存我的坐标数据库.
Veb*_*osa 28
SciPy的kmeans2()存在一些数值问题:其他人报告了错误消息,例如"Matrix不是正定的 - 在第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
Run Code Online (Sandbox Code Playgroud)
Nat*_*han 20
对于连续数据,k-means非常容易.
您需要一个手段列表,并为每个数据点找到最接近的平均值,并将新数据指向它的平均值.您的均值将代表输入数据中最近显着的点集群.
我不断进行平均,因此无需使用旧数据来获得新的平均值.给定旧的平均值k
,下一个数据点x
和一个常数n
,即保持平均值的过去数据点的数量,新的平均值是
k*(1-(1/n)) + n*(1/n)
Run Code Online (Sandbox Code Playgroud)
这是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)
Run Code Online (Sandbox Code Playgroud)
你可以在所有数据都通过时打印出来,但观察它实时变化会更有趣.我在20ms声音的频率包络上使用它,并且在与它通话一两分钟之后,它对于短'a'元音,长'o'元音和's'辅音具有一致的类别.奇怪!
从维基百科,您可以使用scipy, K-means聚类矢量量化
或者,您可以使用OpenCV的Python包装器,ctypes-opencv.
或者你可以使用OpenCV的新Python界面,以及他们的kmeans实现.
(多年以后)这个kmeans.py 是可以指定你自己的距离函数使用scikits-learn-k-means是直截了当且相当快的; 它使用scipy.spatial.distance中的20多个指标中的任何一个.