Clustering avec une matrice de distance


52

J'ai une matrice (symétrique) Mqui représente la distance entre chaque paire de nœuds. Par exemple,

    ABCDEFGHIJKL
A 0 20 20 20 40 60 60 60 100 120 120 120
B 20 0 20 20 60 80 80 80 120 140 140 140 140
C 20 20 0 20 60 80 80 80 120 140 140 140 140
D 20 20 20 0 60 80 80 80 120 140 140 140 140
E 40 60 60 60 0 20 20 20 60 80 80 80
F 60 80 80 80 20 0 20 20 40 60 60 60
G 60 80 80 80 20 20 0 20 60 80 80 80
H 60 80 80 80 20 20 20 0 60 80 80 80 80
I 100 120 120 120 60 40 60 60 0 20 20 20
J 120 140 140 140 80 60 80 80 20 0 20 20
K 120 140 140 140 80 80 80 80 20 20 0 0 20
L 120 140 140 140 80 80 80 80 20 20 20 20 0

Existe-t-il une méthode permettant d'extraire des grappes M(si nécessaire, le nombre de grappes peut être fixé), de sorte que chaque grappe contienne des nœuds distants les uns des autres. Dans l'exemple, les grappes seraient (A, B, C, D), (E, F, G, H)et (I, J, K, L).

J'ai déjà essayé UPGMA et k-means mais les clusters résultants sont très mauvais.

Les distances sont les étapes moyennes que prendrait un marcheur aléatoire pour aller de nœud Aà nœud B( != A) et revenir au nœud A. C'est garanti c'est M^1/2une métrique. Pour exécuter, cela ksignifie que je n'utilise pas le centre de gravité. Je définis la distance entre les ngrappes de nœuds ccomme la distance moyenne entre ntous les nœuds de c.

Merci beaucoup :)


1
Vous devriez envisager d'ajouter les informations selon lesquelles vous avez déjà essayé UPGMA (et d'autres que vous avez peut-être essayé) :)
Björn Pollex

1
J'ai une question. Pourquoi avez-vous dit que le k-means fonctionnait mal? J'ai passé votre matrice à k-means et le regroupement a été parfait. N'avez-vous pas passé la valeur de k (nombre de clusters) à k-means?

3
@ user12023 Je pense que vous avez mal compris la question. La matrice n'est pas une série de points - ce sont les distances par paire les séparant. Vous ne pouvez pas calculer le centroïde d'une collection de points si vous ne tenez compte que des distances entre eux (et non de leurs coordonnées réelles), du moins pas de manière évidente.
Stumpy Joe Pete le

7
k-means ne supporte pas les matrices de distance . Il n'utilise jamais de distances point à point. Donc, je ne peux que supposer que votre matrice doit avoir été réinterprétée en tant que vecteurs et exploitée sur ces vecteurs ... peut-être que la même chose s’est produite pour les autres algorithmes que vous avez essayés: ils attendaient des données brutes et vous passiez une matrice de distance.
Anony-Mousse

Réponses:


38

Il y a un certain nombre d'options.

k-medoids en cluster

Premièrement, vous pouvez essayer de partitionner autour de medoids (pam) au lieu d’utiliser le clustering k-means. Celui-ci est plus robuste et pourrait donner de meilleurs résultats. Van der Laan a retravaillé l'algorithme. Si vous voulez le mettre en œuvre vous-même, son article mérite d'être lu.

Il existe un algorithme de classification k-medoids spécifique pour les grands ensembles de données. L'algorithme s'appelle Clara in R et est décrit au chapitre 3 de la section Recherche de groupes dans les données: introduction à l'analyse par grappes. par Kaufman, L et Rousseeuw, PJ (1990).

classification hiérarchique

Au lieu d'UPGMA, vous pouvez essayer d'autres options de clustering hiérarchique. Tout d'abord, lorsque vous utilisez un clustering hiérarchique, veillez à définir correctement la méthode de partitionnement. Cette méthode de partitionnement consiste essentiellement à calculer les distances entre les observations et les grappes. J'utilise principalement la méthode de Ward ou le couplage complet, mais d'autres options pourraient vous convenir.

Je ne sais pas si vous l'avez déjà essayé, mais la méthode de liaison unique ou de jonction de voisin est souvent préférée à l'UPGMA dans les applications phylogénétiques. Si vous ne l'aviez pas encore essayé, vous pourriez également tenter votre chance, car cela donne souvent d'excellents résultats.


Dans R, vous pouvez jeter un coup d'œil au cluster de paquets . Tous les algorithmes décrits sont implémentés ici. Voir? Pam,? Clara,? Hclust, ... Vérifiez également les différentes implémentations de l'algorithme en? Kmeans. Parfois, choisir un autre algorithme peut améliorer considérablement la mise en cluster.


