BICを使用してKMEANSのkの数を推定する


13

現在、おもちゃのデータセット(ofc iris(:))のBICを計算しようとしています。ここに示すように結果を再現したいです(図5)。

これには2つの問題があります。

  • 表記:
    • n =クラスターの要素数
    • C =クラスター中心座標
    • バツj =クラスター iに割り当てられたデータポイント
    • m =クラスターの数

1)式で定義された分散 (2):

=1nmj=1nバツjC2

私が見る限り、クラスター内の要素よりもクラスターmが多い場合、分散が負になる可能性があることは問題であり、カバーされません。これは正しいです?

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の私の結果は次のようになります。

これは私が期待していたものに近づいておらず、意味もありません...しばらくの間方程式を見て、間違いを見つけることはもうありません)


ここでクラスタリングのBICの計算を見つけることができます。SPSSが行う方法です。必ずしもあなたが示す方法とまったく同じではありません。
ttnphns 14年

ttnphnsありがとうございます。前にあなたの答えを見ました。しかし、それはステップがどのように導き出されるかについて言及していないので、私が探していたものではありません。さらに、このSPSS出力または構文が何であれ、非常に読みやすくありません。ともあれ、ありがとう。この質問には関心がないため、参照を探し、分散の別の推定値を使用します。
カムセン14

私はこれがあなたの質問に答えないことを知っています(したがって、コメントとして残します)が、Rパッケージmclustは有限混合モデルに適合し(パラメトリッククラスタリング手法)、クラスターの数、形状、サイズ、方向、および不均一性を自動的に最適化します。sklearnを使用していることを理解していますが、それをそこに放り出したかっただけです。
ブラッシュ平衡

1
Brash、sklearnにはGMMもあります
-eyaler

@KamSenここで私を助けてくれますか?: - stats.stackexchange.com/questions/342258/...
Pranay Wankhede

回答:


14

次のものと比較して判断すると、数式にいくつかのエラーがあるようです。

1。

np.sum([n[i] * np.log(n[i]) -
               n[i] * np.log(N) -
             ((n[i] * d) / 2) * np.log(2*np.pi) -
              (n[i] / 2) * np.log(cl_var[i]) -
             ((n[i] - m) / 2) for i in range(m)]) - const_term

論文には3つのエラーがあります。4行目と5行目にはdの係数がありません。最後の行は1をmに置き換えます。

np.sum([n[i] * np.log(n[i]) -
               n[i] * np.log(N) -
             ((n[i] * d) / 2) * np.log(2*np.pi*cl_var) -
             ((n[i] - 1) * d/ 2) for i in range(m)]) - const_term

2。

const_term:

const_term = 0.5 * m * np.log(N)

する必要があります:

const_term = 0.5 * m * np.log(N) * (d+1)

3。

分散式:

cl_var = [(1.0 / (n[i] - m)) * sum(distance.cdist(p[np.where(label_ == i)], [centers[0][i]], 'euclidean')**2)  for i in range(m)]

スカラーでなければなりません:

cl_var = (1.0 / (N - m) / d) * sum([sum(distance.cdist(p[np.where(labels == i)], [centers[0][i]], 'euclidean')**2) for i in range(m)])

4。

base10ログの代わりに自然ログを使用します。

5。

最後に、そして最も重要なことは、計算しているBICが通常の定義からの逆符号を持っていることです。最小化ではなく最大化を検討している


1
MKϕ2

@eyalerここで私を修正してもらえますか?: - stats.stackexchange.com/questions/342258/...
Pranay Wankhede

論文をリンクしたり、数学的なマークアップで書いたりできますか?
ドンラン

:PLはここに私の関連する質問を参照stats.stackexchange.com/questions/374002/...を
rnso

Seanny123とeyaler @ポストを参照してくださいstats.stackexchange.com/questions/374002/... rnsoからを。この式は、3つのクラスターが必要な虹彩データに約9のクラスターを与えています。
ベルナルドブラガ

11

これは基本的にeyalerのソリューションであり、いくつかのメモがあります。誰かがクイックコピー/貼り付けを希望する場合は、入力しました。

ノート:

  1. eyalers 4番目のコメントは正しくありませんnp.logはすでに自然なログであり、変更は不要です

  2. eyalers逆についての5番目のコメントは正しいです。以下のコードでは、最大値を探しています-この例には負のBIC番号があることに注意してください

コードは次のとおりです(これもすべてeyalerの功績です)。

from sklearn import cluster
from scipy.spatial import distance
import sklearn.datasets
from sklearn.preprocessing import StandardScaler
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 - m) / d) * sum([sum(distance.cdist(X[np.where(labels == i)], [centers[0][i]], 
             'euclidean')**2) for i in range(m)])

    const_term = 0.5 * m * np.log(N) * (d+1)

    BIC = np.sum([n[i] * np.log(n[i]) -
               n[i] * np.log(N) -
             ((n[i] * d) / 2) * np.log(2*np.pi*cl_var) -
             ((n[i] - 1) * d/ 2) for i in range(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]

print BIC

github.com/bobhancock/goxmeans/blob/master/doc/BIC_notes.pdfを見ると、このBIC式がMAXIMUMに対してどのように最適化されているのか説明できますか?ミニマムで見せて、それが何をするのかを言葉で説明してもらえますか?数式を解釈するのが難しいと判明
user305883

PLはここに私の関連する質問を参照してください。stats.stackexchange.com/questions/374002/...を
rnso

1
数式にバグがあるようです。誰かがそれを修正することができましたか?
STiGMa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.