欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

机器学习笔记:python中scikit-learn库的K-Means类

程序员文章站 2022-07-14 19:28:58
...

K-Means类概述

在scikit-learn中,包括两个K-Means的算法,一个是传统的K-Means算法,对应的类是KMeans。另一个是基于采样的Mini Batch K-Means算法,对应的类是MiniBatchKMeans。一般来说,使用K-Means的算法调参是比较简单的。

用KMeans类的话,一般要注意的仅仅就是k值的选择,即参数n_clusters;如果是用MiniBatchKMeans的话,也仅仅多了需要注意调参的参数batch_size,即我们的Mini Batch的大小。

当然KMeans类和MiniBatchKMeans类可以选择的参数还有不少,但是大多不需要怎么去调参。下面我们就看看KMeans类和MiniBatchKMeans类的一些主要参数。

KMeans类主要参数

KMeans类的主要参数有:

1) n_clusters: 即我们的k值,一般需要多试一些值以获得较好的聚类效果。k值好坏的评估标准在下面会讲。

2)max_iter: 最大的迭代次数,一般如果是凸数据集的话可以不管这个值,如果数据集不是凸的,可能很难收敛,此时可以指定最大的迭代次数让算法可以及时退出循环。

3)n_init:用不同的初始化质心运行算法的次数。由于K-Means是结果受初始值影响的局部最优的迭代算法,因此需要多跑几次以选择一个较好的聚类效果,默认是10,一般不需要改。如果你的k值较大,则可以适当增大这个值。

4)init: 即初始值选择的方式,可以为完全随机选择’random’,优化过的’k-means++‘或者自己指定初始化的k个质心。一般建议使用默认的’k-means++’。

5)algorithm:有“auto”, “full” or “elkan”三种选择。“full"就是我们传统的K-Means算法, “elkan”是我们原理篇讲的elkan K-Means算法。默认的"auto"则会根据数据值是否是稀疏的,来决定如何选择"full"和“elkan”。一般数据是稠密的,那么就是 “elkan”,否则就是"full”。一般来说建议直接用默认的"auto"

MiniBatchKMeans类主要参数

MiniBatchKMeans类的主要参数比KMeans类稍多,主要有:

1) n_clusters: 即我们的k值,和KMeans类的n_clusters意义一样。

2)max_iter:最大的迭代次数, 和KMeans类的max_iter意义一样。

3)n_init:用不同的初始化质心运行算法的次数。这里和KMeans类意义稍有不同,KMeans类里的n_init是用同样的训练集数据来跑不同的初始化质心从而运行算法。而MiniBatchKMeans类的n_init则是每次用不一样的采样数据集来跑不同的初始化质心运行算法。

4)batch_size:即用来跑Mini Batch KMeans算法的采样集的大小,默认是100.如果发现数据集的类别较多或者噪音点较多,需要增加这个值以达到较好的聚类效果。

5)init: 即初始值选择的方式,和KMeans类的init意义一样。

6)init_size: 用来做质心初始值候选的样本个数,默认是batch_size的3倍,一般用默认值就可以了。

7)reassignment_ratio: 某个类别质心被重新赋值的最大次数比例,这个和max_iter一样是为了控制算法运行时间的。这个比例是占样本总数的比例,乘以样本总数就得到了每个类别质心可以重新赋值的次数。如果取值较高的话算法收敛时间可能会增加,尤其是那些暂时拥有样本数较少的质心。默认是0.01。如果数据量不是超大的话,比如1w以下,建议使用默认值。如果数据量超过1w,类别又比较多,可能需要适当减少这个比例值。具体要根据训练集来决定。

8)max_no_improvement:即连续多少个Mini Batch没有改善聚类效果的话,就停止算法, 和reassignment_ratio, max_iter一样是为了控制算法运行时间的。默认是10.一般用默认值就足够了。

K值的评估标准

