写点什么

主成分分析 PCA 与奇异值分解 SVD- 高维数据可视化以及参数 n_components

  • 2022-11-17
    山东
  • 本文字数:2729 字

    阅读完需:约 9 分钟

高维数据的可视化和 n_components

PCA(    ['n_components=None', 'copy=True', 'whiten=False', "svd_solver='auto'", 'tol=0.0', "iterated_power='auto'", 'random_state=None'],)# n_components:降维后维度的数量,可填正整数、[0,1]浮点数、mle
复制代码


import matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.decomposition import PCAimport pandas as pd
iris = load_iris()X = iris.datay = iris.targetX.shape---(150, 4)
pd.DataFrame(X).head()--- 0 1 2 30 5.1 3.5 1.4 0.21 4.9 3.0 1.4 0.22 4.7 3.2 1.3 0.23 4.6 3.1 1.5 0.24 5.0 3.6 1.4 0.2
set(y)---{0, 1, 2}
pca = PCA(n_components=2) # 实例化# 这里n_components=2,就是说降维以后需要留下2个维度的特征pca = pca.fit(X) # 拟合模型X_dr = pca.transform(X) # 获取新矩阵# 也可以一步到位 X_dr = PCA(2).fit_transform(X)X_dr[:5,:]---array([[-2.68412563, 0.31939725], [-2.71414169, -0.17700123], [-2.88899057, -0.14494943], [-2.74534286, -0.31829898], [-2.72871654, 0.32675451]])
plt.figure()plt.scatter(X_dr[y==0,0], X_dr[y==0,1],c="red",label=iris.target_names[0],alpha=0.7)plt.scatter(X_dr[y==1,0], X_dr[y==1,1],c="black",label=iris.target_names[1],alpha=0.7)plt.scatter(X_dr[y==2,0], X_dr[y==2,1],c="orange",label=iris.target_names[1],alpha=0.7)# alpha:透明度plt.legend()plt.title("PCA of IRIS dataset")plt.show() # 降维后数据可视化
复制代码



pca.explained_variance_# 属性explained_variance_,查看降维后每个新特征向量上所带的信息量大小(可解释方差的大小)# 往往第一个特征上信息量最大,即方差最大,向后逐渐减小---array([4.22824171, 0.24267075])
pca.explained_variance_ratio_# 属性explained_variance_ratio_,查看将为后每个新特征向量所占的信息量和原始数据总信息量的百分比# 又叫可解释方差贡献率# 大部分信息都被有效的集中在了第一个特征上---array([0.92461872, 0.05306648])
pca.explained_variance_ratio_.sum() # 新矩阵带有原矩阵的数据量---0.977685206318795
pca_line = PCA().fit(X) # 默认返回min(X.shape)个特征pca_line.explained_variance_ratio_# 因为对协方差矩阵进行分解后就可以得到最优的p个方向向量# 将数据代入求解即可以得到每个方向上数据的方差占比---array([0.92461872, 0.05306648, 0.01710261, 0.00521218])
复制代码


选择最好的 n_components:累积可解释方差贡献率曲线在数据量大于特征维度的时候,我们设置 n_components 为默认值,可以画出累计可解释方差贡献率曲线,以此选择最好的 n_components 的整数取值。累积可解释方差贡献率曲线是一条以降维后保留的特征个数为横坐标,降维后新特征矩阵捕捉到的可解释方差贡献率为纵坐标的曲线,能够帮助我们决定 n_components 最好的取值。


import numpy as np
plt.figure()plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))plt.xticks([1,2,3,4])plt.xlabel("number of components after dimension reduction") # 降维后维度数量plt.ylabel("cumulative explained variance ratio") # 累计可解释方差比
复制代码



一般这条曲线会先急剧上升,然后平缓上升至 1,我们选择急剧到平缓转折点对应的数值作为 n_components 的值

最大似然估计自选超参数

最大似然估计选择超参数是让 PCA 自选超参数的方法。需要注意的是,该方法计算量较大,在高维度时会消耗大量时间


pca_mle = PCA(n_components='mle')pca_mle = pca_mle.fit(X)X_mle = pca_mle.transform(X)X_mle.shape # MLE自动选择了三个特征---(150, 3)
复制代码

按信息量占比选超参数

n_components 后面加之间的浮点数,并且让数 svd_solver ='full',表示希望降维后的总解释性方差占比大于 n_components 指定的百分比。比如说,如果我们希望保留 97%的信息量,就可以输入 n_components=0.97,PCA 会自动选出能够让保留的信息量超过 97%的特征数量。


pca_f = PCA(n_components=0.97,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])
pca_f.explained_variance_ratio_.sum()---0.977685206318795
pca_f = PCA(n_components=0.99,svd_solver="full")pca_f = pca_f.fit(X)X_f = pca_f.transform(X)pca_f.explained_variance_ratio_.sum()---0.9947878161267247
复制代码

svd_solver

PCA(    ['n_components=None', 'copy=True', 'whiten=False', "svd_solver='auto'", 'tol=0.0', "iterated_power='auto'", 'random_state=None'],)# svd_solver:在降维过程中,用来控制矩阵分解的一些细节的参数。有四种模式可选:"auto", "full", "arpack", "randomized",默认”auto"。
复制代码


"auto":基于 X.shape 和 n_components 的默认策略来选择分解器。如果输入数据的尺寸大于 500x500 且要提取的特征数小于数据最小维度 min(X.shape)的 80%,就启用效率更高的”randomized“方法。否则,精确完整的 SVD 将被计算,截断将会在矩阵被分解完成后有选择地发生


"full":从 scipy.linalg.svd 中调用标准的 LAPACK 分解器来生成精确完整的 SVD,适合数据量比较适中,计算时间充足的情况,生成的精确完整的 SVD 的结构为:



"arpack":从 scipy.sparse.linalg.svds 调用 ARPACK 分解器来运行截断奇异值分解(SVD truncated),分解时就将特征数量降到 n_components 中输入的数值 k,可以加快运算速度,适合特征矩阵很大的时候,但一般用于特征矩阵为稀疏矩阵的情况,此过程包含一定的随机性。截断后的 SVD 分解出的结构为:



不太理解这里的 k 是降维后的维度,还是去掉奇异值为 0 后奇异值的数量


"randomized",通过 Halko 等人的随机方法进行随机 SVD。在"randomized"方法中,分解器会先生成多个随机向量,然后一一去检测这些随机向量中是否有任何一个符合我们的分解需求,如果符合,就保留这个随机向量,并基于这个随机向量来构建后续的向量空间。这个方法已经被 Halko 等人证明,比"full"模式下计算快很多,并且还能够保证模型运行效果。适合特征矩阵巨大,计算量庞大的情况。

random_state

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


视频作者:菜菜TsaiTsai链接:【技术干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili


发布于: 刚刚阅读数: 3
用户头像

一个烟台人 2022-09-14 加入

还未添加个人简介

评论

发布
暂无评论
主成分分析PCA与奇异值分解SVD-高维数据可视化以及参数n_components_机器学习_烧灯续昼2002_InfoQ写作社区