PCA主成分分析

本文详细解读了Scikit-learn库中的PCA和SVD降维算法,通过手写数字数据集展示了PCA如何减少维度并保持关键信息,同时介绍了SVD的数学原理和在降维中的应用。还演示了如何利用PCA进行LFW人脸数据集的可视化,并探讨了选择不同svd_solver和random_state的影响。
摘要由CSDN通过智能技术生成
Sklearn中的降维算法

在这里插入图片描述

PCA和SVD

class sklearn.decomposition.PCA (n_components=None, copy=True, whiten=False, svd_solver=’auto’, tol=0.0,
								iterated_power=’auto’, random_state=None)

二维数据的降维

在这里插入图片描述

重要参数:n_components

案例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
#导入digits手写数据集
digits = datasets.load_digits()
X = digits.data
y = digits.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state=666)

knn = KNeighborsClassifier()
knn.fit(X_train,y_train)
#原始数据集共有64维
array([[ 0.,  0.,  6., ...,  4.,  0.,  0.],
       [ 0.,  1.,  3., ..., 14.,  0.,  0.],
       [ 0.,  0.,  5., ..., 14.,  3.,  0.],
       ...,
       [ 0.,  3., 15., ..., 12.,  3.,  0.],
       [ 0.,  0.,  1., ...,  7.,  0.,  0.],
       [ 0.,  0.,  9., ...,  0.,  0.,  0.]])
knn.score(X_test,y_test)
#0.9888888888888889
#使用PCA降维,设置降为2维
from sklearn.decomposition import PCA

pca = PCA(n_components=2)
pca.fit(X_train)
X_train_reduction = pca.transform(X_train) # 训练数据集降维结果
X_test_reduction = pca.transform(X_test) # 测试数据集降维结果

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_reduction, y_train)
knn_clf.score(X_test_reduction, y_test)
#0.6055555555555555

PCA算法提供了一个特殊的指标pca.explained_variance_ratio_(解释方差比例),我们可以使用这个指标找到某个数据集保持多少的精度:

pca.explained_variance_ratio_
# 输出:
#array([ 0.14566817,  0.13735469])

对于现在的PCA算法来说,得到的是二维数据:0.14566817表示第一个轴能够解释14.56%数据的方差;0.13735469表示第二个轴能够解释13.73%数据的方差。PCA过程寻找主成分,就是找使得原数据的方差维持的最大。这个值就告诉我们,PCA最大维持了原来所有方差的百分比。对于这两个维度来说,[ 0.14566817, 0.13735469]涵盖了原数据的总方差的28%左右的信息,剩下72%的方差信息就丢失了,显然丢失的信息过多.

# 横轴是是样本X的i个特征数,纵轴是前i个轴解释方差比例的和
plt.plot([i for i in range(X_train.shape[1])], 
         [np.sum(pca.explained_variance_ratio_[:i+1]) for i in range(X_train.shape[1])])
plt.show()

在这里插入图片描述

如果我们希望保持95%以上的信息,就能得到相应的降维后的主成分个数。在sklearn中,实例化时传入一个数字,就表示保持的方差比例:

pca = PCA(0.95,svd_solver="full")
pca.fit(X_train)
# 输出:
#PCA(copy=True, iterated_power='auto', n_components=0.95, random_state=None,
#  svd_solver='auto', tol=0.0, whiten=False)
#查看一下降维后主成分的个数为28,即对于64维数据来说,28维数据就可以解释95%以上的方差。
pca.n_components_
#28

数据降维还有一个作用是可视化,降到2维数据之后:

pca = PCA(n_components=2)
pca.fit(X)
X_reduction = pca.transform(X)
for i in range(10):
    plt.scatter(X_reduction[y==i,0], X_reduction[y==i,1], alpha=0.8)
plt.show()

在这里插入图片描述

PCA中的SVD

SVD有一种惊人的数学性质,即是它可以跳过数学神秘的宇宙,不计算协方差矩阵,直接找出一个新特征向 量组成的n维空间,而这个n维空间就是奇异值分解后的右矩阵
(所以一开始在讲解降维过程时,我们说”生成新 特征向量组成的空间V",并非巧合,而是特指奇异值分解中的矩阵 )

重要参数:svd_solver 与 random_state

重要属性:components_

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)#实例化   min_faces_per_person=60:每个人取出60张脸图

faces.images.shape#(1277,62,47)  1277是矩阵中图像的个数,62是每个图像的特征矩阵的行,47是每个图像的特征矩阵的列
#怎样理解这个数据的维度?
faces.data.shape#(1277,2914)   行是样本,列是样本相关的所有特征:2914 = 62 * 47
#换成特征矩阵之后,这个矩阵是什么样?
X = faces.data

#创建画布和子图对象
fig, axes = plt.subplots(4,5#4行5列个图
                        ,figsize=(8,4)#figsize指的是图的尺寸
                        ,subplot_kw = {"xticks":[],"yticks":[]} #不要显示坐标轴
                        )

#不难发现,axes中的一个对象对应fig中的一个空格
#我们希望,在每一个子图对象中填充图像(共24张图),因此我们需要写一个在子图对象中遍历的循环
axes.shape#(4,5)
 
#二维结构,可以有两种循环方式,一种是使用索引,循环一次同时生成一列上的四个图
#另一种是把数据拉成一维,循环一次只生成一个图
#在这里,究竟使用哪一种循环方式,是要看我们要画的图的信息,储存在一个怎样的结构里
#我们使用 子图对象.imshow 来将图像填充到空白画布上
#而imshow要求的数据格式必须是一个(m,n)格式的矩阵,即每个数据都是一张单独的图
#因此我们需要遍历的是faces.images,其结构是(1277, 62, 47)
#要从一个数据集中取出24个图,明显是一次性的循环切片[i,:,:]来得便利
#因此我们要把axes的结构拉成一维来循环

# [*axes.flat]#2维
axes.flat#降低一个维度
# [*axes.flat] #1维

#填充图像
for i, ax in enumerate(axes.flat):
    ax.imshow(faces.images[i,:,:] 
              ,cmap="gray" #选择色彩的模式
            )
 
fig
# cmap参数取值选择各种颜色:https://matplotlib.org/tutorials/colors/colormaps.html

在这里插入图片描述

#原本有2900维,我们现在来降到150维
pca = PCA(150).fit(X)#这里X = faces.data,不是faces.images.shape ,因为sklearn只接受2维数组降,不接受高维数组降
# x_dr = pca.transform(X)
# x_dr.shape#(1277,150)

V = pca.components_#新特征空间
V.shape#V(k,n)   (150, 2914)

fig, axes = plt.subplots(3,8,figsize=(8,4),subplot_kw = {"xticks":[],"yticks":[]})
 
#取出每一个图片的特征矩阵并重新塑造其维度
for i, ax in enumerate(axes.flat):
    ax.imshow(V[i,:].reshape(62,47),cmap="gray")

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顾十方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值