与原始图像进行比较
最后,让我们比较使用k = 12的压缩图像和原始图像的区别。
relative_size = ori_vs_kmeans.loc["Color-Reduced", "Image Size (KB)"]/ori_vs_kmeans.loc["Original", "Image Size (KB)"] print("Reduction: {:.3f}% from original image size".format((1-relative_size)*100)) print("Explained Variance: {:.3f}%".format(ori_vs_kmeans.loc["Color-Reduced", "Explained Variance"]))
缩小比例:原始图像的79.012%解释方差:95.916%
通过使用k-means,我们可以将图像大小减少79.012%,而解释方差为95.916%,这真是太好了!接下来,我们执行PCA,看看它是否可以优于k-means。
主成分分析(PCA)
概念
PCA是用于降维的无监督学习技术之一。它从协方差矩阵计算出特征向量,然后将其称为主轴,并按称为解释方差百分比的特征值进行递减排序。然后将数据集居中并投影到形成主要成分(或分数)的主轴上。为了减少数据维度,我们仅保留一定数量的主成分n来解释原始数据集的方差,而忽略其余部分。
假设我们有一个X_ori
数据集,其中包含m个观察值和n个特征。减去每行的平均值,我们得到居中的数据X。然后,PCA将为每个特征计算k个特征向量,从而产生形状为n×k的矩阵V。PCA投影或分数将以Z = XV给出,其中Z的尺寸为m×k。
降维时,我们在X_ori
中选择n_select小于n。以下是我们使用所选PC重建矩阵X的方法:
其中:
Z_reduce的尺寸为m×n_selectV_reduce的维数为n×n_selectT是矩阵转置运算
最后,我们添加均值以得到原始图像的最终PCA,如下所示:
理念
我们将通过选择要使用的主分量n_select利用PCA来减小图像尺寸,以便它仅存储重要像素以保留原始图像的特征,从而使其在存储中更加有效。
我们的原始图像包含三个颜色通道:红色,绿色和蓝色。对于每个颜色通道,我们将像素视为具有(高度)观察值和(宽度)特征的2D矩阵。在lena.png中,我们有三个2D矩阵,其中包含220个观测值和220个特征。
RGB通道的主要组件
在每个颜色通道上执行PCA,从而得到PCA投影(或分数)和主成分(轴),它们都将是形状为220×220的矩阵形式。
res = [] cum_var = [] X_t = np.transpose(X) for channel in range(3): # SEPARATE EACH RGB CHANNEL pixel = X_t[channel].reshape(*ori_pixels.shape[:2]) # PCA pca = PCA(random_state = 123) pixel_pca = pca.fit_transform(pixel) pca_dict = { "Projection": pixel_pca, "Components": pca.components_, "Mean": pca.mean_ } res.append(pca_dict) # EVALUATION cum_var.append(np.cumsum(pca.explained_variance_ratio_))
我们可以可视化每个颜色通道的主要成分,如下所示:
PC的可视化信息不足,随机性很大。我们应该引入一个称为解释方差的指标来评估PC性能。取值范围是0到100%,表示原始图像和压缩图像之间的相似度。
cum_var_df = pd.DataFrame(np.array(cum_var).T * 100, index = range(1, pca.n_components_+1), columns = ["Explained Variance by Red", "Explained Variance by Green", "Explained Variance by Blue"]) cum_var_df["Explained Variance"] = cum_var_df.mean(axis = 1) cum_var_df
重复试验
在本节中,我们将重复以下步骤从n_select到n_select = 220:
- 区分PCA投影的前n_select列和组件的前n_select行
- 使用PCA建立公式和原始图像
- 对红色,绿色和蓝色每个颜色通道重复步骤1-2。
- 将三种颜色通道的PCA重构组合为一个3D矩阵
- 保存指标值(解释方差,图像大小和颜色数量)以进行进一步优化
- 用越来越多的主成分绘制压缩(重构)图像
pca_results = [] for n in range(1, pca.n_components_+1): # SELECT N-COMPONENTS FROM PC temp_res = [] for channel in range(3): pca_channel = res[channel] pca_pixel = pca_channel["Projection"][:, :n] pca_comp = pca_channel["Components"][:n, :] pca_mean = pca_channel["Mean"] compressed_pixel = np.dot(pca_pixel, pca_comp) + pca_mean temp_res.append(compressed_pixel.T) compressed_image = np.transpose(temp_res) pca_dict = { "n": n, "Pixels": compressed_image, "Explained Variance": cum_var_df["Explained Variance"][n], "Image Size (KB)": imageByteSize(compressed_image), "No. of Colors": len(np.unique(np.uint8(compressed_image).reshape(-1, 3), axis = 0)) } pca_results.append(pca_dict) pca_results = pd.DataFrame(pca_results).set_index("n") pca_results.head()
PCA指标:主成分的最佳数量
在本节中,我们将尝试搜索最佳数量的PC,以在达到预期的解释方差的同时,使内存占用尽可能最小。
我们想通过分析解释方差来获得最佳主成分数,这是思考过程:左图:我们需要19、33和73个主成分才能分别解释原始图像的方差的90%,95%和99%。中图:但是需要权衡取舍,解释方差越大,图像尺寸就越大。黑色虚线表示原始图像尺寸,我们要在此线下方选择n。因此,选择19或33个主成分。右图:如果将n从19增加到33,然后再增加到73,则图像中存在的颜色数量将减少。
从图中可以得出结论,应当33个主成分,因为它给我们提供了较小的图像大小和相当高的解释方差,并且比使用19个主要成分更接近原始图像。
与原始图像进行比较
最后,让对压缩图像和原始图像进行比较。
relative_size = ori_vs_pca.loc["PC-Reduced", "Image Size (KB)"]/ori_vs_kmeans.loc["Original", "Image Size (KB)"] print("Reduction: {:.3f}% from original image size".format((1-relative_size)*100)) print("Explained Variance: {:.3f}%".format(ori_vs_pca.loc["PC-Reduced", "Explained Variance"]))
缩小比例:原始图像大小的6.825%解释方差:95.072%
通过使用PCA,我们只能将图像大小减小6.825%,并且压缩后的图像成功捕获了原始图像的95.072%的特征。接下来,我们比较k-means和PCA的结果。
k-means和PCA的比较
我们考虑几个指标,以比较使用k-means和PCA压缩图像的效果:
- 图片大小(以千字节为单位)
- 解释方差
- 图像中存在的颜色数
reduction_kmeans = (1-final_compare.loc["Color-Reduced", "Image Size (KB)"] / ori_img_size) * 100 reduction_pca = (1-final_compare.loc["PC-Reduced", "Image Size (KB)"] / ori_img_size) * 100 print("Image Size Reduction using K-Means: {:.3f}%".format(reduction_kmeans)) print("Image Size Reduction using PCA: {:.3f}%".format(reduction_pca))
使用k-means缩小图像大小:79.012%使用PCA缩小图像大小:6.825%
结论
我们使用无监督学习算法成功地实现了图像压缩,例如k-means聚类和使用主成分分析(PCA)进行降维。
在k-means中,通常通过可视化来主观地选择最佳聚类中心数k。在这里,我们提出两种选择方法,即:
- 使用最长垂直距离的方法
- 使用有限差分法和二阶导数
在PCA中,确定使用的PC数量首先要考虑解释方差,然后还要考虑图像大小减小的比例和减少颜色的数量,以分析它们与原始图像的相似性。
使用k-means,图像大小减小到79.012%,仅12种颜色就能解释原始图像的95.916%差异。使用PCA,图像大小减小仅为6.825%,并根据我们的目标解释了95,072%的差异。在经过PCA缩小的图像中,与原始图像相比,存在更多的颜色数量,表明存在噪音。从主观上可以看出,PCA压缩的图像更加粗糙。
与PCA相比,更建议使用k-means来缩小图像尺寸,但是如果我们要保持原始图像的整体色彩,请使用PCA。
另一个建议是尝试连续执行两种方法来进行图像缩小,即先用k-means再用PCA,或是先用PCA再用k-means。