zoukankan      html  css  js  c++  java
  • 机器学习实战基础(二十四):sklearn中的降维算法PCA和SVD(五) PCA与SVD 之 重要接口inverse_transform

    重要接口inverse_transform 

    在上周的特征工程课中,我们学到了神奇的接口inverse_transform,可以将我们归一化,标准化,甚至做过哑变量的特征矩阵还原回原始数据中的特征矩阵,这几乎在向我们暗示,任何有inverse_transform这个接口的过程都是可逆的。PCA应该也是如此。在sklearn中,我们通过让原特征矩阵X右乘新特征空间矩阵V(k,n)来生成新特征矩阵X_dr,那理论上来说,让新特征矩阵X_dr右乘V(k,n)的逆矩阵 ,就可以将新特征矩阵X_dr还原为X。那sklearn是否这样做了呢?让我们来看看下面的案例。

    1 迷你案例:用人脸识别看PCA降维后的信息保存量

    人脸识别是最容易的,用来探索inverse_transform功能的数据。我们先调用一组人脸数据X(m,n),对人脸图像进行绘制,然后我们对人脸数据进行降维得到X_dr,之后再使用inverse_transform(X_dr)返回一个X_inverse(m,n),并对这个新矩阵中的人脸图像也进行绘制。
    如果PCA的降维过程是可逆的,我们应当期待X(m,n)和X_inverse(m,n)返回一模一样的图像,即携带一模一样的信息。

    1. 导入需要的库和模块

    from sklearn.datasets import fetch_lfw_people
    from sklearn.decomposition import PCA
    import matplotlib.pyplot as plt
    import numpy as np

    2. 导入数据,探索数据

    faces = fetch_lfw_people(min_faces_per_person=60)
    faces.images.shape
    #怎样理解这个数据的维度?
    faces.data.shape
    #换成特征矩阵之后,这个矩阵是什么样?
    X = faces.data

    3. 建模降维,获取降维后的特征矩阵X_dr

    pca = PCA(150)
    X_dr = pca.fit_transform(X)
    X_dr.shape

    4. 将降维后矩阵用inverse_transform返回原空间

    X_inverse = pca.inverse_transform(X_dr)
     
    X_inverse.shape

    5. 将特征矩阵X和X_inverse可视化

    fig, ax = plt.subplots(2,10,figsize=(10,2.5)
                          ,subplot_kw={"xticks":[],"yticks":[]}
                         )
     
    #和2.3.3节中的案例一样,我们需要对子图对象进行遍历的循环,来将图像填入子图中
    #那在这里,我们使用怎样的循环?
    #现在我们的ax中是2行10列,第一行是原数据,第二行是inverse_transform后返回的数据
    #所以我们需要同时循环两份数据,即一次循环画一列上的两张图,而不是把ax拉平
     
    for i in range(10):
        ax[0,i].imshow(face.image[i,:,:],cmap="binary_r")
        ax[1,i].imshow(X_inverse[i].reshape(62,47),cmap="binary_r")

    可以明显看出,这两组数据可视化后,由降维后再通过inverse_transform转换回原维度的数据画出的图像和原数据画的图像大致相似,但原数据的图像明显更加清晰。
    这说明,inverse_transform并没有实现数据的完全逆转。这是因为,在降维的时候,部分信息已经被舍弃了,X_dr中往往不会包含原数据100%的信息,所以在逆转的时
    候,即便维度升高,原数据中已经被舍弃的信息也不可能再回来了。所以,降维不是完全可逆的。

    Inverse_transform的功能,是基于X_dr中的数据进行升维,将数据重新映射到原数据所在的特征空间中,而并非恢复所有原有的数据。
    但同时,我们也可以看出,降维到300以后的数据,的确保留了原数据的大部分信息,所以图像看起来,才会和原数据高度相似,只是稍稍模糊罢了。

    2 迷你案例:用PCA做噪音过滤

    降维的目的之一就是希望抛弃掉对模型带来负面影响的特征,而我们相信,带有效信息的特征的方差应该是远大于噪音的,所以相比噪音,有效的特征所带的信息应该不会在PCA过程中被大量抛弃。
    inverse_transform能够在不恢复原始数据的情况下,将降维后的数据返回到原本的高维空间,即是说能够实现”保证维度,但去掉方差很小特征所带的信息“。利用inverse_transform的这个性质,我们能够实现噪音过滤。

    1. 导入所需要的库和模块

    from sklearn.datasets import load_digits
    from sklearn.decomposition import PCA
    import matplotlib.pyplot as plt
    import numpy as np

    2. 导入数据,探索数据

    digits = load_digits()
    digits.data.shape

    3. 定义画图函数

    def plot_digits(data):
        fig, axes = plt.subplots(4,10,figsize=(10,4)
                                ,subplot_kw = {"xticks":[],"yticks":[]}
                                )
        for i, ax in enumerate(axes.flat):
            ax.imshow(data[i].reshape(8,8),cmap="binary")
            
    plot_digits(digits.data)

    4. 为数据加上噪音

    np.random.RandomState(42)
     
    #在指定的数据集中,随机抽取服从正态分布的数据
    #两个参数,分别是指定的数据集,和抽取出来的正太分布的方差
    noisy = np.random.normal(digits.data,2)
     
    plot_digits(noisy)

    5. 降维

    pca = PCA(0.5).fit(noisy)
    X_dr = pca.transform(noisy)
    X_dr.shape

    6. 逆转降维结果,实现降噪

    without_noise = pca.inverse_transform(X_dr)
    plot_digits(without_noise)
  • 相关阅读:
    反向迭代
    c++知识点
    LeetCode-Count Bits
    LeetCode-Perfect Rectangle
    LeetCode-Perfect Squares
    LeetCode-Lexicographical Numbers
    LeetCode-Find Median from Data Stream
    LeetCode-Maximal Square
    LeetCode-Number of Digit One
    LeetCode-Combination Sum IV
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/12988645.html
Copyright © 2011-2022 走看看