Saat ini saya mencoba menghitung BIC untuk kumpulan data mainan saya (ofc iris (:). Saya ingin mereproduksi hasil seperti yang ditunjukkan di sini (Gbr. 5). Makalah itu juga merupakan sumber saya untuk formula BIC.
Saya memiliki 2 masalah dengan ini:
- Notasi:
- = jumlah elemen dalam klaster
- = pusat koordinat cluster
- = titik data yang ditetapkan untuk cluster
- = jumlah cluster
1) Varians sebagaimana didefinisikan dalam Persamaan. (2):
Sejauh yang saya lihat itu bermasalah dan tidak tercakup bahwa varians bisa negatif ketika ada lebih banyak cluster daripada elemen dalam cluster. Apakah ini benar?
2) Saya tidak bisa membuat kode saya berfungsi untuk menghitung BIC yang benar. Semoga tidak ada kesalahan, tetapi akan sangat dihargai jika seseorang bisa memeriksanya. Seluruh persamaan dapat ditemukan dalam Persamaan. (5) di koran. Saya menggunakan scikit belajar untuk semuanya sekarang (untuk membenarkan kata kunci: 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")
Hasil saya untuk BIC terlihat seperti ini:
Yang bahkan tidak mendekati apa yang saya harapkan dan juga tidak masuk akal ... Saya melihat persamaan sekarang untuk beberapa waktu dan saya tidak mendapatkan lebih jauh menemukan kesalahan saya):
sumber
Jawaban:
Tampaknya Anda memiliki beberapa kesalahan dalam rumus Anda, sebagaimana ditentukan dengan membandingkan dengan:
1.
Di sini ada tiga kesalahan di koran, baris keempat dan kelima tidak ada faktor d, ganti baris terakhir m untuk 1. Seharusnya:
2.
Const_term:
seharusnya:
3.
Rumus varians:
harus berupa skalar:
4.
Gunakan log natural, bukan log base10 Anda.
5.
Akhirnya, dan yang paling penting, BIC yang Anda hitung memiliki tanda kebalikan dari definisi reguler. jadi Anda ingin memaksimalkan bukannya meminimalkan
sumber
Ini pada dasarnya adalah solusi eyeral, dengan beberapa catatan .. Saya baru saja mengetiknya jika seseorang menginginkan salinan / tempel cepat:
Catatan:
eyaler komentar ke-4 salah np.log sudah menjadi log natural, tidak diperlukan perubahan
eyaler komentar ke-5 tentang invers benar. Dalam kode di bawah ini, Anda mencari MAKSIMUM - ingat bahwa contohnya memiliki angka BIC negatif
Kode adalah sebagai berikut (sekali lagi, semua kredit ke eyaler):
sumber