6.1 K-means聚类
K-means 是一种将输入数据划分成k个簇的简单的聚类算法。K-means反复提炼初 始评估的类中心,步骤如下:
(1) 以随机或猜测的方式初始化类中心
;
(2) 将每个数据点归并到离它距离最近的类中心所属的类
;
(3) 对所有属于该类的数据点求平均,将平均值作为新的类中心;
(4) 重复步骤(2)和步骤(3)直到收敛。
K-means 试图使类内总方差最小:
是输入数据,并且是矢量。该算法是启发式提炼算法,在很多情形下都适用,但 是并不能保证得到最优的结果。为了避免初始化类中心时没选取好类中心初值所造 成的影响,该算法通常会初始化不同的类中心进行多次运算,然后选择方差V最小 的结果。
6.1.1 SciPy聚类包
SciPy矢量量化包 scipy.cluster.vq 中有 K-means 的实现,下面是使用方法。
from scipy.cluster.vq import *
import numpy as np
import matplotlib.pyplot as plt
class1 = 1.5 * np.random.randn(100,2)
class2 = np.random.randn(100,2) + np.array([5,5])
features = np.vstack((class1,class2))
centroids , variance = kmeans(features,2)
code, distance = vq(features,centroids)
plt.figure()
ndx = np.where(code == 0)[0]
plt.plot(features[ndx,0],features[ndx,1],'*')
ndx = np.where(code == 1)[0]
plt.plot(features[ndx,0],features[ndx,1],'r.')
plt.plot(centroids[:,0],centroids[:,1],'go')
plt.axis('off')
plt.show()
绘制出的结果如图所示。
6.1.2 图像聚类
利用之前计算过的前40个主 成分进行投影,用投影系数作为每幅图像的向量描述符。用pickle模块载入模型文 件,在主成分上对图像进行投影,然后用下面的方法聚类:
import imtools
import pickle
from scipy.cluster.vq import *
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 获取selected-fontimages 文件下图像文件名,并保存在列表中
imlist = imtools.get_imlist('selected_fontimages/')
imnbr = len(imlist)
# 载入模型文件
with open('a_pca_modes.pkl','rb') as f:
immean = pickle.load(f)
V = pickle.load(f)
# 创建矩阵,存储所有拉成一组形式后的图像
immatrix = np.array([np.array(Image.open(im)).flatten() for im in imlist],'f')
# 投影到前40个主成分上
immean = immean.flatten()
projected = np.array([np.dot(V[:40],immatrix[i]-immean) for i in range(imnbr)])
# 进行k-means 聚类
projected = whiten(projected)
centroids,distortion = kmeans(projected,4)
code,distance = vq(projected,centroids)
# 绘制聚类簇
for k in range(4):
ind = np.where(code==k)[0]
plt.figure()
plt.gray()
for i in range(np.minimum(len(ind),40)):
plt.subplot(4,10,i+1)
plt.imshow(immatrix[ind[i]].reshape((25,25)))
plt.axis('off')
plt.show()
实验效果:
6.1.3 在主成分上可视化图像
为了便于观察上面是如何利用主成分进行聚类的,我们可以在一对主成分方向的坐 标上可视化这些图像。一