web-dev-qa-db-fra.com

Clustering non supervisé avec un nombre inconnu de clusters

J'ai un grand ensemble de vecteurs en 3 dimensions. J'ai besoin de les regrouper en fonction de la distance euclidienne de sorte que tous les vecteurs dans un cluster particulier aient une distance euclidienne entre eux inférieure à un seuil "T".

Je ne sais pas combien de clusters existent. À la fin, il peut exister des vecteurs individuels qui ne font partie d'aucun cluster car sa distance euclidienne n'est pas inférieure à "T" avec l'un des vecteurs dans l'espace.

Quels algorithmes/approches existants devraient être utilisés ici?

68
London guy

Vous pouvez utiliser clustering hiérarchique . Il s'agit d'une approche plutôt basique, il existe donc de nombreuses implémentations disponibles. Il est par exemple inclus dans Python scipy .

Voir par exemple le script suivant:

import matplotlib.pyplot as plt
import numpy
import scipy.cluster.hierarchy as hcluster

# generate 3 clusters of each around 100 points and one Orphan point
N=100
data = numpy.random.randn(3*N,2)
data[:N] += 5
data[-N:] += 10
data[-1:] -= 20

# clustering
thresh = 1.5
clusters = hcluster.fclusterdata(data, thresh, criterion="distance")

# plotting
plt.scatter(*numpy.transpose(data), c=clusters)
plt.axis("equal")
title = "threshold: %f, number of clusters: %d" % (thresh, len(set(clusters)))
plt.title(title)
plt.show()

Ce qui produit un résultat similaire à l'image suivante. clusters

Le seuil donné comme paramètre est une valeur de distance sur la base de laquelle la décision est prise si les points/clusters seront fusionnés dans un autre cluster. La métrique de distance utilisée peut également être spécifiée.

Notez qu'il existe différentes méthodes pour calculer la similitude intra/inter-cluster, par ex. distance entre les points les plus proches, distance entre les points les plus éloignés, distance aux centres des grappes, etc. Certaines de ces méthodes sont également prises en charge par le module de clustering hiérarchique scipys ( liaison simple/complète/moyenne ... ). Selon votre message, je pense que vous voudriez utiliser lien complet .

Notez que cette approche permet également de petits clusters (à un seul point) s'ils ne répondent pas au critère de similitude des autres clusters, c'est-à-dire le seuil de distance.


Il existe d'autres algorithmes qui fonctionneront mieux, qui deviendront pertinents dans les situations avec beaucoup de points de données. Comme d'autres réponses/commentaires le suggèrent, vous pouvez également consulter l'algorithme DBSCAN:


Pour un bon aperçu de ces algorithmes de clustering et d'autres, jetez également un œil à cette page de démonstration (de la bibliothèque scikit-learn de Python):

Image copiée de cet endroit:

http://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html

Comme vous pouvez le voir, chaque algorithme fait des hypothèses sur le nombre et la forme des clusters qui doivent être pris en compte. Que ce soit des hypothèses implicites imposées par l'algorithme ou des hypothèses explicites spécifiées par paramétrage.

72
moooeeeep

La réponse de moooeeeep recommande d'utiliser le clustering hiérarchique. Je voulais expliquer comment choisir le seuil du clustering.

Une façon consiste à calculer les regroupements en fonction de différents seuils t1, t2, t, ... puis à calculer une métrique pour la "qualité" du clustering. La prémisse est que la qualité d'un clustering avec le nombre optimal de clusters aura la valeur maximale de la métrique de qualité.

Calinski-Harabasz est un exemple de mesure de bonne qualité que j'ai utilisée dans le passé. En bref: vous calculez les distances moyennes entre les clusters et les divisez par les distances intra-cluster. L'affectation de cluster optimale aura les clusters les plus séparés les uns des autres et les clusters les plus "serrés".

Soit dit en passant, vous n'avez pas à utiliser le clustering hiérarchique. Vous pouvez également utiliser quelque chose comme k - signifie, le pré-calculer pour chaque k, puis choisir le k qui a le score de Calinski-Harabasz le plus élevé .

Faites-moi savoir si vous avez besoin de plus de références, et je vais parcourir mon disque dur pour trouver des articles.

21
Max

Découvrez l'algorithme DBSCAN . Il se fonde sur la densité locale des vecteurs, c'est-à-dire qu'ils ne doivent pas être distants de plus d'une distance ε , et peut déterminer automatiquement le nombre de clusters. Il considère également les valeurs aberrantes, c'est-à-dire les points avec un nombre insuffisant de ε - voisins, comme ne faisant pas partie d'un cluster. La page Wikipedia contient des liens vers quelques implémentations.

11
Fred Foo

Utilisez OPTIQUE , qui fonctionne bien avec de grands ensembles de données.

OPTIQUE: Ordonner les points pour identifier la structure de clustering étroitement liée à DBSCAN, trouve un échantillon de base de haute densité et développe les clusters à partir d'eux 1 . Contrairement à DBSCAN, conserve la hiérarchie de cluster pour un rayon de voisinage variable. Mieux adapté à une utilisation sur de grands ensembles de données que l'implémentation sklearn actuelle de DBSCAN

from sklearn.cluster import OPTICS
db = DBSCAN(eps=3, min_samples=30).fit(X)

Affinez eps, min_samples selon vos besoins.

0
Ravindra babu