简介
K-Means是最流行的聚类算法之一。通过对一个聚类的中心点,它根据其他点与该中心点的距离来分组。
K-Means的一个缺点是,在运行对点进行分组的算法之前,必须选择聚类的数量,即K。
如果你想阅读关于K-Means聚类的深入指南,请看"用Scikit-Learn进行K-Means聚类"。
肘部方法和剪影分析
最常用的选择K数的技术是肘部方法和剪影分析。
为了方便选择Ks,Yellowbrick库将代码中的for循环和我们通常要写的情节包装成4行代码。
要从Jupyter笔记本中直接安装Yellowbrick,请运行:
! pip install yellowbrick
让我们看看它在一个熟悉的数据集上是如何工作的,这个数据集已经是Scikit-learn的一部分,即Iris数据集。
第一步是导入数据集、KMeans 和yellowbrick 库,并加载数据:
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from yellowbrick.cluster import KElbowVisualizer, SilhouetteVisualizer
iris = load_iris()
yellowbrick.cluster注意这里,我们从KElbowVisualizer 和SilhouetteVisualizer ,这些都是我们要用来可视化Elbow和Silhouette结果的模块。
加载数据集后,在data 束的键(一种数据类型,是字典的扩展)中,是我们想要聚类的点的值。如果你想知道这些数字代表什么,可以看一下iris['feature_names'] 。
众所周知,鸢尾花数据集包含三种类型的鸢尾花:"versicolor"、"virginica "和 "setosa"。你也可以检查iris['target_names'] 中的类来验证。
因此,我们有4个特征需要聚类,根据我们已经知道的情况,它们应该被分成3个不同的聚类。让我们看看我们用肘部方法和剪影分析的结果是否能证实这一点。
首先,我们将选择特征值:
print(iris['feature_names']) # displays ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
print(iris['target_names']) # displays array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
X = iris['data']
然后,我们可以创建一个KMeans 模型,一个KElbowVisualizer() 实例,该实例将接收该模型以及将被计算的指标的K数,在这种情况下,从2到11Ks。
之后,我们用fit() ,用数据来拟合visualizer,用show() 来显示图。如果没有指定度量,visualizer会使用扭曲度量,计算每个点到其指定中心的距离平方之和:
model = KMeans(random_state=42)
elb_visualizer = KElbowVisualizer(model, k=(2,11))
elb_visualizer.fit(X)
elb_visualizer.show()

现在,我们已经有了一个K-Means聚类的失真分数肘部图,用一条垂直线标出了最佳的ks数,在这种情况下,4 。
看来,如果我们不知道实际的聚类数量,带有失真度量的肘部方法并不是最好的选择。Silhouette也会表明有4个集群吗?为了回答这个问题,我们只需要用一个有4个簇的模型和一个不同的可视化对象来重复上一段代码:
model_4clust = KMeans(n_clusters = 4, random_state=42)
sil_visualizer = SilhouetteVisualizer(model_4clust)
sil_visualizer.fit(X)
sil_visualizer.show()

这段代码显示了4个中心的150个样本的KMeans聚类的Silhouette图。为了分析这个聚类,我们需要看一下剪影系数(或分数)的值,它的最佳值是接近1。我们的平均值是0.5 ,用垂直线标记,不是那么好。
我们还需要看一下聚类之间的分布--一个好的图有相似大小的聚类区域或分布良好的点。在这个图中,有3个较小的聚类(数字3、2、1)和一个较大的聚类(数字0),这不是我们所期待的结果。
让我们对3个聚类重复同样的图,看看会发生什么。
model_3clust = KMeans(n_clusters = 3, random_state=42)
sil_visualizer = SilhouetteVisualizer(model_3clust)
sil_visualizer.fit(X)
sil_visualizer.show()

通过改变聚类的数量,剪影分数得到0.05 ,聚类更加平衡。如果我们不知道集群的实际数量,通过实验和结合两种技术,我们会选择3 ,而不是2 作为K的数量。
这就是一个例子,说明结合和比较不同的指标,将数据可视化,并试验不同的聚类值对于将结果引向正确的方向非常重要。还有,拥有一个便于分析的库可以在这个过程中提供帮助。