Tôi hiện đang cố gắng tính BIC cho bộ dữ liệu đồ chơi của mình (ofc iris (:). Tôi muốn sao chép các kết quả như được hiển thị ở đây (Hình 5). Bài báo đó cũng là nguồn của tôi cho các công thức BIC.
Tôi có 2 vấn đề với điều này:
- Ký hiệu:
- = số phần tử trong cụm
- = tọa độ trung tâm của cụm
- = điểm dữ liệu được gán cho cụm
- = số cụm
1) Phương sai như được định nghĩa trong biểu thức. (2):
Theo như tôi có thể thấy nó có vấn đề và không được đề cập rằng phương sai có thể âm khi có nhiều cụm hơn các phần tử trong cụm. Điều này có đúng không?
2) Tôi chỉ không thể làm cho mã của mình hoạt động để tính BIC chính xác. Hy vọng không có lỗi, nhưng nó sẽ được đánh giá cao nếu ai đó có thể kiểm tra. Toàn bộ phương trình có thể được tìm thấy trong phương trình. (5) trong bài báo. Tôi đang sử dụng scikit learn cho mọi thứ ngay bây giờ (để biện minh cho từ khóa: 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")
Kết quả của tôi cho BIC trông như thế này:
Điều này thậm chí không gần với những gì tôi đã mong đợi và cũng không có ý nghĩa gì cả ... Tôi đã xem xét các phương trình bây giờ và không nhận được bất kỳ sai lầm nào nữa):