2009-10-09 67 views
44

Estoy buscando la implementación de Python del algoritmo k-means con ejemplos para agrupar y almacenar en caché mi base de datos de coordenadas.Algoritmo Python k-means

+1

me hizo una aplicación similar para imágenes. Puede usar matrices en 2D en lugar de valores RGB. Es muy ingenuo pero funciona para mí https://github.com/keremgocen/pattern-recog-notes. – mass

Respuesta

53

Scipy's clustering implementaciones funcionan bien, e incluyen una implementación k-means.

También hay scipy-cluster, que hace agrupamiento aglomerativo; Esto tiene la ventaja de que no es necesario que decida la cantidad de clusters antes de tiempo.

0

También puede usar GDAL, que tiene muchas funciones para trabajar con datos espaciales.

28

de SciPy kmeans2() tiene algunos problemas numéricos: otros tienen reported mensajes de error como "Matrix no es definida positiva - la descomposición de Cholesky no se puede calcular" en la versión 0.6.0, y sólo se encontró con el mismo en la versión 0.7.1.

Por el momento, recomendaría usar PyCluster en su lugar. Ejemplo de uso:

>>> 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 
+2

También parece que la función kmeans del clúster scipy no acepta un método de distancia y siempre usa Euclidean. ¿Otra razón para usar PyCluster? – Sid

+0

simplemente pulse el error mencionado ... Veo en su ejemplo las agrupaciones de grupos, pero ¿puede obtener el clúster como "centro"? – monkut

+0

@monkup, 'numpy.vstack ([points [labels == i] .mean (0) for i in range (labels.max() + 1)])' para obtener los centros de los clusters. –

19

Para datos continuos, k-means es muy fácil.

Necesita una lista de sus medios, y para cada punto de datos, encuentre el promedio más cercano y promedie el nuevo punto de datos al mismo. sus medios representarán los clústeres salientes recientes de puntos en los datos de entrada.

Hago el promedio continuamente, por lo que no es necesario tener los datos antiguos para obtener el nuevo promedio. Dada la edad media k, el siguiente punto x de datos, y una constante n que es el número de puntos de datos anteriores para mantener el promedio de, la nueva media es

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

Aquí está el código completo en 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) 

puede imprimir el medio cuando todos los datos han pasado, pero es mucho más divertido verlo cambiar en tiempo real. Usé esto en sobres de frecuencia de bits de 20 ms de sonido y después de hablar con él durante un minuto o dos, tenía categorías consistentes para la vocal corta 'a', la vocal larga 'o' y la consonante 's'. ¡extraño!

+0

¡Este es un gran algoritmo de aprendizaje de kmeans en línea! Pero hay un error en la última fila del código. debería eliminar una pestaña de esta fila: means [closest_k] = means [closest_k] * (1-param) + x * (param) – lai

-3

* El presente código de K-medias con Phyton *

from math import math 

from functions import functions 

class KMEANS: 

@staticmethod 
def KMeans(data,classterCount,globalCounter): 
counter=0 
classes=[] 
cluster =[[]] 
cluster_index=[] 
tempClasses=[] 
for i in range(0,classterCount): 
globalCounter+=1 
classes.append(cluster) 
cluster_index.append(cluster) 
tempClasses.append(cluster) 
classes2=classes[:] 
for i in range(0,len(classes)): 
globalCounter=1 
cluster = [data[i]] 
classes[i]=cluster 
functions.ResetClasterIndex(cluster_index,classterCount,globalCounter) 
functions.ResetClasterIndex(classes2,classterCount,globalCounter) 
def clusterFills(classeses,globalCounter,counter): 
counter+=1 
combinedOfClasses = functions.CopyTo(classeses) 
functions.ResetClasterIndex(cluster_index,classterCount,globalCounter) 
functions.ResetClasterIndex(tempClasses,classterCount,globalCounter) 
avarage=[] 
for k in range(0,len(combinedOfClasses)): 
globalCounter+=1 
avarage.append(functions.GetAvarage(combinedOfClasses[k])) 
for i in range(0,len(data)): 
globalCounter+=1 
minimum=0 
index=0 
for k in range(0,len(avarage)): 
total=0.0 
for j in range(0,len(avarage[k])): 
total += (avarage[k][j]-data[i][j]) **2 
tempp=math.sqrt(total) 
if(k==0): 
minimu=tempp 
if(tempp&lt;=minimu): 
minimu=tempp 
index=k 
tempClasses[index].append(data[i]) 
cluster_index[index].append(i) 
if(functions.CompareArray(tempClasses,combinedOfClasses)==1): 
return clusterFills(tempClasses,globalCounter,counter) 
returnArray = [] 
returnArray.append(tempClasses) 
returnArray.append(cluster_index) 
returnArray.append(avarage) 
returnArray.append(counter) 
return returnArray 

cdcd = clusterFills(classes,globalCounter,counter) 
if cdcd !=None: 
return cdcd 

@staticmethod 
def KMeansPer(data,classterCount,globalCounter): 
perData=data[0:int(float(len(data))/100*30)] 
result = KMEANS.KMeans(perData,classterCount,globalCounter) 
cluster_index=[] 
tempClasses=[] 
classes=[] 
cluster =[[]] 
for i in range(0,classterCount): 
globalCounter+=1 
classes.append(cluster) 
cluster_index.append(cluster) 
tempClasses.append(cluster) 
classes2=classes[:] 
for i in range(0,len(classes)): 
globalCounter=1 
cluster = [data[i]] 
classes[i]=cluster 
functions.ResetClasterIndex(cluster_index,classterCount,globalCounter) 
functions.ResetClasterIndex(classes2,classterCount,globalCounter) 
counter=0 
def clusterFills(classeses,globalCounter,counter): 
counter+=1 
combinedOfClasses = functions.CopyTo(classeses) 
functions.ResetClasterIndex(cluster_index,classterCount,globalCounter) 
functions.ResetClasterIndex(tempClasses,classterCount,globalCounter) 
avarage=[] 
for k in range(0,len(combinedOfClasses)): 
globalCounter+=1 
avarage.append(functions.GetAvarage(combinedOfClasses[k])) 
for i in range(0,len(data)): 
globalCounter+=1 
minimum=0 
index=0 
for k in range(0,len(avarage)): 
total=0.0 
for j in range(0,len(avarage[k])): 
total += (avarage[k][j]-data[i][j]) **2 
tempp=math.sqrt(total) 
if(k==0): 
minimu=tempp 
if(tempp&lt;=minimu): 
minimu=tempp 
index=k 
tempClasses[index].append(data[i]) 
cluster_index[index].append(i) 
if(functions.CompareArray(tempClasses,combinedOfClasses)==1): 
return clusterFills(tempClasses,globalCounter,counter) 
returnArray = [] 
returnArray.append(tempClasses) 
returnArray.append(cluster_index) 
returnArray.append(avarage) 
returnArray.append(counter) 
return returnArray 

cdcd = clusterFills(result[0],globalCounter,counter) 
if cdcd !=None: 
return cdcd 

Read ...

0

SciKit de KMeans() aprender es la forma más sencilla de aplicar k-means clustering en Python. El ajuste de clusters es simple como: kmeans = KMeans(n_clusters=2, random_state=0).fit(X).

Este fragmento de código muestra cómo almacenar coordenadas de centroides y predecir clusters para una matriz de coordenadas.

>>> 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.]]) 

(cortesía de SciKit Aprender de documentación, vinculado anteriormente)

Cuestiones relacionadas