聚类算法效果衡量标准及图片压缩案例
1.SSE:误差平方和
误差平方和:计算每个簇内的样本到该簇质心的距离平方,然后加和,然后把每个簇的距离平方和再相加,公式如下:
SSE比较
2. “肘”方法(Elbow method)
“肘”方法(Elbow method):
(1)对于n个点的数据集,迭代计算k from 1 to n,每次聚类完成后计算每个点到其所属的簇中心的距离的平方和;
(2)平方和是会逐渐变小的,直到k==n时平方和为0,因为每个点都是它所在的簇中心本身。
(3)在这个平方和变化过程中,会出现一个拐点也即“肘”点,下降率突然变缓时即认为是最佳的k值。
3. 轮廓系数法(Silhouette Coefficient)
结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。
- a是Xi与同簇的其他样本的平均距离,称为凝聚度(Cohesion);
- b是Xi与最近簇中所有样本的平均距离,称为分离度(Separation)。
最近簇的定义:
- p是某个簇Ck中的样本。即,用Xi到某个簇所有样本平均距离作为衡量该点到该簇的距离后,选择离Xi最近的一个簇作为最近簇。
- 求出所有样本的轮廓系数后再求平均值就得到了平均轮廓系数。
- 平均轮廓系数的取值范围为[-1,1],系数越大,聚类效果越好。
- 簇内样本的距离越近,簇间样本距离越远
4. Calinski-Harabasz Index
Calinski-Harabasz:类别内部数据的协方差越小越好,类别之间的协方差越大越好,这样的Calinski-Harabasz分数s会高,分数s高则聚类效果越好。
- m为训练集样本数,k为类别数,tr为矩阵的迹。
- Bk为类别之间的协方差矩阵,Wk为类别内部数据的协方差矩阵。
用尽量少的类别聚类尽量多的样本,同时获得较好的聚类效果。
总结
- 肘部法
下降率突然变缓时即认为是最佳的k值 - SC系数
取值为[-1, 1],其值越大越好 - CH系数
分数s高则聚类效果越好
代码案例3: 聚类算法的图片压缩实战应用
运用Kmeans算法实现图像压缩,并观察压缩后图像的变化
# 导包
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin
from sklearn.datasets import load_sample_image
from sklearn.utils import shuffle
from time import time
# 导入图片,设定参数
n_colors = 32
# 加载sklearn内部图片
china = load_sample_image("china.jpg")
# china
# 转换为浮点数,而不是默认的8位整数编码。为了使得plt.Imshow在浮点数数据上更好的显示(需要在[0-1]范围内)
china = np.array(china, dtype=np.float64) / 255
# 将图片由三维转化到二维
w, h, d = original_shape = tuple(china.shape)
assert d == 3
image_array = np.reshape(china, (w * h, d))
# 在小样本数据上拟合模型
t0 = time()
image_array_sample = shuffle(image_array, random_state=0)[:1000] # 打乱样本数据顺序(对应打乱)
kmeans = KMeans(n_clusters=n_colors, random_state=0).fit(image_array_sample)
print("done in %0.3fs." % (time() - t0))
#为所有点赋标签
t0 = time()
labels = kmeans.predict(image_array)
print("done in %0.3fs." % (time() - t0))
# 压缩聚类
def recreate_image(codebook, labels, w, h):
"""从code book和labels中重新创建(压缩)图像 """
d = codebook.shape[1]
image = np.zeros((w, h, d)) #生成三维数组,用0填充
label_idx = 0
for i in range(w):
for j in range(h):
image[i][j] = codebook[labels[label_idx]] # 每个像素点用聚类后的标签填充
label_idx += 1
return image
# 可视化
plt.figure(1)
plt.clf()
ax = plt.axes([0, 0, 1, 1])
plt.axis('off')
plt.title('原始图片 (96,615 colors)')
plt.imshow(china)
plt.figure(2)
plt.clf()
ax = plt.axes([0, 0, 1, 1])
plt.axis('off')
plt.title('聚类后的图片(32 colors, K-Means)')
plt.imshow(recreate_image(kmeans.cluster_centers_, labels, w, h))
聚类算法图像压缩原理(自总结):先将图片转化为二维ndarray,根据给定k值(n_colors = 32)应用聚类算法(Kmeans)进行聚类,给每个样本赋予聚类后的标签,用标签值和图片维度重新生成图片,达到压缩效果(用更少的颜色来表达图片)。