web-dev-qa-db-fra.com

Algorithme k-means Python

Je recherche une implémentation Python de l'algorithme k-means avec des exemples pour regrouper et mettre en cache ma base de données de coordonnées.

46
Eeyore

Les implémentations de cluster _ fonctionnent bien et incluent une implémentation k-means .

Il y a aussi scipy-cluster , qui effectue une classification par agglomération; Cela présente l'avantage que vous n'avez pas besoin de décider du nombre de clusters à l'avance.

54
tom10

SciPy's kmeans2 () a quelques problèmes numériques: d'autres ont ont signalé des messages d'erreur tels que "Matrix is ​​not positive - la décomposition de Cholesky ne peut pas être calculée" dans la version 0.6.0, et je viens de rencontrer la même chose dans version 0.7.1.

Pour le moment, je recommanderais plutôt d’utiliser PyCluster . Exemple d'utilisation:

>>> 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
28
Vebjorn Ljosa

Pour les données continues, k-means est très facile.

Vous avez besoin d'une liste de vos moyennes et, pour chaque point de données, trouvez la moyenne la plus proche de celle-ci et faites la moyenne du nouveau point de données. vos moyens représenteront les groupes de points saillants récents dans les données d'entrée.

Je fais la moyenne en continu, il n’est donc pas nécessaire de disposer des anciennes données pour obtenir la nouvelle moyenne. Étant donné l’ancienne moyenne k, le prochain point de données x et une constante n qui correspond au nombre de points de données passés pour lesquels la moyenne est maintenue, la nouvelle moyenne est

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

Voici le code complet 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)

vous pouvez simplement imprimer les moyens une fois que toutes les données sont passées, mais il est beaucoup plus amusant de les voir changer en temps réel. J'ai utilisé cela sur des enveloppes de fréquences de 20 ms de sons et après une conversation d'une minute ou deux, il y avait des catégories cohérentes pour la voyelle courte, la voyelle longue 'o' et la consonne 's'. bizarre!

20
Nathan

De wikipedia , vous pouvez utiliser scipy, K-means regroupant une quantification vectorielle

Vous pouvez également utiliser un wrapper Python pour OpenCV, ctypes-opencv .

Ou vous pourriez la nouvelle interface Python d'OpenCV , et leur implémentation de kmeans .

5
Jacob

(Des années plus tard), cette kmeans.py sous est-il-possible-de-spécifier-votre-propre-fonction-de-distance-à l'aide de scikits-learn-k-moyennes est simple et raisonnablement rapide; il utilise l'une des 20 métriques de scipy.spatial.distance.

5
denis

SciKit Learn KMeans () est le moyen le plus simple d'appliquer la classification en k-means en Python. L'ajustement des grappes est simple comme suit: kmeans = KMeans(n_clusters=2, random_state=0).fit(X).

Cet extrait de code montre comment stocker des coordonnées de centre de gravité et prévoir des grappes pour un tableau de coordonnées.

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

(gracieuseté de la documentation de SciKit Learn, lien ci-dessus)

0
gsilv

Vous pouvez également utiliser GDAL, qui possède de nombreuses fonctions pour travailler avec des données spatiales.

0
George Silva