本文应用软件为pycharm,通过sklearn库来实现k-means聚类,使用了3种确认K-means聚类簇数的方法,主要以应用为主,原理网上很多就不讲,代码实现会详细说明。
一、k-means实现方法
k-means首先需要用到sklearn库。
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters = i, init = 'k-means++', max_iter =300, n_init = 10, random_state = 0)
第一行是导入库
第二行的KMeans就是实现k-means聚类函数,这个函数里面的参数中。
n_clusters表示簇的数量(需要通过方法来确认的),
init表示使用的是‘k-means'选取初始簇中心,当然相关的还有“random"随机选择初始簇中心。
max_iter表示迭代次数,次数越高越容易收敛到最佳解,较低的会使效果不理想。
n_init表示初始中心的随机选择次数。
random _state是随机种子,保证每次运行结果一致。
二、通过簇内误差平方和确认k值(肘部法则)
import pandas as pd
dataset = pd.read_csv('k均值数据集.csv')
wcss,X = [],dataset.iloc[:,[3,4]].values # 选取数据集第4和第5列,作为特征矩阵x
kmeans.fit(X) # 对特征矩阵x进行拟合,只用于训练模型,不返回结果值
wcss.append(kmeans.inertia_) # 将当前簇数的簇内误差平方和添加到wcss中
这里对前面弄好的kmeans模型用fit函数训练,得到的就是簇内误差平方和。 可以写一个循环,比较簇数为不同情况时,簇内误差平方和变化,然后绘制折线图,当变化较平缓时,那么这个簇数就可以拿来当作模型的k值。也就是肘部法则。
for i in range (1,11): # 遍历1~10个簇数
kmeans = KMeans(n_clusters = i, init = 'k-means++', max_iter =300, n_init = 10, random_state = 0)
kmeans.fit(X)
wcss.append(kmeans.inertia_)
plt.plot(range(1,11),wcss)
plt.title('肘部法则')
plt.xlabel('簇的数量')
plt.ylabel('簇内误差平方和(SSE)')
plt.show()
可以看到在第五个簇数时,效果较好。
三、轮廓系数与Davies-Bouldin指数
这两个的话,轮廓系数是越高越好,Davies-Bouldin指数是越低越好。在python中,也有直接用来计算的函数,下面这个代码就是需要导入的函数。
from sklearn.metrics import silhouette_score, davies_bouldin_score
silhouette_score是轮廓系数的,davies_bouldin_score是Davies-Bouldin指数的。
## 轮廓系数
# 计算轮廓系数和Davies-Bouldin指数
silhouette_scores = []
davies_bouldin_scores = []
for i in range(2, 11):
kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)
y_kmeans = kmeans.fit_predict(X)
silhouette_scores.append(silhouette_score(X, y_kmeans))
davies_bouldin_scores.append(davies_bouldin_score(X, y_kmeans))
plt.subplot(1, 2, 1)
plt.plot(range(2, 11), silhouette_scores, marker='o')
plt.title('Silhouette Score Method')
plt.xlabel('Number of clusters')
plt.ylabel('Silhouette Score')
plt.subplot(1, 2, 2)
plt.plot(range(2, 11), davies_bouldin_scores, marker='o')
plt.title('Davies-Bouldin Index Method')
plt.xlabel('Number of clusters')
plt.ylabel('Davies-Bouldin Index')
plt.show()
也是差不多同样的方法,直接套用就好了。
绘制可视化结果如下。
可以看到,左边的轮廓系数到5时,和右边Davies-Bouldin指数到5时较好表现,与第一个簇内误差平方和得到的结论一样。因此可以选择5作为簇数。综合3种方法也会增加说服力。
然后再做k-means聚类,并绘制聚类图。
可以看出,簇数为5时,聚类效果较好。