Actualmente estoy tratando de calcular el BIC para mi conjunto de datos de juguete (ofc iris (:). Quiero reproducir los resultados como se muestra aquí (Fig. 5). Ese documento también es mi fuente para las fórmulas de BIC.
Tengo 2 problemas con esto:
- Notación:
- = número de elementos en el clúster
- = coordenadas centrales del grupo
- = puntos de datos asignados al grupo
- = número de grupos
1) La varianza como se define en la ecuación. (2):
Hasta donde puedo ver, es problemático y no está cubierto que la varianza puede ser negativa cuando hay más grupos que elementos en el grupo. ¿Es esto correcto?
2) Simplemente no puedo hacer que mi código funcione para calcular el BIC correcto. Esperemos que no haya ningún error, pero sería muy apreciado si alguien pudiera verificarlo. Toda la ecuación se puede encontrar en la ecuación. (5) en el periódico. Estoy usando scikit learn para todo en este momento (para justificar la palabra clave: P).
from sklearn import cluster
from scipy.spatial import distance
import sklearn.datasets
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import numpy as np
def compute_bic(kmeans,X):
"""
Computes the BIC metric for a given clusters
Parameters:
-----------------------------------------
kmeans: List of clustering object from scikit learn
X : multidimension np array of data points
Returns:
-----------------------------------------
BIC value
"""
# assign centers and labels
centers = [kmeans.cluster_centers_]
labels = kmeans.labels_
#number of clusters
m = kmeans.n_clusters
# size of the clusters
n = np.bincount(labels)
#size of data set
N, d = X.shape
#compute variance for all clusters beforehand
cl_var = [(1.0 / (n[i] - m)) * sum(distance.cdist(X[np.where(labels == i)], [centers[0][i]], 'euclidean')**2) for i in xrange(m)]
const_term = 0.5 * m * np.log10(N)
BIC = np.sum([n[i] * np.log10(n[i]) -
n[i] * np.log10(N) -
((n[i] * d) / 2) * np.log10(2*np.pi) -
(n[i] / 2) * np.log10(cl_var[i]) -
((n[i] - m) / 2) for i in xrange(m)]) - const_term
return(BIC)
# IRIS DATA
iris = sklearn.datasets.load_iris()
X = iris.data[:, :4] # extract only the features
#Xs = StandardScaler().fit_transform(X)
Y = iris.target
ks = range(1,10)
# run 9 times kmeans and save each result in the KMeans object
KMeans = [cluster.KMeans(n_clusters = i, init="k-means++").fit(X) for i in ks]
# now run for each cluster the BIC computation
BIC = [compute_bic(kmeansi,X) for kmeansi in KMeans]
plt.plot(ks,BIC,'r-o')
plt.title("iris data (cluster vs BIC)")
plt.xlabel("# clusters")
plt.ylabel("# BIC")
Mis resultados para el BIC se ven así:
Lo cual ni siquiera está cerca de lo que esperaba y tampoco tiene sentido ... Miré las ecuaciones ahora por un tiempo y no encuentro más mi error):