EDIT: Vous venez de penser à quelque chose: si vous travaillez avec des graphes, des nœuds et autres, vous devriez également jeter un coup d'œil à l'algorithme de classification de Markov. Celui-ci est utilisé par exemple pour regrouper des séquences basées sur les similarités d'explosion, et fonctionne incroyablement bien. Il peut effectuer le regroupement à votre place ou vous donner des idées sur la façon de résoudre le problème de recherche sur lequel vous vous concentrez. Sans rien savoir en fait, je suppose que ses résultats méritent d’être examinés. Si je puis me permettre, je considère toujours cette méthode de Stijn van Dongen comme l’un des plus beaux résultats de la mise en grappes que j’ai jamais rencontrés.

http://www.micans.org/mcl/


22

Un moyen de mettre en évidence les clusters sur votre matrice de distance consiste à mettre à l' échelle multidimensionnelle . Lorsque vous projetez des individus (ici, ce que vous appelez vos nœuds) dans un espace 2D, cela fournit une solution comparable à celle de PCA. Ceci n'est pas supervisé, vous ne pourrez donc pas spécifier a priori le nombre de clusters, mais je pense qu'il peut être utile de résumer rapidement une matrice de distance ou de similarité donnée.

Voici ce que vous obtiendrez avec vos données:

tmp <- matrix(c(0,20,20,20,40,60,60,60,100,120,120,120,
                20,0,20,20,60,80,80,80,120,140,140,140,
                20,20,0,20,60,80,80,80,120,140,140,140,
                20,20,20,0,60,80,80,80,120,140,140,140,
                40,60,60,60,0,20,20,20,60,80,80,80,
                60,80,80,80,20,0,20,20,40,60,60,60,
                60,80,80,80,20,20,0,20,60,80,80,80,
                60,80,80,80,20,20,20,0,60,80,80,80,
                100,120,120,120,60,40,60,60,0,20,20,20,
                120,140,140,140,80,60,80,80,20,0,20,20,
                120,140,140,140,80,60,80,80,20,20,0,20,
                120,140,140,140,80,60,80,80,20,20,20,0),
              nr=12, dimnames=list(LETTERS[1:12], LETTERS[1:12]))
d <- as.dist(tmp)
mds.coor <- cmdscale(d)
plot(mds.coor[,1], mds.coor[,2], type="n", xlab="", ylab="")
text(jitter(mds.coor[,1]), jitter(mds.coor[,2]),
     rownames(mds.coor), cex=0.8)
abline(h=0,v=0,col="gray75")

mds

J'ai ajouté un petit vacillement sur les coordonnées x et y pour permettre de distinguer les cas. Remplacez tmppar 1-tmpsi vous préférez travailler avec des différences, mais cela produit essentiellement la même image. Cependant, voici la solution de clustering hiérarchique, avec des critères d'agglomération uniques :

plot(hclust(dist(1-tmp), method="single"))

hc

Vous pourriez affiner la sélection des grappes en fonction du dendrogramme ou de méthodes plus robustes. Voir par exemple la question connexe suivante: quels critères de fin pour les grappes hiérarchiques agglomératives sont-ils utilisés dans la pratique?


2

Le clustering spectral [1] nécessite une matrice d’affinité, le clustering étant défini par les premières fonctions propres de la décomposition deK

L=D1/2AD1/2

Avec étant la matrice d'affinité des données et étant la matrice diagonale définie comme (edit: désolé d'être clair, mais vous pouvez générer une matrice d'affinité à partir d' une matrice de distance à condition que vous connaissez le maximum possible / distance raisonnable comme , bien que d'autres schémas existent aussi)ADAij=1dij/max(d)

