K-means聚类算法
1.聚类概念
聚类属于无监督学习(无类别标签)。聚类就是相似的东西分到一组。
2.K-means基本概念
要得到簇的个数,需要指定K值。
质心:均值,即向量各维取平均即可。
距离的度量:常用欧几里得距离和余弦相似度(先标准化)
优化目标:
min
∑
i
=
1
K
∑
x
∈
C
i
d
i
s
t
(
C
i
,
x
)
2
\min {{\sum\limits_{i=1}^{K}{\sum\limits_{x\in {{C}_{i}}}{dist\left( {{C}_{i}},x \right)}}}^{2}}
mini=1∑Kx∈Ci∑dist(Ci,x)2其中
C
i
{{C}_{i}}
Ci表示簇。
3. K-means 算法
(1)Clustering 中的经典算法,数据挖掘十大经典算法之一。
(2)算法接受参数 k ;然后将事先输入的n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。
(3)算法思想:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
(4)算法描述
①适当选择k个类的初始中心;
②在第i次迭代中,对任意一个样本,求其到各个中心的距离,将该样本归到距离最短的中心所在的类;
③利用均值等方法更新该类的中心值;
④对于所有的k个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。
(5)算法流程
输入:k, data[n];
① 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1];
② 对于data[0]….data[n], 分别与c[0]…c[k-1]比较,假定与c[i]差值最少,就标记为i;
③ 对于所有标记为i点,重新计算c[i]={ 所有标记为i的data[j]之和}/标记为i的个
数;
④ 重复(2)(3),直到所有c[i]值的变化小于给定阈值。
4.优劣势
(1)优势
简单,快速,适合常规数据集。
(2)劣势
K值难确定;复杂度与样本呈线性关系;很难发现任意形状的簇;最终结果跟初始点选择相关;容易陷入局部最优。
5.利用K-means进行图像压缩
在图像压缩问题中,K均值聚类算法会把类似的颜色分别放在K个簇中——也就是说,每个簇的颜色都变成了一种。因此,我们只需要保留每个像素的标签(表明该像素在哪个簇中),以及每个簇的颜色编码即可完成图像的压缩。
(1)原始图片展示
from sklearn.cluster import KMeans
from skimage import io
import numpy as np
image = io.imread('test2.jpg')
io.imshow(image)
io.show()
# shape[0]:行,shape[1]:列,shape[2]:channel,图片通道数,1:表示黑白色,3:表示彩色(rgb)
image.shape
输出结果:(154, 160, 3)
(2)进行压缩处理
rows = image.shape[0]
cols = image.shape[1]
# image[0,0,:]:表示在第一个像素点的位置上的rgb取值,位置(0,0),reshape之后呢,位置变成(0)
image = image.reshape(rows*cols,3)
# n_init:每一次算法运行时开始的centroid seeds是随机生成的,
# 这样得到的结果也可能有好有坏. 所以要运行算法n_init次, 取其中最好的(时间最短的).
kmeans = KMeans(n_clusters=128,n_init=10,max_iter=200)
kmeans.fit(image)
clusters = np.asarray(kmeans.cluster_centers_,dtype=np.uint8)
labels = np.asarray(kmeans.labels_,dtype=np.uint8)
labels = labels.reshape(rows,cols)
print(clusters.shape)
np.save('codebook_test.npy',clusters)
io.imsave('compressed_test.jpg',labels)
输出结果:(128, 3)
(3)显示压缩后的图片
image = io.imread('compressed_test.jpg')
io.imshow(image)
io.show()