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

1.主成分分析概述

主成分分析是最为简单粗暴的一种数据降维方式,顾名思义就是找到数据中最为主要的方面,用这些方面来替代原始数据。具体来说,假设我们有一个具有n维特征的数据集,共有m个样本点,我们希望将这m个样本的特征维度从n维降到b维,希望b维数据尽可能的替代原始数据集。
其中最为重要的因素就是如何保证减少维度后数据损失尽可能的小
如下图所示,我们试图将二维数据降到一维,图中列出两个维度PC1和PC2,显然PC1维度可以更加好的代表原始数据,因为把数据投影到PC1后,它们之间的方差最大,即PC1这个方向上包含了更多的信息量。这个PC1就是第一主成分,与PC1正交的PC2包含较少的信息量,为第二主成分,如果第一主成分包含的信息量足够大,那么光用第一主成分就可以很好的表示原始数据。
机器学习实战——PCA实现图像压缩_第1张图片
以此类推,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,使得满足所要求的方差百分比。

copy:

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

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

whiten:

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

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

2、PCA对象的属性

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

3、PCA对象的方法

fit(X,y=None)

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

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

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

fit_transform(X)

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

inverse_transform()

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

transform(X)

将数据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()

显示的原始数据集:
机器学习实战——PCA实现图像压缩_第2张图片

压缩后的数据,分为为原始数据,主成分数量为5,30,86时对应的压缩后的数据:可以看出当主成分数量为86时,压缩后的图片比较清晰。
机器学习实战——PCA实现图像压缩_第3张图片

你可能感兴趣的:(机器学习实战,机器学习)