{Di,i=jAi,jDij=0

Avec étant le eigendecomposition de , avec comme colonnes empilées les fonctions propres, en ne conservant que les plus grandes vecteurs propres , on définit la matrice de ligne normaliséeL KXLKX

Yij=Xij(j(Xij)2)1/2

Chaque ligne de est un point de et peut être groupée avec un algorithme de classification ordinaire (comme K-means).R kYRk

Regardez ma réponse ici pour voir un exemple: https://stackoverflow.com/a/37933688/2874779


[1] Ng, AY, Jordan, MI et Weiss, Y. (2002). Sur le clustering spectral: analyse et algorithme. Progrès des systèmes de traitement d'informations neuronaux, 2, 849-856. Pg.2


2

Ce que vous faites, c'est essayer de regrouper les nœuds d'un graphique, ou d'un réseau, proches les uns des autres. Il existe tout un domaine de recherche consacré à ce problème, parfois appelé détection de communauté dans les réseaux . Regarder votre problème de ce point de vue peut probablement clarifier les choses.

Vous trouverez de nombreux algorithmes dédiés à ce problème et certains d'entre eux sont basés sur la même idée que vous avez eue, à savoir la mesure des distances entre les nœuds avec des marches aléatoires.

Le problème est souvent formulé sous la forme d' optimisation de la modularité [1], dans laquelle la modularité d'un cluster mesure dans quelle mesure le clustering sépare le réseau en clusters densément connectés (c'est-à-dire des clusters dont les nœuds sont proches les uns des autres).

En fait, vous pouvez montrer que la modularité est égale à la probabilité qu’un marcheur aléatoire reste, après un pas, dans les mêmes grappes qu’initialement moins la même probabilité pour deux marcheurs aléatoires indépendants [2].

Si vous autorisez plus de marcheurs aléatoires, vous recherchez une mise en cluster plus grossière du réseau. Le nombre d'étapes de la marche aléatoire joue donc le rôle d'un paramètre de résolution permettant de récupérer une hiérarchie de clusters. Dans ce cas, la quantité qui exprime la tendance des randonneurs aléatoires à rester dans leur groupe initial après t étapes est appelée la stabilité de Markov d'une partition à l'instant t [2] et équivaut à la modularité lorsque t = 1 .

Vous pouvez donc résoudre votre problème en recherchant le regroupement de votre graphique qui optimise la stabilité à un instant donné t , où t est le paramètre de résolution (plus grand t vous donnera des grappes plus grandes). L'une des méthodes les plus utilisées pour optimiser la stabilité (ou la modularité avec un paramètre de résolution) est l' algorithme de Louvain [3]. Vous pouvez trouver une implémentation ici: https://github.com/michaelschaub/generalizedLouvain .

[1] Newman, MEJ & Girvan, M. Recherche et évaluation de la structure de la communauté dans les réseaux. Phys. Rev. E 69, 026113 (2004).

[2] Delvenne, J.-C., Yaliraki, SN et Barahona, M. Stabilité des communautés de graphes à travers les échelles de temps. Proc. Natl. Acad. Sci. 107, 12755-12760 (2010).

[3] Blondel, VD, Guillaume, J.-L., Lambiotte, R. et Lefebvre, E. Déploiement rapide de communautés dans de grands réseaux. J. Stat. Mech. Théorie Exp. 2008, P10008 (2008).


1

Eh bien, il est possible d’effectuer une classification K-means sur une matrice de similarité donnée, il faut d’abord centrer la matrice, puis prendre les valeurs propres de la matrice. La dernière étape, la plus importante, consiste à multiplier les deux premiers ensembles de vecteurs propres à la racine carrée de diagonales des valeurs propres pour obtenir les vecteurs puis à passer à l'aide de K-moyennes. Le code ci-dessous montre comment procéder. Vous pouvez changer la matrice de similarité. fpdist est la matrice de similarité.

mds.tau <- function(H)
{
  n <- nrow(H)
   P <- diag(n) - 1/n
   return(-0.5 * P %*% H %*% P)
  }
  B<-mds.tau(fpdist)
  eig <- eigen(B, symmetric = TRUE)
  v <- eig$values[1:2]
#convert negative values to 0.
v[v < 0] <- 0
X <- eig$vectors[, 1:2] %*% diag(sqrt(v))
library(vegan)
km <- kmeans(X,centers= 5, iter.max=1000, nstart=10000) .
#embedding using MDS
cmd<-cmdscale(fpdist)

0

Avant d'essayer d'exécuter le regroupement sur la matrice, vous pouvez essayer l'une des techniques d'analyse factorielle et ne conserver que les variables les plus importantes pour calculer la matrice de distance. Une autre chose que vous pouvez faire est d'essayer d'utiliser des méthodes floues qui ont tendance à fonctionner mieux (du moins d'après mon expérience) dans ce type de cas, essayez d'abord Cmeans, Fuzzy K-medoids et spécialement GKCmeans.


0

Le co-clustering est l'une des réponses que je pense. Mais je ne suis pas expert ici. La co-classification n'est pas la méthode du nouveau-né, vous pouvez donc trouver des algues dans R, le wiki montre bien ces concepts. Une autre méthode qui n’est pas mentionnée est le partitionnement de graphe (mais je vois que ce graphe ne serait pas clairsemé, le partitionnement de graphe serait utile si votre matrice était dominée par des valeurs signifiant = distance maximale = aucune similarité entre les nœuds).


0

Regardez dans AFFINITY PROPAGATION. Cette technique prend en entrée la matrice de similarité et produit un nombre optimal de clusters avec un exemple représentatif pour chaque cluster.


2
Pourriez-vous développer et expliquer en quoi cette méthode peut aider dans ce cas?
Andy


0

Vous pouvez également utiliser l'algorithme de Kruskal pour rechercher des arbres recouvrants minimaux, mais se terminant dès que vous obtenez les trois clusters. J'ai essayé de cette façon et il produit les clusters que vous avez mentionnés: {ABCD}, {EFGH} et {IJKL}.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.