2013-04-05 9 views
18

Ho usato k-means per raggruppare i miei dati in R ma mi piacerebbe essere in grado di valutare la complessità del modello rispetto al modello del mio clustering usando Baysiean Information Criterio (BIC) e AIC. Attualmente il codice che ho usato in R è:Come calcolare BIC per k-means clustering in R

KClData <- kmeans(Data, centers=2, nstart= 100) 

Ma mi piacerebbe essere in grado di estrarre il BIC e Log verosimiglianza. Qualsiasi aiuto sarebbe molto apprezzato!

+1

La funzione 'Mclust' nel pacchetto mclust potrebbe essere di interesse. – Roland

+0

Roland, grazie per il suggerimento! In realtà sto cercando di confrontare i risultati di k-means con gli output di Mclust, ed è per questo che mi piacerebbe usare il BIC dal mio k-means clustering a GMM usato da Mclust. – UnivStudent

+3

Non sono un esperto, ma penso che k-means non sia un algoritmo di massima verosimiglianza. Sei sicuro che AIC e BIC siano applicabili? – Roland

risposta

13

Per chiunque altro sbarca qui, c'è un metodo proposto da Sherry Towers allo http://sherrytowers.com/2013/10/24/k-means-clustering/, che utilizza l'output da stats::kmeans. Cito:

L'AIC può essere calcolato con la seguente funzione:

kmeansAIC = function(fit){ 

m = ncol(fit$centers) 
n = length(fit$cluster) 
k = nrow(fit$centers) 
D = fit$tot.withinss 
return(D + 2*m*k) 
} 

Dalla aiuto per stats::AIC, si può anche vedere che il BIC può essere calcolato in modo simile a quello AIC. Un modo semplice per ottenere il BIC è quello di sostituire il return() nella funzione di cui sopra, con questo:

return(data.frame(AIC = D + 2*m*k, 
        BIC = D + log(n)*m*k)) 

Così si può usare questa come segue:

fit <- kmeans(x = data,centers = 6) 
kmeansAIC(fit) 
+0

Ho usato i tuoi metodi, ma il valore BIC dei kmea risulta sempre monotono diminuendo con l'aumento del numero di cluster. Per favore guarda i post: http://stats.stackexchange.com/questions/55147/k-means-bic-to-validate-clusters-in-r/183097#183097 – pengchy

+1

Prendendo una ipotesi selvaggia, direi che c'è un errore da qualche parte. –

+0

Grazie a qualsiasi Clifton, ho testato il BIC con un numero K più alto, quando K raggiunge 155 il BIC ha il valore più basso. In origine, ho provato solo il K con un massimo di 50. – pengchy

6

Per calcolare BIC, è sufficiente aggiungere .5*k*d*log(n) (dove k è il numero di mezzi, d è la lunghezza di un vettore nel set di dati, e n è il numero di punti di dati) per la funzione di errore k-mezzi standard.

La penalità k-means standard è \sum_n (m_k(n)-x_n)^2, dove m_k(n) è la media associata all'ennesimo punto dati. Questa penalità può essere interpretata come una probabilità di log come, quindi BIC è perfettamente valido.

BIC aggiunge semplicemente un termine di penalità aggiuntivo all'errore k-significa proporzionale a k.

+0

I non pensare che la penalità k-means '\ sum_n (m_k (n) - x_n)^2' (o il negativo di quello) sia la log-verosimiglianza. La log-likelihood dovrebbe avere altri 3 termini: '-n * log (K)', '-0.5 * n * d * log (2 * pi)' e '-n * d * log (\ sigma)', dove \ sigma è lo standard comune per tutti i gaussiani. Inoltre, la "k" nella formula BIC non è il numero di cluster, è il numero di parametri liberi nel modello gaussiano della miscela, quindi k dovrebbe essere: 'k = K-1 + 1 + K * d = K * (d + 1) '. Qui sto usando lower k per il termine del parametro BIC, e il capitale K come numero di mezzi/cluster. – Jason

+0

'K-1' è il numero K-1 di pesi per i gaussiani, poiché i pesi si sommano a 1, il dof è K-1. '1' per quello std comune per tutti i gaussiani. E 'K * d' è il numero di parametri per le coordinate dei centri del cluster. – Jason

+0

Ci sono pesi in k-means? Penso di no. Allora, perché abbiamo bisogno di K-1? – user5054

3

Solo per aggiungere a ciò che utente1149913 ha detto (non ho abbastanza reputazione per commentare), dal momento che si sta utilizzando la funzione kmea in R, \sum_n (m_k(n)-x_n)^2 è già calcolato per voi come KClData$tot.withinss.

2

Invece di reimplementare AIC o BIC, abbiamo può definire una funzione log-verosimiglianza per gli oggetti kmeans; questo verrà quindi utilizzato dalla funzione BIC nel pacchetto stats.

logLik.kmeans <- function(object) structure(
    -object$tot.withinss/2, 
    df = nrow(object$centers)*ncol(object$centers), 
    nobs = length(object$cluster) 
) 

Poi per usarlo, lo chiamano BIC come normale. Ad esempio:

example(kmeans, local=FALSE) 
BIC(cl) 
# [1] 26.22842084 

Questo metodo sarà fornita nel successivo rilascio del pacchetto stackoverflow.

+0

In attesa della nuova versione di StackOverflow, la versione corrente 0.1.2 non ha implementato questa funzione. – pengchy

+0

@pengchy la versione github ce l'ha, io lo invio a cran quando ne ho la possibilità. –

+1

sei segno invertito. Hai bisogno di un segno meno. – EngrStudent