SciPy Cluster 聚类
K-means 聚类是一种在一组未标记数据中寻找聚类和聚类中心的方法。直观地说,我们可以认为聚簇是由一组数据点组成的,与到聚类外部点的距离相比,这些数据点之间的距离很小。
给定一组K个中心,K-means算法迭代以下两个步骤
- 对于每一个中心点,与其他任何中心相比,更靠近它的训练子集点(其聚类)被识别
- 计算每个聚类中数据点的每个特征的均值,并且该均值向量成为该聚类的新中心。
重复这两个步骤,直到中心不再移动或分配不再改变。然后,可以将一个新点 x 分配给最近原型的聚类。SciPy 库的 cluster 包提供了良好的 K-Means 算法。接下来让我们看一下如何使用它。
SciPy 中的 K-Means 实现
我们将了解如何在 SciPy 中实现 K-Means。
导入 K 均值
我们将看到每个导入函数的实现和用法。
from SciPy.cluster.vq import kmeans,vq,whiten
数据生成
我们必须模拟一些数据来探索聚类。
from numpy import vstack,array
from numpy.random import rand
# 生成具有三个特性的数据
data = vstack((rand(100,3) + array([.5,.5,.5]),rand(100,3)))
print(data)
现在,我们必须检查数据。上述程序生成的数据如下。
[[ 0.50873083 1.02878655 0.69055683]
[ 0.88566368 1.22214578 0.97740513]
[ 1.24178071 0.60736959 0.55033043]
[ 0.90010454 1.48542369 0.71342669]
[ 1.20503944 0.88827521 0.76215377]
[ 0.76582151 0.6549201 1.00574503]
[ 0.82264536 1.01361857 0.94858096]
[ 1.39456286 0.55220939 1.33500485]
[ 1.30633392 1.33061089 1.27435441]
[ 0.94173932 0.80079924 1.402304 ]
[ 1.17097576 1.46344904 0.63345985]
[ 1.17553564 1.12188846 0.58447945]
[ 0.83955871 0.95589153 0.81186137]
[ 0.93110285 0.55495583 1.49888295]
[ 1.33432523 1.11254108 0.85029435]
[ 0.89618336 1.25775843 0.70894759]
...
]
在每个特征的基础上对一组观察进行归一化。在运行 K-Means 之前,用白化方法重新调整观察集的每个特征维度是有很有帮助的。每个特征除以它在所有观测值中的标准差,得到单位方差。
白化数据
我们必须使用以下代码来白化数据。
from numpy import vstack,array
from numpy.random import rand
from scipy.cluster.vq import kmeans,vq,whiten
# 生成具有三个特性的数据
data = vstack((rand(100,3) + array([.5,.5,.5]),rand(100,3)))
# 白化数据
data = whiten(data)
数据白化(whitening)是把一组随机变量转化成协方差为单位阵的一组随机变量的过程。
协方差矩阵是单位阵表面随机变量之间相关性为0,并且每一个随机变量的方差都是1。经过这个操作之后每一个随机变量都像是白噪音。所以这个操作叫做白化。
白化的目的就是降低输入的冗余性。
用三个聚类计算 K 均值
现在让我们使用以下代码计算具有三个聚类的 K-Means。
# 设置 K = 3 (2 clusters) 计算 K-Means
centroids,_ = kmeans(data,3)
上面的代码对形成 K 个聚类的一组观察向量执行 K-Means算法。K-Means 算法调整质心直到不能再进行下一步调整,即失真的变化,因为最后一次迭代小于某个阈值。在这里,我们可以通过使用下面给出的代码打印 centroids 变量来观察聚类的质心。
print(centroids)
上面的代码执行结果如下。
[[1.51683645 2.09438728 1.0546252 ]
[1.14163895 0.65947158 1.5506293 ]
[2.77063336 2.58370975 2.71759576]]
使用下面给出的代码将每个值分配给一个聚类。
# 将每个值分配给一个聚类
clx,_ = vq(data,centroids)
vq函数将“M”乘以“N”的obs阵列中的每个观测向量与质心进行比较,并将观测分配给最近的聚类。它返回每个观测值的聚类和失真。我们也可以检查失真。让我们使用以下代码检查每个观察的聚类。
# 检查每个观察的聚类
print(clx)
上面的代码输出如下。
[1 1 1 2 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 2 1 2 2 1 1 1 1 1 1 1 1
1 1 2 1 2 2 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 2 1
1 1 1 1 1 1 1 2 1 1 2 1 1 1 1 1 1 1 2 2 1 1 1 1 1 1 0 0 2 2 2 2 0 0 0 2 2
2 2 0 0 2 0 2 2 2 2 0 0 0 0 0 2 0 0 2 2 0 0 2 0 2 0 0 2 2 0 0 2 0 0 0 0 2
2 2 0 2 0 2 0 0 2 0 2 0 2 0 0 0 2 0 0 0 2 0 0 0 1 2 2 2 0 2 2 2 0 0 0 0 0
2 0 2 2 0 2 2 2 0 2 0 2 2 0 0]
上述数组的不同值 0、1、2 表示不同的聚类。
完整代码如下
from numpy import vstack,array
from numpy.random import rand
from scipy.cluster.vq import kmeans,vq,whiten
data = vstack((rand(100,3) + array([.5,.5,.5]),rand(100,3)))
data = whiten(data)
# 设置 K = 3 (2 clusters) 计算 K-Means
centroids,_ = kmeans(data,3)
# 将每个值分配给一个聚类
clx,_ = vq(data,centroids)
print(clx)