Clustering con una matrice di distanza


52

Ho una matrice (simmetrica) Mche rappresenta la distanza tra ogni coppia di nodi. Per esempio,

    ABCDEFGHIJKL
A 0 20 20 20 40 60 60 60 100 100 120 120 120
B 20 0 20 20 60 80 80 80 120 140 140 140
C 20 20 0 20 60 80 80 80 120 140 140 140
D 20 20 20 0 60 80 80 80 120 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
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 60 80 80 20 20 0 20
L 120 140 140 140 80 60 80 80 20 20 20 0

Esiste un metodo per estrarre i cluster M(se necessario, è possibile correggere il numero di cluster), in modo tale che ciascun cluster contenga nodi con piccole distanze tra loro. Nell'esempio, i cluster sarebbero (A, B, C, D), (E, F, G, H)e (I, J, K, L).

Ho già provato UPGMA e k-means ma i cluster risultanti sono molto cattivi.

Le distanze sono i passi medi che un camminatore casuale dovrebbe prendere per passare da un nodo Aall'altro B( != A) e tornare al nodo A. È garantito che M^1/2è una metrica. Per eseguire k-means, non uso il centroide. Definisco la distanza tra il ncluster di nodi ccome la distanza media tra ne tutti i nodi in c.

Molte grazie :)


1
Dovresti considerare di aggiungere le informazioni che hai già provato UPGMA (e altre che potresti aver provato) :)
Björn Pollex

1
Ho una domanda. Perché hai detto che il k-mean ha funzionato male? Ho passato il tuo Matrix a k-mean e ha fatto un cluster perfetto. Non hai passato il valore di k (numero di cluster) a k-mean?

3
@ user12023 Penso che tu abbia frainteso la domanda. La matrice non è una serie di punti: sono le distanze a coppie tra di loro. Non puoi calcolare il centroide di una raccolta di punti quando hai solo le distanze tra loro (e non le loro coordinate effettive), almeno non in modo ovvio.
Stumpy Joe Pete,

7
k-mean non supporta le matrici di distanza . Non usa mai distanze punto-punto. Quindi posso solo supporre che debba aver reinterpretato la tua matrice come vettori , ed eseguito su questi vettori ... forse lo stesso è accaduto per gli altri algoritmi che hai provato: si aspettavano dati grezzi e hai superato una matrice di distanza.
Anony-Mousse

Risposte:


38

Esistono diverse opzioni.

cluster di k-medoids

Innanzitutto, puoi provare a partizionare attorno ai medoidi (pam) invece di usare il clustering k-means. Questo è più robusto e potrebbe dare risultati migliori. Van der Laan ha rielaborato l'algoritmo. Se lo implementerai da solo, vale la pena leggere il suo articolo .

Esiste un algoritmo di clustering k-medoids specifico per set di dati di grandi dimensioni. L'algoritmo si chiama Clara in R ed è descritto nel capitolo 3 di Ricerca di gruppi di dati: un'introduzione all'analisi dei cluster. di Kaufman, L e Rousseeuw, PJ (1990).

clustering gerarchico

Invece di UPGMA, potresti provare alcune altre opzioni di clustering gerarchico. Prima di tutto, quando si utilizza il clustering gerarchico, assicurarsi di definire correttamente il metodo di partizionamento. Questo metodo di partizionamento è essenzialmente il modo in cui vengono calcolate le distanze tra osservazioni e cluster. Uso principalmente il metodo di Ward o il collegamento completo, ma altre opzioni potrebbero essere la scelta giusta per te.

Non so se l'hai ancora provato, ma il metodo di collegamento singolo o l'unione adiacente è spesso preferito al di sopra di UPGMA nelle applicazioni filogenetiche. Se non l'hai ancora provato, potresti anche provarci, dato che spesso dà risultati straordinariamente buoni.


In R puoi dare un'occhiata al cluster di pacchetti . Tutti gli algoritmi descritti sono implementati lì. Vedi? Pam,? Clara,? Hclust, ... Controlla anche la diversa implementazione dell'algoritmo in? Kmeans. Talvolta la scelta di un altro algoritmo può migliorare sostanzialmente il clustering.


EDIT: Ho pensato solo a qualcosa: se lavori con grafici, nodi e simili, dovresti dare un'occhiata anche all'algoritmo di clustering markov. Quello è usato ad esempio nel raggruppare sequenze basate su somiglianze esplosive e si comporta incredibilmente bene. Può fare il clustering per te o darti alcune idee su come risolvere il problema di ricerca su cui ti stai concentrando. Senza saperlo in effetti, immagino che valga la pena dare un'occhiata ai suoi risultati. Se così posso dire, considero ancora questo metodo di Stijn van Dongen uno dei migliori risultati nel clustering che io abbia mai incontrato.

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


22

Un modo per evidenziare i cluster sulla matrice della distanza è tramite il ridimensionamento multidimensionale . Quando si proiettano individui (qui come si chiamano i nodi) in uno spazio 2D, fornisce una soluzione comparabile a PCA. Questo è senza supervisione, quindi non sarai in grado di specificare a priori il numero di cluster, ma penso che possa aiutare a riassumere rapidamente una data distanza o matrice di somiglianza.

Ecco cosa otterresti con i tuoi dati:

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

Ho aggiunto un piccolo jitter sulle coordinate xey per consentire casi distinti. Sostituire tmpda 1-tmpse si preferisce di lavoro con differenze, ma essenzialmente questo rese la stessa immagine. Tuttavia, ecco la soluzione di clustering gerarchica, con criteri di agglomerazione singoli :

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

