当前位置:   article > 正文

机器学习实战——PCA实现图像压缩_pca压缩图片

pca压缩图片

1.主成分分析概述

主成分分析是最为简单粗暴的一种数据降维方式,顾名思义就是找到数据中最为主要的方面,用这些方面来替代原始数据。具体来说,假设我们有一个具有n维特征的数据集,共有m个样本点,我们希望将这m个样本的特征维度从n维降到b维,希望b维数据尽可能的替代原始数据集
其中最为重要的因素就是如何保证减少维度后数据损失尽可能的小
如下图所示,我们试图将二维数据降到一维,图中列出两个维度PC1和PC2,显然PC1维度可以更加好的代表原始数据,因为把数据投影到PC1后,它们之间的方差最大,即PC1这个方向上包含了更多的信息量。这个PC1就是第一主成分,与PC1正交的PC2包含较少的信息量,为第二主成分,如果第一主成分包含的信息量足够大,那么光用第一主成分就可以很好的表示原始数据。
在这里插入图片描述
以此类推,PCA算法就是希望找到原始数据中最重要的维度,然后把原始数据投影到这些维度上,即把高维数据映射到低维度空间表示,由于映射后新生成的样本点之间方差最大,样本间的差异也最大限度的保存下来。

算法过程

  1. 对变量进行z-score标准化操作,消除变量间不同量纲造成的影响
  2. 计算数据的协方差矩阵
  3. 计算所得协方差的特征值(即主成分方差)与特征向量
  4. 将所得的特征值从大到小排序,并选择最大的k个特征值,即前k个主成分对应的特征向量。具体k如何选择,需要计算前k个特征值的累计贡献率来决定
  5. 将原始数据投影到所选取的k个特征向量组成的低维度空间,转化为新样本。通过原始数据乘以这k个特征向量即可得到

函数原型及参数说明

sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False)

参数说明:

n_components:

意义:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
类型:int 或者 string,缺省时默认为None,所有成分被保留。
          赋值为int,比如n_components=1,将把原始数据降到一个维度。
          赋值为string,比如n_components='mle',将自动选取特征个数n,使得满足所要求的方差百分比。
  • 1
  • 2
  • 3
  • 4

copy:

类型:bool,True或者False,缺省时默认为True。

意义:表示是否在运行算法时,将原始训练数据复制一份。
若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;
若为False,则运行PCA算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。
  • 1
  • 2
  • 3
  • 4
  • 5

whiten:

类型:bool,缺省时默认为False

意义:白化,使得每个特征具有相同的方差。
  • 1
  • 2
  • 3

2、PCA对象的属性

components_ :返回具有最大方差的成分。
explained_variance_ratio_:返回 所保留的n个成分各自的方差百分比。
n_components_:返回所保留的成分个数n。
mean_:
noise_variance_:

3、PCA对象的方法

fit(X,y=None)
  • 1

fit()可以说是scikit-learn中通用的方法,每个需要训练的算法都会有fit()方法,它其实就是算法中的“训练”这一步骤。因为PCA是无监督学习算法,此处y自然等于None。

fit(X),表示用数据X来训练PCA模型。

函数返回值:调用fit方法的对象本身。比如pca.fit(X),表示用X对pca这个对象进行训练。

fit_transform(X)
  • 1

用X来训练PCA模型,同时返回降维后的数据。
newX=pca.fit_transform(X),newX就是降维后的数据。

inverse_transform()
  • 1

将降维后的数据转换成原始数据,X=pca.inverse_transform(newX)

transform(X)
  • 1

将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维。

此外,还有get_covariance()、get_precision()、get_params(deep=True)、score(X, y=None)等方法,以后用到再补充吧。

示例:利用PCA进行图像压缩

采用的数据集是MNIST手写数据集,选择划分后的训练集样本作为数据集,共有60000个手写数据,每个样本的形状为(28,28)。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
import tensorflow as tf

# 导入数据集
data = tf.keras.datasets.mnist
(x_train, y_train), (_,_) = data.load_data()
x_trainnew = x_train.reshape(60000, 784)
pca = PCA()
pca.fit(x_trainnew)
# 显示数据集的64个数据
plt.figure()
fig, ax = plt.subplots(8, 8, figsize=(6, 6), dpi=600)  # ax是一个(8,8)的数组
for i, axi in enumerate(ax.flat):  # enumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。i是数据下标,axi是数据
    axi.imshow(x_train[i], cmap='binary')
    axi.set(xticks=[], yticks=[])  # 取消子图X,Y轴的刻度
# 计算各个N下的累计贡献率,找出累计贡献率大于90%时对应的K值
cumsum = np.cumsum(pca.explained_variance_ratio_)
d = np.argmax(cumsum >= 0.9)
# 进行数据降维,并且根据降维后的数据生成原始数据
xr = []
for n in [5, 30, d]:
    pca = PCA(n_components=n)
    x_reduced = pca.fit_transform(x_trainnew)
    x_recovered = pca.inverse_transform(x_reduced)
    xr.append(x_recovered)
instances=[]
for i in range(5):
    # 在列表instances中增加训练集中标签为i的第一个数据
    instances.append(x_train[y_train == i][0])
    print(x_train[y_train == i].shape)
    for j in range(3):
        # 将降维后的训练集中标标签为i的第一个数据增加到instances中,xr也是列表,包含三个数组(即三个降维后的训练集)
        instances.append(xr[j][y_train == i][0])
        print(xr[j][y_train == i][0])

images = [instance.reshape(28, 28) for instance in instances]
plt.figure()
fix, ax = plt.subplots(5, 4, dpi=600)
for i, axi in enumerate(ax.flat):
    axi.imshow(images[i], cmap='binary')
    axi.set(xticks=[], yticks=[])
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

显示的原始数据集:
在这里插入图片描述

压缩后的数据,分为为原始数据,主成分数量为5,30,86时对应的压缩后的数据:可以看出当主成分数量为86时,压缩后的图片比较清晰。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/94062
推荐阅读
相关标签
  

闽ICP备14008679号