To calculate the BIC for the kmeans results, I have tested the following methods:
- The following formula is from: [ref2]
The r code for above formula is:
k3 <- kmeans(mt,3)
intra.mean <- mean(k3$within)
k10 <- kmeans(mt,10)
centers <- k10$centers
BIC <- function(mt,cls,intra.mean,centers){
x.centers <- apply(centers,2,function(y){
as.numeric(y)[cls]
})
sum1 <- sum(((mt-x.centers)/intra.mean)**2)
sum1 + NCOL(mt)*length(unique(cls))*log(NROW(mt))
}
#
the problem is when i using the above r code, the calculated BIC was monotone increasing. what's the reason?
[ref2] Ramsey, S. A., et al. (2008). "Uncovering a macrophage transcriptional program by integrating evidence from motif scanning and expression dynamics." PLoS Comput Biol 4(3): e1000021.
2. I have used the new formula from https://stackoverflow.com/questions/15839774/how-to-calculate-bic-for-k-means-clustering-in-r
BIC2 <- function(fit){
m = ncol(fit$centers)
n = length(fit$cluster)
k = nrow(fit$centers)
D = fit$tot.withinss
return(data.frame(AIC = D + 2*m*k,
BIC = D + log(n)*m*k))
}
This method given the lowest BIC value at cluster number 155.
using @ttnphns provided method, the corresponding R code as listed below. However, the problem is what the difference between Vc and V? And how to calculate the element-wise multiplication for two vectors with different length?
BIC3 <- function(fit,mt){ Nc <- as.matrix(as.numeric(table(fit$cluster)),nc=1) Vc <- apply(mt,2,function(x){ tapply(x,fit$cluster,var) }) V <- matrix(rep(apply(mt,2,function(x){ var(x) }),length(Nc)),byrow=TRUE,nrow=length(Nc)) LL = -Nc * colSums( log(Vc + V)/2 ) ##how to calculate this? elementa-wise multiplication for two vectors with different length? BIC = -2 * rowSums(LL) + 2*K*P * log(NRoW(mt)) return(BIC) }