不像监督学习的分类问题和回归问题,我们的无监督聚类没有样本输出,也就没有比较直接的聚类评估方法。但是我们可以从簇内的稠密程度和簇间的离散程度来评估聚类的效果。常见的方法有轮廓系数Silhouette Coefficient和Calinski-Harabasz Index。个人比较喜欢Calinski-Harabasz Index,这个计算简单直接,得到的Calinski-Harabasz分数值s越大则聚类效果越好。

Calinski-Harabasz分数值s的数学计算公式是:
机器学习笔记:python中scikit-learn库的K-Means类
其中m为训练集样本数,k为类别数。Bk为类别之间的协方差矩阵,Wk为类别内部数据的协方差矩阵。tr为矩阵的迹。

也就是说,类别内部数据的协方差越小越好,类别之间的协方差越大越好,这样的Calinski-Harabasz分数会高。在scikit-learn中, Calinski-Harabasz Index对应的方法是metrics.calinski_harabaz_score.

其他评估方法

K-Means应用实例

下面用一个实例来讲解用KMeans类和MiniBatchKMeans类来聚类。我们观察在不同的k值下Calinski-Harabasz分数。

from sklearn.cluster import KMeans
from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from mpl_toolkits.mplot3d import Axes3D

#建立三维的数据,用3个特征,样本数为1000,簇内中心:[[-1,-1,-1],[0,0,0],[1,1,1],[2,2,2],[4,4,4]] 簇内方差:[0.5,0.6,0.4,0.3,0.7]
#make_blobs() 用来生成的样本数据集。
data,label=make_blobs(n_samples=1000,n_features=3,centers=[[-1,-1,-1],[0,0,0],[1,1,1],[2,2,2],[4,4,4]],cluster_std=[0.5,0.6,0.4,0.3,0.7])#centers[[x,y,z]]代表中心点x,y,z轴坐标
fig=plt.figure(num='figure1',figsize=(6,8))
ax=Axes3D(fig)
ax.scatter(data[:,0],data[:,1],data[:,2],marker='o',cmap=plt.cm.Set1, edgecolor='k', s=40)
ax.set_title("original data")
plt.show()

数据集效果图如下:
机器学习笔记:python中scikit-learn库的K-Means类
用调用sklean中的Kmean类:

y_pred=KMeans(n_clusters=2).fit_predict(data)
fig2=plt.figure(num='figure2',figsize=(6,8))
ax2=Axes3D(fig2)
ax2.scatter(data[:,0],data[:,1],data[:,2],c=y_pred,marker='o', s=40)
ax2.set_title("Afther Kmeans")
plt.show()

当n_clusters=2时,
效果图:
机器学习笔记:python中scikit-learn库的K-Means类
评估:

score=metrics.calinski_harabaz_score(data, y_pred)#模型评估
print(score)

当n_clusters=2时,
score:1998.9405928157062

当n_clusters=3时,
score:3082.9043156698986

当n_clusters=4时,
score:3042.1419109849057

当n_clusters=5时,
score:2775.4532886290726

将数据集分成3簇、4簇,都有不错的效果。
机器学习笔记:python中scikit-learn库的K-Means类

MiniBatchKMeans类:
大家可以自己去运行一下MiniBatchKMeans类,效果也是挺不错的。

from sklearn.cluster import KMeans,MiniBatchKMeans
from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from mpl_toolkits.mplot3d import Axes3D
#分出3簇,每次抽取200个样本
y_pred = MiniBatchKMeans(n_clusters=3, batch_size=200).fit_predict(data)
score = metrics.calinski_harabaz_score(data, y_pred)
print(score)
fig3=plt.figure(num='figure3',figsize=(6,8))
ax3=Axes3D(fig3)
ax3.scatter(data[:,0],data[:,1],data[:,2],c=y_pred,marker='o', s=40)
ax3.set_title("Afther Kmeans")
plt.show()

参考资料:
用scikit-learn学习K-Means聚类:
https://www.cnblogs.com/pinard/p/6169370.html
官网sklearn.cluster.KMeans:
https://scikit-learn.org/0.17/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans