• 学习笔记——PCA降维sklearn


    PCA降维sklearn


    本文从sklearn中PCA的使用出发,讲解如何使用PCA在sklearn中进行降维。具体讲解PCA的重要参数、重要属性和重要接口三个方面。

    1 重要参数

    1.1 参数n_components

    1.1.1 数字

    • 如果填数字,代表我们降维之后需要保留的维度,即降维后要保留的特征数量。
    • 输入的范围在[0.mim(X.shape)],即小于 特征数量和样本数量的最小值
    • 累积可解释性方差贡献率曲线可以帮助我们选择合适的n_components

    实践:鸢尾花数据集降维可视化

    from sklearn.datasets import load_iris
    from sklearn.decomposition import PCA
    import matplotlib.pyplot as pl
    import numpy as np
    iris=load_iris()
    y=iris.target
    X=iris.data
    
    y.shape
    (150,)
    X.shape
    (150, 4)
    
    #降维
    pca=PCA(n_components=2)
    pca=pca.fit(X)
    X_dr=pca.transform(X)
    #可视化
    colors=['red','black','orange']
    plt.figure()
    for i in  range(3):
        plt.scatter(X_dr[y==i,0],
                   X_dr[y==i,1],
                   alpha=0.7,
                   c=colors[i]
                   ,label=iris.target_names[i])
    plt.legend()
    plt.title('PCA of IRIS dataset')
    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

    在这里插入图片描述

    以下代码中涉及到PCA的两个重要属性:

    • explained_variance_:查看降维后每个新特征向量上所带的信息量大小(可解释性方差的大小)
    • explained_variance_ratio:又叫可解释方差贡献率,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比
    pca.explained_variance_
    #array([4.22824171, 0.24267075])
    pca.explained_variance_ratio_
    #array([0.92461872, 0.05306648])
    pca.explained_variance_ratio_.sum()
    #0.9776852063187949
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    # 累积可解释方差贡献率
    pca_line=PCA().fit(X)#什么都不填,也有进行特征空间的转换,但是没有减少特征的个数
    plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))
    plt.xticks([1,2,3,4])
    plt.ylabel("cumulative explained variance ratio")
    plt.xlabel("number of components after dimension reduction")
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    1.1.2 mle

    #最大似然估计选择超参数,
    pca_mle=PCA(n_components="mle")
    pca_mle=pca_mle.fit(X)
    X_mle=pca_mle.transform(X)
    pca_mle.explained_variance_ratio_.sum()
    #0.9947878161267246
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.1.3 信息量

    n_components中输入浮点数,代表降维到 满足该浮点数信息量的程度即可。

    #按信息量占比选择超参数
    pca_f=PCA(n_components=0.97,svd_solver='full')
    #当n_components的含义为信息量占比时,必须让参数svd_solver="full"
    pca_f=pca_f.fit(X)
    X_f=pca_f.transform(X)
    pca_f.explained_variance_ratio_
    #array([0.92461872, 0.05306648])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.2参数svd_solver

    参数svd_solver是在降维过程中,用来控制矩阵分解的一些细节的参数。有四种模式可选:“auto”, “full”, “arpack”,

    “randomized”,默认”auto"。 在实践时,一般用"auto",当计算不出来时,用"randomized"。

    auto”:简单来说就是,数据量小时,用"full"策略;数据量大时,用"randomized"策略

    基于X.shape和n_components的默认策略来选择分解器:如果输入数据的尺寸大于500x500且要提

    取的特征数小于数据最小维度min(X.shape)的80%,就启用效率更高的”randomized“方法。否则,精确完整

    的SVD将被计算,截断将会在矩阵被分解完成后有选择地发生

    full”:适合于数据量适中的情况

    从scipy.linalg.svd中调用标准的LAPACK分解器来生成精确完整的SVD,适合数据量比较适中,计算时

    间充足的情况,生成的精确完整的SVD的结构为:

    arpack”:适用于特征矩阵为稀疏矩阵的情况,即特征矩阵中为0的元素比非0的元素多得多

    randomized”:适合特征矩阵巨大,计算量庞大的情况

    1.3参数random_state

    在参数svd_solver的值为"arpack"或"randomized"的时候生效,可以控制这两种SVD模式中的随机模式,通常我们选用“auto”,不必对这个参数纠结太多。

    2 重要属性

    2.1 components_

    在n维特征矩降维的过程中

    1. 输入原数据,结构为(m, n),找出原本的n个特征向量构成的n维空间V
    2. 决定降维后的特征数量: k,
    3. 通过某种变化,找出n个新的特征向量,以及它们构成的新n维空间V
    4. 找出原始数据在新特征空间V中的n个新特征向量上对应的值,即**“将数据映射到新空间中”**
    5. 选取前k个信息量最大的特征,删掉没有被选中的特征,成功将n维空间V降为k维

    根据以上的降维过程,参数components_中保存的就是降维后的特征向量V(k,n),这里我们用图像数据来可视化解读V(k.n)

    from sklearn.datasets import fetch_lfw_people
    from sklearn.decomposition import PCA
    import matplotlib.pyplot as plt
    import numpy as np
    faces=fetch_lfw_people(min_faces_per_person=60)
    faces.images.shape#(1348, 62, 47)
    #1348是图像的个数,相当于每一个样本,只是图像特征有两个维度,
    #data中2914=62*47
    faces.data.shape#(1348, 2914)
    X=faces.data
    fig,axes=plt.subplots(3,8
                         ,figsize=(8,4)
                         ,subplot_kw={"xticks":[],"yticks":[]})#不显示坐标轴
    # fig#生成一张纸
    # axes.shape#一个个子图对象
    for i,ax in enumerate(axes.flat):
        ax.imshow(faces.images[i,:,:]
                 ,cmap="gray"
                 )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述
    <这里不知道为什么违规,参考下图,此图更清晰>

    #建模降维
    pca=PCA(150).fit(X)
    v=pca.components_
    v.shape#(150, 2914)
    fig,axes=plt.subplots(3,8
                         ,figsize=(8,4)
                         ,subplot_kw={"xticks":[],"yticks":[]})#不显示坐标轴
    # fig#生成一张纸
    # axes.shape#一个个子图对象
    for i,ax in enumerate(axes.flat):
        ax.imshow(v[i,:].reshape(62,47)
                 ,cmap="gray"
                 )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    可以发现,新特征空间可视化后的人脸非常模糊。大部分是和五官和亮度相关的向量,说明PCA能够将原始数据集中重要的数据进行聚集。

    2.2 explained_variance

    • explained_variance_:查看降维后每个新特征向量上所带的信息量大小(可解释性方差的大小)

    代码见n_components讲解部分的实践

    2.3 explained_variance_ratio_

    • explained_variance_ratio:又叫可解释方差贡献率,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比

    代码见n_components讲解部分的实践

    3 重要接口

    fit transform fit_transform三个较为熟悉,不多赘述

    3.1 inverse_transform

    • inverse_transform能将归一化、标准化的数据还原到原始数据中,得到原始数据
    • 但是在降维过程中,inverse_transform的过程只是在升维,将数据重新映射到原数据所在的特征空间,而并非恢复所有原有的数据。降维是不可逆的 ,原始数据中被舍弃的信息不会再回来。
    • 利用降维过程中的inverse_transform的特性,可以进行降噪。

    实践1:对比inverse_transform得到的数据和原始数据

    pca=PCA(150)
    X_dr=pca.fit_transform(X)
    X_dr.shape#(1348, 150)
    X_inverse=pca.inverse_transform(X_dr)
    X_inverse.shape#(1348, 2914)
    fig,ax=plt.subplots(2,10,figsize=(10,2.5)
                       ,subplot_kw={"xticks":[],"yticks":[]})
    for i in range(10):
        ax[0,i].imshow(faces.images[i,:,:],cmap="binary_r")
        ax[1,i].imshow(X_inverse[i,:].reshape(62,47),cmap="binary_r")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    实践2:利用inverse_transform进行降噪处理

    #PCA做噪声过滤
    from sklearn.datasets import load_digits
    from sklearn.decomposition import PCA
    import matplotlib.pyplot as plt
    import numpy as np
    digits=load_digits()
    digits.data.shape#(1797, 64)
    
    #定义作图函数
    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)#原始数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    # 为数据加上噪音
    np.random.RandomState(42)
    noisy=np.random.normal(digits.data,2)
    plot_digits(noisy)#加上噪音后的“原始数据”
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    #降维
    pca=PCA(0.5).fit(noisy)
    # pca.explained_variance_ratio_.sum()
    X_dr=pca.transform(noisy)
    X_dr.shape#(1797, 6)
    noisy_inverse=pca.inverse_transform(X_dr)
    plot_digits(noisy_inverse)#利用inverse_transform升维除噪后的数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    注:本文内容是本人在学习“菜菜的机器学习课程”过程中的记录、总结和整理,将重点部分整理出来的笔记。此文更侧重用法与实践,关于PCA和SVD、降维原理内容等理论知识没有过多整理。侵删

  • 相关阅读:
    QT--day2
    Oracle VM VirtualBox安装CentOS 7系统
    机器学习之偏差与方差的区别
    dc_shell的report_xx和查找pin或cell的input/output [all_fanin/out]
    Python处理复杂的CSV文件
    Rodrigues:旋转矩阵的向量表达
    langchain callback学习
    【Axure视频教程】item和targetitem函数
    【高阶数据结构】并查集的实现(含压缩路径)及其应用-C++版本
    C++ 之 backtrace
  • 原文地址:https://blog.csdn.net/weixin_55730631/article/details/126371570