hc

Potresti perfezionare ulteriormente la selezione di cluster basati sul dendrogramma o su metodi più solidi, vedi ad esempio questa domanda correlata: quali criteri di arresto per il clustering gerarchico agglomerativo vengono utilizzati nella pratica?


2

K

L=D1/2AD1/2

ADAij=1dij/max(d)

{Di,i=jAi,jDij=0

Con come eigendecomposition di , con autofunzioni impilate come colonne, mantenendo solo i più grandi autovettori in , definiamo la matrice normalizzata di rigaL K XXLKX

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

Ogni riga di è un punto in e può essere raggruppata con un normale algoritmo di clustering (come K-medie).R kYRk

Guarda la mia risposta qui per vedere un esempio: https://stackoverflow.com/a/37933688/2874779


[1] Ng, AY, Jordan, MI, & Weiss, Y. (2002). Sul clustering spettrale: analisi e un algoritmo. Progressi nei sistemi di elaborazione delle informazioni neurali, 2, 849-856. pg.2


2

Quello che stai facendo è cercare di raggruppare nodi di un grafico o di una rete vicini l'uno all'altro. C'è un intero campo di ricerca dedicato a questo problema che a volte viene chiamato rilevamento della comunità nelle reti . Guardare il tuo problema da questo punto di vista può probabilmente chiarire le cose.

Troverai molti algoritmi dedicati a questo problema e in effetti alcuni di essi si basano sulla stessa idea che avevi, che è quella di misurare le distanze tra i nodi con passeggiate casuali.

Il problema è spesso formulato come ottimizzazione della modularità [1] in cui la modularità di un clustering misura in che modo il clustering separa la rete in cluster densamente connessi (ovvero cluster in cui i nodi sono vicini tra loro).

In realtà, puoi mostrare che la modularità è uguale alla probabilità che un deambulatore casuale rimanga, dopo un passo, negli stessi cluster rispetto a meno inizialmente la stessa probabilità per due deambulatori casuali indipendenti [2].

Se si consentono più passaggi dei camminatori casuali, si sta cercando un raggruppamento più grossolano della rete. Il numero di passaggi della camminata casuale svolge quindi il ruolo di un parametro di risoluzione che consente di ripristinare una gerarchia di cluster. In questo caso, la quantità che esprime la tendenza dei camminatori casuali a rimanere nel loro cluster iniziale dopo t passi è chiamata stabilità di Markov di una partizione al tempo t [2] ed è equivalente alla modularità quando t = 1 .

Puoi quindi risolvere il tuo problema trovando il raggruppamento del tuo grafico che ottimizza la stabilità in un dato momento t , dove t è il parametro di risoluzione ( t più grande ti darà cluster più grandi). Uno dei metodi più utilizzati per ottimizzare la stabilità (o la modularità con un parametro di risoluzione) è l' algoritmo di Louvain [3]. Puoi trovare un'implementazione qui: https://github.com/michaelschaub/generalizedLouvain .

[1] Newman, MEJ & Girvan, M. Trovare e valutare la struttura della comunità nelle reti. Phys. Rev. E 69, 026113 (2004).

[2] Delvenne, J.-C., Yaliraki, SN & Barahona, M. Stabilità delle comunità grafiche attraverso scale temporali. Proc. Natl. Acad. Sci. 107, 12755-12760 (2010).

[3] Blondel, VD, Guillaume, J.-L., Lambiotte, R. & Lefebvre, E. Rapido sviluppo delle comunità in grandi reti. J. Stat. Mech. Teoria Exp. 2008, P10008 (2008).


1

Bene, è possibile eseguire il clustering dei mezzi K su una data matrice di somiglianza, all'inizio è necessario centrare la matrice e quindi prendere gli autovalori della matrice. Il passaggio finale e più importante è la moltiplicazione delle prime due serie di autovettori per la radice quadrata delle diagonali degli autovalori per ottenere i vettori e poi procedere con K-medie. Sotto il codice mostra come farlo. Puoi cambiare la matrice di somiglianza. fpdist è la matrice di somiglianza.

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

Prima di provare a eseguire il clustering sulla matrice, puoi provare a eseguire una delle tecniche di analisi dei fattori e mantenere solo le variabili più importanti per calcolare la matrice della distanza. Un'altra cosa che puoi fare è provare a usare i metodi fuzzy che tendono a funzionare meglio (almeno nella mia esperienza) in questo tipo di casi, prova prima Cmeans, Fuzzy K-medoids e Specially GKCmeans.


0

Il co-clustering è una delle risposte che penso. Ma non sono esperto qui. Il co-clustring non è un metodo neonato, quindi puoi trovare alcuni algos in R, wiki mostra che i concetti sono in buone condizioni. Un altro metodo che non è menzionato è il partizionamento del grafico (ma vedo che il grafico non sarebbe scarso, il partizionamento del grafico sarebbe utile se la tua matrice fosse dominata da valori che significano = distanza massima = nessuna somiglianza tra i nodi).


0

Guarda PROPAGAZIONE AFFINITÀ, Questa tecnica prende come input la matrice di somiglianza e produce un numero ottimale di cluster insieme a un esempio rappresentativo per ciascun cluster.


2
Potresti approfondire questo e spiegare come questo metodo aiuta in questo caso?
Andy,


0

Puoi anche usare l'algoritmo Kruskal per trovare alberi di spanning minimi, ma terminare non appena ottieni i tre cluster. Ho provato in questo modo e produce i cluster che hai citato: {ABCD}, {EFGH} e {IJKL}.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.