K_means

导入数据

#分别导人numpy、matplot1ib以及pandas,用于数学运算、作图以及数据分析。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd 
#使用pandas分别读取训练数据与测试数据集。
digits_train = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra',
                           header= None)
digits_test = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tes',
                          header= None)

建立模型

K-means聚类模型所采用的迭代式算法,直观易懂并且非常实用,只是有两大缺陷:

  • 容易收敛到局部最优解
  • 需要预先设定簇的数量。
#从训练与测试数据集上都分离出64维度的像素特征与1维度的数字目标。
x_train = digits_train[np.arange (64)]
y_train = digits_train[64]
x_test = digits_test[np. arange (64)]
y_test = digits_test[64]
#从sklearn.cluster中导人KMeans模型。
from sklearn.cluster import KMeans
#初始化KMeans模型,并设置聚类中心数量为10。
kmeans = KMeans(n_clusters = 10)
kmeans.fit(x_train)
#逐条判断每个测试图像所属的聚类中心。
y_pred = kmeans.predict(x_test)

性能测评

标注类别的数据集上的时候,不同的数据特点,这里提供两种方式。

  • 如果被用来评估的数据本身带有正确的类别信息,那么就使用AdjustedRandIndex(ARI)。ARI指标与分类问题中计算准确性(Accuracy)的方法类似。
  • 如果被用于评估的数据没有所属类别,那么我们习惯使用轮廓系数(Silhouette Coefficient)来度量聚类结果的质量。轮廓系数同时兼顾了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果并且取值范围为[-1, 1]。轮廓系数值越大,表.示聚类效果越好。

使用ARI进行K-means聚类性能评估

#从sklearn导人度量函数库metrics.
from sklearn import metrics
#使用ARI进行KMeans聚类性能评估。
print(metrics.adjusted_rand_score(y_test, y_pred))
0.6625166948913885

利用轮廓系数评价不同类簇数量的K-means聚类实例

#导入numpy.
import numpy as np
#从sklearn.cluster中导人KMeans算法包。
from sklearn.cluster import KMeans
#从sklearn.metrics导人silhouette_ score 用于计算轮廓系数。
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
#分割出3* 2=6个子图,并在1号子图作图。
plt.subplot(3,2,1)
#初始化原始数据点。
x1 = np.array([1, 2, 3, 1, 5, 6, 5, 5, 6, 7, 8, 9, 7, 9])
x2 = np.array([1, 3, 2, 2, 8, 6,7, 6, 7, 1, 2, 1, 1,3])
x = np.array(list(zip(x1, x2))).reshape(len(x1), 2)
#在1号子图做出原始数据点阵的分布。
plt.xlim([0, 10])
plt.ylim([0, 10])
plt.title ('Instances')
plt.scatter(x1, x2)
colors=['b','g','r','c','m','y','k','b']
markers=['o','s','D','v','^','p','*', '+']
clusters=[2, 3, 4, 5, 8]
# clusters=range(0,70)
subplot_counter= 1
sc_scores= []
for t in clusters:
    subplot_counter += 1
    plt.subplot(3, 2, subplot_counter)
    kmeans_model = KMeans(n_clusters = t).fit(x)
    for i,l in enumerate(kmeans_model.labels_):
        plt.plot(x1[i], x2[i], color=colors[l], 
             marker= markers[l], ls= 'None')
        plt.xlim([0, 10])
        plt.ylim([0, 10]) 
    sc_score = silhouette_score(x, kmeans_model.labels_ , metric= 'euclidean')
    sc_scores.append(sc_score)
#绘制轮廓系数与不同类簇数量的直观显示图。
    plt.title('K=%s,silhouette coefficient=%0.03f'%(t, sc_score))
#绘制轮廓系数与不同类簇数量的关系曲线。
plt.figure ()
plt.plot (clusters, sc_scores,'*-')
plt.xlabel ('Number of Clusters')
plt.ylabel ('Silhouette Coefficient Score')
plt.show ()

在这里插入图片描述在这里插入图片描述

得出当聚类中心数量为3的时候,轮廓系数最大;此时,也可以观察到聚类中心数量为3也符合数据的分布特点,的确是相对较为合理的类簇数量。

利用“肘部”观察法粗略地预估类簇个数

#导人必要的工具包。
import numpy as np
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
import matplotlib.pyplot as plt
#使用均匀分布函数随机三个簇,每个簇周围10个数据样本。
clusterl = np.random. uniform(0.5, 1.5, (2, 10))
cluster2 = np.random.uniform(5.5, 6.5, (2, 10))
cluster3 = np.random.uniform(3.0, 4.0, (2, 10))
#绘制30个数据样本的分布图像。
x = np.hstack( (clusterl, cluster2, cluster3)).T
plt.scatter(x[:,0], x[:, 1])
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()

#测试9种不同聚类中心数量下,每种情况的聚类质量,并作图。
K = range(1, 10)
meandistortions = []
for k in K:
    kmeans = KMeans (n_clusters=k)
    kmeans.fit(x)
    meandistortions.append(sum(np.min(cdist(x,kmeans.cluster_centers_
                                            ,'euclidean'), axis=1)) /x.shape[0])
plt.plot(K, meandistortions, 'bo-')
plt.xlabel('k')
plt.ylabel('Average Dispersion')
plt.title('Selecting k with the Elbow Method')
plt.show ()

在这里插入图片描述在这里插入图片描述

分析:类簇数量为1或2的时候,样本距所属类簇的平均距离的下降速度很快,这说明更改K值会让整体聚类结构有很大改变,也意味着新的聚类数量让算法有更大的收敛空间,这样的K值不能反映真实的类簇数量。而当K=3时,平均距离的下降速度有了显著放缓,这意味着进一步增加K值不再会有利于算法的收敛,也同时暗示着K=3是相对最佳的类簇数量。

发布了58 篇原创文章 · 获赞 77 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/weixin_41503009/article/details/104409014