Calinski-Harabaz指数(Calinski-Harabasz Index,简称CH指数)是一种用于评估聚类算法性能的内部有效性指标,特别适用于K均值聚类等基于划分的聚类方法,该指数通过计算各类中心点与数据集全局中心点之间的欧氏距离来衡量数据集的离散程度。具体而言,CH指数由类间分离度与类内紧密度的比值计算得出。因此,CH指数值越大,表明聚类结果中类内样本越紧密,类间分离越明显,即聚类效果越理想。
公式如下:
$$
\mathrm{s(k)=}\ \ \frac{\mathrm{tr(A)m-k}\ }{\mathrm{tr(B)k-1}}\
$$
\mathrm{s(k)=}\ \ \frac{\mathrm{tr(A)m-k}\ }{\mathrm{tr(B)k-1}}\
$$
其中,m为样本数量,k为设定的聚类数,A为类与类之间的协方差,B为类内部的协方差,tr为求矩阵的迹。总的来说就是总体协方差比内部协方差。简单来说就是CH指数越大,类与类之间的差别越明显,模型的聚类效果越好。
当然,该方法存在缺点:需要预先指定簇数,也就是上文中提到的K值,需要预先给定,因此需要预先尝试多个簇数
python下调用sklearn和numpy
实现如下
from sklearn.utils import check_X_y
from sklearn.preprocessing import LabelEncoder
import numpy as np
def calinski_harabaz(X, labels):
#计算CH指数
X, labels = check_X_y(X, labels)
#print(X.shape)
le = LabelEncoder()
labels = le.fit_transform(labels)
n_samples, _ = X.shape
n_labels = len(le.classes_)
extra_disp, intra_disp = 0., 0.
mean = np.mean(X, axis=0)
for k in range(n_labels):
cluster_k = X[labels == k]
mean_k = np.mean(cluster_k, axis=0)
extra_disp += len(cluster_k) * np.sum((mean_k - mean) ** 2)
intra_disp += np.sum((cluster_k - mean_k) ** 2)
return (1. if intra_disp == 0. else
extra_disp * (n_samples - n_labels) /
(intra_disp * (n_labels - 1.)))
print