1.拐点法(选取斜率突变点)
构造自定义函数,用于绘制不同k值和对应总的簇内离差平方和的折线图
def k_SSE(X, clusters):
K = range(1,clusters+1)
TSSE = []
for k in K:
SSE = []
kmeans = KMeans(n_clusters=k)
kmeans.fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
for label in set(labels):
SSE.append(np.sum((X.loc[labels == label,]-centers[label,:])**2))
TSSE.append(np.sum(SSE))
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('ggplot')
plt.plot(K, TSSE, 'b*-')
plt.xlabel('簇的个数')
plt.ylabel('簇内离差平方和之和')
plt.show()
X = pd.DataFrame(np.concatenate([np.array([x1,y1]),np.array([x2,y2]),np.array([x3,y3])], axis = 1).T)
k_SSE(X, 15)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2c9547d4c27f3a645d126754cc3c6e47.png)
2.轮廓系数法(选取最高点)
def k_silhouette(X, clusters):
K = range(2,clusters+1)
S = []
for k in K:
kmeans = KMeans(n_clusters=k)
kmeans.fit(X)
labels = kmeans.labels_
S.append(metrics.silhouette_score(X, labels, metric='euclidean'))
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('ggplot')
plt.plot(K, S, 'b*-')
plt.xlabel('簇的个数')
plt.ylabel('轮廓系数')
plt.show()
k_silhouette(X, 15)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/39162e811d7882c20a9cde183b06fab4.png)
3.间隔统计量法(寻找正负突变点,不用指定取值范围)
def short_pair_wise_D(each_cluster):
mu = each_cluster.mean(axis = 0)
Dk = sum(sum((each_cluster - mu)**2)) * 2.0 * each_cluster.shape[0]
return Dk
def compute_Wk(data, classfication_result):
Wk = 0
label_set = set(classfication_result)
for label in label_set:
each_cluster = data[classfication_result == label, :]
Wk = Wk + short_pair_wise_D(each_cluster)/(2.0*each_cluster.shape[0])
return Wk
def gap_statistic(X, B=10, K=range(1,11), N_init = 10):
X = np.array(X)
shape = X.shape
tops = X.max(axis=0)
bots = X.min(axis=0)
dists = np.matrix(np.diag(tops-bots))
rands = np.random.random_sample(size=(B,shape[0],shape[1]))
for i in range(B):
rands[i,:,:] = rands[i,:,:]*dists+bots
gaps = np.zeros(len(K))
Wks = np.zeros(len(K))
Wkbs = np.zeros((len(K),B))
for idxk, k in enumerate(K):
k_means = KMeans(n_clusters=k)
k_means.fit(X)
classfication_result = k_means.labels_
Wks[idxk] = compute_Wk(X,classfication_result)
for i in range(B):
Xb = rands[i,:,:]
k_means.fit(Xb)
classfication_result_b = k_means.labels_
Wkbs[idxk,i] = compute_Wk(Xb,classfication_result_b)
gaps = (np.log(Wkbs)).mean(axis = 1) - np.log(Wks)
sd_ks = np.std(np.log(Wkbs), axis=1)
sk = sd_ks*np.sqrt(1+1.0/B)
gapDiff = gaps[:-1] - gaps[1:] + sk[1:]
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('ggplot')
plt.bar(np.arange(len(gapDiff))+1, gapDiff, color = 'steelblue')
plt.xlabel('簇的个数')
plt.ylabel('k的选择标准')
plt.show()
gap_statistic(X)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/95417123d7401b1d0ad4b9ffb968860b.png)