目录
1.概述
2.案例
3.K-Means矢量量化
K-Means聚类最重要的应用之一是非结构数据(声音,图像)上的矢量量化(VQ),非结构化数据往往占据较多的储存空间,文件本身比较大,运算非常缓慢,我们希望能够在保证数据质量的前提下,尽量的缩小非结构化的数据大小,或者简化非结构化数据的结构。矢量量化就可以帮助我们实现这个目的。K-Means的本质是一种降维应用,它与一些其它的降维算法的思路不太相同。例如,特征选择的降维是直接选取对模型贡献最大的特征,PCA的降维是聚合信息,而 矢量量化的降维是在同等样本量上压缩信息的大小, 既不改变特征数目,也不改变样本数目,只改变在这些特征下的样本上的信息量。emmmm.....细细品
举个例子来说,有一组40个样本的数据,分别含有40组不同的信息(x1,x2)。我们把这组数据聚成4类,找出4个质心,我们认为每一簇的样本点和它们所属质心非常相似,因此它们所承载的信息就约等于它们所在的簇的质心所承载的信息。那我,我们就可以用每个簇的质心来覆盖原有样本。这样,40个样本带有的40种取值,就被我们压缩了4组取值,虽然样本量还是40个,但是这40个样本所带的取值其实只有4个,就是4个质心。
#导包 import numpy as np import pandas as pd 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#洗牌 #实例化导入颐和园图片 china=load_sample_image('china.jpg') print(china) print(china.dtype)#查看图片数据类型 print(china.shape) #包含多少种不同的颜色? newimage=china.reshape((427*640,3)) print(newimage.shape) result=pd.DataFrame(newimage).drop_duplicates().shape#去重复颜色 print(result) #图像可视化 plt.figure(figsize=(15,15)) plt.imshow(china)#导入三维数组形成的图片 plt.show()
图片探索完毕,我们可以了解到图片还有9w种颜色,我们希望 使用K-Means将颜色压缩到64种 ,也就是说将9w种颜色聚成64类,用64个质心来代替全部的9w种颜色。
为了比较,我们还要画出随机压缩到64种颜色的矢量量化图像。我们需要 随机选择64个样本点作为随机质心 。对比上面使用K- Means,观察图像可视化的状况,查看图片信息的损失度。
K-Means矢量量化:
#导包 import numpy as np import pandas as pd 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#洗牌 #实例化导入颐和园图片 china=load_sample_image('china.jpg') # 数据预处理 n_clusters=64 china=np.array(china,dtype=np.float64)/china.max()#归一化,压缩[0,1]之间 w,h,d=original_shape=tuple(china.shape)#把chian从图片模式转换为矩阵格式 assert d==3#确保d一定为3,不然报错 image_array=np.reshape(china,(w*h,d))#改变矩阵结构 #对数据进行KMeans矢量量化 image_array_sample=shuffle(image_array,random_state=0)[:1000]#数据量大先使用1000个数找到质心 kmeans=KMeans(n_clusters=n_clusters,random_state=0).fit(image_array_sample) print(kmeans.cluster_centers_.shape)#返回64个质心 #根据质心对所有数据进行分类 labels=kmeans.predict(image_array) print(labels.shape) #使用质心替换所有样本 image_kmeans=image_array.copy() for i in range(w*h): image_kmeans[i]=kmeans.cluster_centers_[labels[i]] #恢复图片结构 image_kmeans=image_kmeans.reshape(w,h,d) print(image_kmeans.shape) #最后绘制图像 #原图 plt.figure(figsize=(10,10)) plt.axis('off') plt.title('Original image (96,615 colors)') plt.imshow(china) plt.show() #kmeans降维后的 plt.figure(figsize=(10,10)) plt.axis('off') plt.title('Quantized image (64 colors,k-means)') plt.imshow(image_kmeans) plt.show()
效果:
随机矢量量化:
import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import pairwise_distances_argmin from sklearn.datasets import load_sample_image#导入图片数据所用的类 from sklearn.utils import shuffle#洗牌 #实例化导入颐和园图片 china=load_sample_image('china.jpg') #3 数据预处理 n_clusters=64 china=np.array(china,dtype=np.float64)/china.max() #把chian从图片模式转换为矩阵格式 w,h,d=original_shape=tuple(china.shape) assert d==3#确保d一定为3,不然报错 image_array=np.reshape(china,(w*h,d)) #对数据进行随机矢量量化 centroid_random=shuffle(image_array,random_state=0)[:n_clusters]#随机找到质心 print(centroid_random.shape) labels_random=pairwise_distances_argmin(centroid_random,image_array,axis=0)#27w个数据分别对应的随机质心的索引 #使用随机质心替换所有样本 image_random=image_array.copy() for i in range(w*h): image_random[i]=centroid_random[labels_random[i]] #恢复图片结构 image_random=image_random.reshape(w,h,d) print(image_random.shape) #显示图片 plt.figure(figsize=(10,10)) plt.axis('off') plt.title('Quantized image (64 colors,random)') plt.imshow(image_random) plt.show()
对比K-Means和随机矢量量化后的图片,可见K-Means比随机矢量量化的好太多。
原文链接:https://blog.csdn.net/qq_43161211/article/details/113833709