教程 > SciPy 教程 > SciPy 教程 阅读:179

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)

运行示例

查看笔记

扫码一下
查看教程更方便