2015-09-07 20 views
5

Ciao StackOverflow comunità,Kmeans R (statistiche) vs Kmeans (AMAP)

Io corro Kmeans (pacchetto statistiche) e Kmeans (pacchetto AMAP) sul set di dati Iris. In entrambi i casi, utilizzo lo stesso algoritmo (Lloyd-Forgy), la stessa distanza (euclidea), lo stesso numero di serie casuali iniziali (50), lo stesso numero massimo di iterazioni (1000) e provo per lo stesso set di valori k (da 2 a 15). Io uso anche lo stesso seme per entrambi i casi (4358).

Non capisco perché in queste condizioni sto ottenendo curve wss diverse, in particolare: il "gomito" che usa il pacchetto stats è molto meno accentuato di quando si usa il pacchetto amap.

Potresti per favore aiutarmi a capire perché? Grazie mille!

Ecco il codice:

# data load and scaling 
newiris <- iris 
newiris$Species <- NULL 
newiris <- scale(newiris) 

# using kmeans (stats) 
wss1 <- (nrow(newiris)-1)*sum(apply(newiris,2,var)) 
for (i in 2:15) { 
    set.seed(4358) 
    wss1[i] <- sum(kmeans(newiris, centers=i, iter.max=1000, nstart=50, 
         algorithm="Lloyd")$withinss) 
    } 

# using Kmeans (amap) 
library(amap) 
wss2 <- (nrow(newiris)-1)*sum(apply(newiris,2,var)) 
for (i in 2:15) { 
    set.seed(4358) 
    wss2[i] <- sum(Kmeans(newiris, centers=i, iter.max=1000, nstart=50, 
         method="euclidean")$withinss) 
    } 

# plots 
plot(1:15, wss1, type="b", xlab="Number of Clusters", 
    ylab="Within groups sum of squares", main="kmeans (stats package)") 
plot(1:15, wss2, type="b", xlab="Number of Clusters", 
    ylab="Within groups sum of squares", main="Kmeans (amap package)") 

EDIT: ho inviato via email l'autore del pacchetto AMAP e pubblicherà la risposta, quando/se ottengo alcuna. https://cran.r-project.org/web/packages/amap/index.html

+0

se si vuole scavare ulteriormente, è possibile leggere il codice sorgente per ogni funzione, digitando semplicemente il nome della funzione e colpire entrare – pcantalupo

+0

possibile duplicato di http : //stackoverflow.com/questions/5696381/r-clustering-results-are-different-everytime-i-run – pcantalupo

+0

Grazie per i vostri commenti @pcantalupo. Sto leggendo il codice e cerco di capirlo. Per il possibile duplicato: grazie per il puntatore. Sto usando il seme come suggerito in quel post. La differenza che noto non è tra diverse esecuzioni della stessa funzione, ma tra le due diverse implementazioni (pacchetti di statistiche e mappe). Commento laterale: quando eseguo Kmeans (amap) con e senza 'set.seed (4358)' Ho ottenuto lo stesso risultato del grafico, che a mio parere è strano – pim

risposta

0

L'autore del pacchetto AMAP, cambiato il codice e il valore della variabile withinss è la somma applicata con il metodo (es. Distanza euclidea).

Un modo per risolvere questo problema, dato il ritorno della funzione Kmeans (amap), ricalcola il valore di withinss (Error Sum of Squares (SSE)).

Ecco la mia proposta:

# utilizzando Kmeans (AMAP)

library(amap) 

    wss2 <- (nrow(newiris)-1)*sum(apply(newiris,2,var)) 

    for (i in 2:15) { 

      set.seed(4358) 

      ans.Kmeans <- Kmeans(newiris, centers=i, iter.max=1000, nstart=50, method="euclidean") 

      wss <- vector(mode = "numeric", length=i) 

      for (j in 1:i) { 
        km = as.matrix(newiris[which(ans.Kmeans$cluster %in% j),]) 

        ## average = as.matrix(t(apply(km,2,mean))) 
        ## wss[j] = sum(apply(km, 1, function(x) sum((x-average)^2))) 
        ## or       
        wss[j] <- (nrow(km)-1) * sum(apply(km,2,var)) 
      } 

      wss2[i] = sum(wss) 
    } 

Nota. Il metodo per pearson in questo pacchetto è sbagliato (attenzione!) Sulla versione 0.8-14.

Linea 325 secondo il codice in questo link:

https://github.com/cran/amap/blob/master/src/distance_T.inl