聚类算法用于降维,KMeans的矢量量化应用
重要属性:
重要接口:
案例
矢量量化的降维是在同等样本量上压缩信息的大小,即不改变特征的数目也不改变样本的数目,只改变在这些特征下的样本上的信息量。
用K-Means聚类中获得的质心来替代原有的数据,可以把数据上的信息量压缩到非常小,但又不损失太多信息。我们接下来就通过一张图图片的矢量量化来看一看K-Means如何实现压缩数据大小,却不损失太多信息量。
1、导入需要的库
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
2、导入数据,探索数据
导入数据:
china = load_sample_image("china.jpg")
china
查看数据:
china.dtypechina.shape
china[0][0]
newimage = china.reshape((427 * 640,3))
newimage.shape
数据去重:
import pandas as pd
pd.DataFrame(newimage).drop_duplicates().shape
图像可视化:
plt.figure(figsize=(15,15))
plt.imshow(china)
导入另一张图片:
flower = load_sample_image("flower.jpg")
plt.figure(figsize=(15,15))
plt.imshow(flower)
图像探索完毕,我们了解了,图像现在有9W多种颜色。我们希望来试试看,能否使用K-Means将颜色压缩到64种,还不严重损耗图像的质量。为此,我们要使用K-Means来将9W种颜色聚类成64类,然后使用64个簇的质心来替代全部的9W种颜色,记得质心有着这样的性质:簇中的点都是离质心最近的样本点。
为了比较,我们还要画出随机压缩到64种颜色的矢量量化图像。我们需要随机选取64个样本点作为随机质心,计算原数据中每个样本到它们的距离来找出离每个样本最近的随机质心,然后用每个样本所对应的随机质心来替换原本的样本。两种状况下,我们观察图像可视化之后的状况,以查看图片信息的损失。
3、决定超参数,数据预处理
将数据维度数量保存,并将数据降维:
n_clusters = 64china = np.array(china, dtype=np.float64) / china.max()
w, h, d = original_shape = tuple(china.shape)
assert d == 3
image_array = np.reshape(china, (w * h, d))
china = np.array(china, dtype=np.float64) / china.max()
(china < 0).sum()
解释上述中的命令含义&#xff1a;
w, h, d &#61; original_shape &#61; tuple(china.shape)
assert d &#61;&#61; 3
image_array &#61; np.reshape(china, (w * h, d))
image_array
reshape&#xff1a;
a &#61; np.random.random((2,4))
a.shape
a.reshape((4,2)) &#61;&#61; np.reshape(a,(4,2))
np.reshape(a,(8,1))
4、对数据进行K-Means的矢量量化
找出质心&#xff1a;
image_array_sample &#61; shuffle(image_array, random_state&#61;0)[:1000]
kmeans &#61; KMeans(n_clusters&#61;n_clusters, random_state&#61;0).fit(image_array_sample)kmeans.cluster_centers_.shape
对数据进行聚类&#xff1a;
labels &#61; kmeans.predict(image_array)
labels.shape
set(labels)
用质心替换样本&#xff1a;
image_kmeans &#61; image_array.copy()image_kmeans labels kmeans.cluster_centers_[labels[0]]for i in range(w*h):image_kmeans[i] &#61; kmeans.cluster_centers_[labels[i]]
image_kmeans.shapepd.DataFrame(image_kmeans).drop_duplicates().shape
恢复图片结构&#xff1a;
image_kmeans &#61; image_kmeans.reshape(w,h,d)
image_kmeans.shape
5、对数据进行随机的矢量量化
centroid_random &#61; shuffle(image_array, random_state&#61;0)[:n_clusters]
centroid_random.shapelabels_random &#61; pairwise_distances_argmin(centroid_random,image_array,axis&#61;0)
labels_random.shape
使用随机数质心替换样本&#xff1a;
image_random &#61; image_array.copy()for i in range(w*h):image_random[i] &#61; centroid_random[labels_random[i]]
恢复结构&#xff1a;
image_random &#61; image_random.reshape(w,h,d)
image_random.shape
6、将原图&#xff0c;按KMeans矢量量化和随机矢量量化的图像绘制出来
plt.figure(figsize&#61;(10,10))
plt.axis(&#39;off&#39;)
plt.title(&#39;Original image (96,615 colors)&#39;)
plt.imshow(china)plt.figure(figsize&#61;(10,10))
plt.axis(&#39;off&#39;)
plt.title(&#39;Quantized image (64 colors, K-Means)&#39;)
plt.imshow(image_kmeans)plt.figure(figsize&#61;(10,10))
plt.axis(&#39;off&#39;)
plt.title(&#39;Quantized image (64 colors, Random)&#39;)
plt.imshow(image_random)
plt.show()
可以发现&#xff0c;用聚类的时候是楼有颜色&#xff0c;天空比较像素低&#xff0c;用随机质心的时候楼颜色比较暗淡&#xff0c;整体来看&#xff0c;还是看着聚类的时候区别不是很大。
单独对比&#xff1a;
原图与聚类&#xff1a;
原图与随机&#xff1a;
聚类和随机&#xff1a;
区别还是蛮大的。