0

KModes クラスタリングを使用して作成したクラスターのシルエット係数を計算しようとしています (データ フィールドはすべてカテゴリカルであるため)。距離の尺度として一致する非類似度を使用しています。

def matching_disimilarity(a, b):
    return np.sum(a != b)

インターネット上で Python でそのような実装を見つけることができなかったので、ウィキペディアのドキュメント ( https://en.wikipedia.org/wiki/Silhouette_(clustering) )に従って自分で作成することにしました。これが私がこれまでに持っているものです。

def silhouette_analysis(df):
    n_clusters = 5
    sil = []

    for i, r_i in df.iterrows():
        c_i = r_i['cluster']
        r_i = r_i.drop('cluster', axis=0)
        same_cluster_df = df[df['cluster'] == c_i].reset_index(drop=True)
        other_clusters_df = df[df['cluster'] != c_i].reset_index(drop=True)

        a_i = 0
        for j, r_j in same_cluster_df.iterrows():
            r_j = r_j.drop('cluster', axis=0)
            d_ij = matching_disimilarity(r_i, r_j)
            a_i += d_ij
        a_i = a_i/(len(same_cluster_df) - 1)

        b_i = []
        b_in = 0
        for c_n in range(n_clusters):
            if c_i == c_n: continue
            nearest_cluster_df = other_clusters_df[other_clusters_df['cluster'] == c_n]
            for j, r_j in nearest_cluster_df.iterrows():
                r_j = r_j.drop('cluster', axis=0)
                d_ij = matching_disimilarity(r_i, r_j)
                b_in += d_ij
            b_in = b_in/len(nearest_cluster_df)
            b_i.append(b_in)
        b_i = min(b_i)

        if (a_i < b_i):
            s_i = 1 - (a_i/b_i)
        elif(a_i == b_i):
            s_i = 0
        else:
            s_i = b_i/a_i - 1

        sil.append(s_i)

    df['sil'] = sil
    return df

引数として渡すデータフレームdfには、列の各行に既にマップされているクラスターがありclusterます。

私が聞きたい3つの質問があります:

  1. 私のコードは正しいですか?クラスターの正しい評価が得られますか?
  2. これは現在、非常に遅いです。20,000 行近くあり、シルエット係数の計算に 2 分以上かかっています。単一行用。
  3. Silhouette coeff の既存の信頼できる Python 実装はありますか。距離尺度として一致する非類似度を使用する KModes クラスタリング用。
4

0 に答える 0