我目前正在尝试为我的玩具数据集(ofc iris (: ))计算 BIC。我想重现结果,如图所示(图 5)。那篇论文也是我 BIC 公式的来源。
我有两个问题:
- 符号:
- 中的元素数
- 的中心坐标
- = 分配给集群
- = 聚类数
1) 方程式中定义的方差。(2):
多于集群中的元素时,方差可能为负是有问题的,并且没有涵盖。它是否正确?
2) 我只是无法让我的代码工作来计算正确的 BIC。希望没有错误,但如果有人可以检查,将不胜感激。整个方程可以在方程中找到。(5) 在论文中。我现在正在使用 scikit learn 进行所有操作(以证明关键字 :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")
我的 BIC 结果如下所示:
这甚至不符合我的预期,也没有任何意义......我现在看了一段时间的方程式,并没有进一步定位我的错误):