PCA+SVD降维:完整代码+实例分析

import warnings
warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
import seaborn as sns
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np

1.引例:鸢尾花数据集降维及可视化

x = load_iris().data
y = load_iris().target
x.shape #一共150个样本,4个特征
(150, 4)
pca = PCA(n_components=2) #将4个特征降成2个特征,以便在平面上展示
x_pca = pca.fit_transform(x)

# 降维结果的可视化
plt.figure()
sns.scatterplot(x_pca[:,0],x_pca[:,1],hue=y,palette=sns.color_palette("Accent", 3))
plt.title('pca result')
plt.xlabel('pc_1')
plt.ylabel('pc_2')
plt.show()

ps:sns.color_palette的可选值请戳sns的color_palette.

在这里插入图片描述

#属性explained_variance_,查看降维后每个新特征向量上所带的信息量大小(可解释性方差的大小) 
pca.explained_variance_
array([4.22824171, 0.24267075])
#属性explained_variance_ratio,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比 
#又叫做可解释方差贡献率 
print(pca.explained_variance_ratio_)
print('降维后的信息量是原始信息量的{:.2%}'.format(pca.explained_variance_ratio_.sum()))
[0.92461872 0.05306648]
降维后的信息量是原始信息量的97.77%

2.PCA重要参数、属性、方法

2.1 重要参数

  • n_components:降到多少维。可以填入整数、0-1之间的小数或者‘mle’
    0~1之间的小数表示保留多少信息量,根据信息量决定降到多少维,必须搭配 svd_solver='full’来使用;
    ‘mle’使用极大似然估计判断要降到多少维

  • svd_solver:可选值‘auto’、‘full’、‘arpack’、‘randomized’;具体区别如下:
    auto:基于X.shape和n_components的默认策略来选择分解器:如果输入数据的尺寸大于500x500且要提 取的特征数小于数据最小维度min(X.shape)的80%,就启用效率更高的”randomized“方法;否则,就使用‘full’模式,截断将会在矩阵被分解完成后有选择地发生
    full:从scipy.linalg.svd中调用标准的LAPACK分解器来生成精确完整的SVD,适合数据量比较适中,计算时 间充足的情况,生成的精确完整的SVD的结构为: U(m,m) ,∑(m,n) ,V(n,n)
    arpack:从scipy.sparse.linalg.svds调用ARPACK分解器来运行截断奇异值分解(SVD truncated),分解时就 将特征数量降到n_components中输入的数值k,可以加快运算速度,适合特征矩阵很大的时候,但一般用于 特征矩阵为稀疏矩阵的情况,此过程包含一定的随机性。截断后的SVD分解出的结构为:U(m,k) ,∑(m,k) ,V(n,n)
    randomized:在"full"方法中,分解器会根据原始数据和输入的 n_components值去计算和寻找符合需求的新特征向量,但是在"randomized"方法中,分解器会先生成多个 随机向量,然后一一去检测这些随机向量中是否有任何一个符合我们的分解需求,如果符合,就保留这个随 机向量,并基于这个随机向量来构建后续的向量空间。这个方法已经被Halko等人证明,比"full"模式下计算快 很多,并且还能够保证模型运行效果。适合特征矩阵巨大,计算量庞大的情况。

  • random_state:当svd_solver取值为arpack和randomized时的随机数种子

补充知识点:SVD

在这里插入图片描述

在这里插入图片描述
详细可戳svd.

2.2 重要属性

  • components_:设降维后的特征矩阵为x_pca,即x * V的转置 = x_pca,components_就是V
    x的shape为(m,n),V的shape是(k,n),x_pca的shape是(m,k)

  • explained_variance_:各主成分的可解释性方差

  • explained_variance_ratio_:各主成分可解释性方差占比(分母是所有特征的方差和)

2.3 重要方法

  • inverse_transform:将降维后的特征矩阵升维会原始的维度
from sklearn.datasets import fetch_lfw_people

faces = fetch_lfw_people(min_faces_per_person=60)

faces.data.shape #一共有1348张图,每张图2914个pixel
(1348, 2914)
faces.images.shape # 62*47=2914
(1348, 62, 47)
fig,axes = plt.subplots(4,4
                       ,figsize=(10,10)
                       ,subplot_kw={
   'xticks':[],'yticks':[]}) #去掉所有子图的坐标
fig.suptitle('original pic',y=0.92,fontsize=15) #给整个画布加上一个总标题
for i,ax in enumerate(axes.flat):
    ax.imshow(faces.images[i,:,:],cmap='gray')    

ps:plt的cmap请戳plt的cmap.

在这里插入图片描述

# pca降维处理
pca = PCA(150).fit(faces.data) #原本有2914维,现在降成150维
v = pca.components_
v.shape
(150, 2914)
fig,axes = plt.subplots(15,10
                       ,figsize=(25,40)
                       ,subplot_kw={
   'xticks':[],'yticks':[]}) #去掉所有子图的坐标
fig.suptitle('feature extraction',y=0.9,fontsize=20) #给整个画布加上一个总标题
for i,ax in enumerate(axes.flat):
    ax.imshow(v[i,:].reshape(62,47),cmap='gray')   
'''
我们可以把components_中的每一行看成一个特征提取器,本例中一共150行,使用v就可以从每张原始图片中提取150个特征出来,也就把2914维降到了150维
从下面对特征提取器的可视化可以看出,不同的提取器提取的是原始图片中不同的特征
比如前几个应该提取的是原始图片中的光线
后面几个可能提取的是五官
之后可能是面部表情
最后那些可能是脸部轮廓
'''

在这里插入图片描述

x_pca = pca.transform(faces.data)
x_pca.shape #原始特征矩阵变成了150维
(1348, 150)
x_inverse = pca.inverse_transform
  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值