主成分分析(PCA)降维

目录

一、前言

二、相关概念

2.1维度

三、降维实现原理

3.1方差

3.2协方差

3.3协方差矩阵

3.4矩阵对角化

3.5补充数学推导过程

四、PCA算法实现

4.1算法步骤

4.2手动实现PCA

4.3人脸识别降维

五、总结


一、前言

在机器学习和数据分析领域,主成分分析(PCA)是一种常用的降维技术,旨在减少数据维度并保留主要信息。通过将高维数据映射到低维空间,PCA使得数据更易于可视化、理解和处理。本文将深入探讨PCA的原理、应用和实现。

二、相关概念

2.1维度

1. 对于数组和Series来说,维度就是功能shape返回的结果,shape中返回了几个数字,就是几维。索引以外的数据,不分行列的叫一维(此时shape返回唯一的维度上的数据个数);有行列之分叫二维(shape返回行×列),也称为表。
2. 数组中的每一张表,都可以是一个特征矩阵或一个DataFrame,这些结构永远只有一张表,所以一定有行列,其中行是样本,列是特征。针对每一张表,维度指的是样本的数量或特征的数量,一般无特别说明,指的都是特征的数量。除了索引之外,一个特征是一维,两个特征是二维,n个特征是n维。

3. 对图像来说,维度就是图像中特征向量的数量。特征向量可以理解为是坐标轴,一个特征向量定义一条直线,是一维,两个相互垂直的特征向量定义一个平面,即一个直角坐标系,就是二维,三个相互垂直的特征向量定义一个空间,即一个立体直角坐标系,就是三维。三个以上的特征向量相互垂直,定义人眼无法看见,也无法想象的高维空间。


三、降维实现原理

在降维过程中,我们会减少特征的数量,这意味着删除数据,数据量变少则表示模型可以获取的信息会变少,模型的表现可能会因此受影响。同时,在高维数据中,必然有一些特征是不带有效的信息的(比如噪音),或者有一些特征带有的信息和其他一些特征是重复的(比如一些特征可能会线性相关)。
 我们希望能够找出一种办法来帮助我们衡量特征上所带的信息量,让我们在降维的过程中,能够即减少特征的数量,又保留大部分有效信息——将那些带有重复信息的特征合并,并删除那些带无效信息的特征等等——逐渐创造出能够代表原特征矩阵大部分信息的,特征更少的,新特征矩阵

3.1方差

我们知道数值的分散程度,可以用数学上的方差来表述。一个变量的方差可以看做是每个元素与变量均值的差的平方和的均值,即:

为了方便处理,我们将每个变量的均值都化为 0 ,因此方差可以直接用每个元素的平方和除以元素个数表示:

3.2协方差

在一维空间中我们可以用方差来表示数据的分散程度。而对于高维数据,我们用协方差进行约束,协方差可以表示两个变量的相关性。为了让两个变量尽可能表示更多的原始信息,我们希望它们之间不存在线性相关性,因为相关性意味着两个变量不是完全独立,必然存在重复表示的信息。

协方差公式为:

 

当样本数较大时,不必在意其是 m 还是 m-1,为了方便计算,我们分母取 m。

当协方差为 0 时,表示两个变量完全独立。为了让协方差为 0,我们选择第二个基时只能在与第一个基正交的方向上进行选择,因此最终选择的两个方向一定是正交的。

至此,我们得到了降维问题的优化目标:将一组 N 维向量降为 K 维,其目标是选择 K 个单位正交基,使得原始数据变换到这组基上后,各变量两两间协方差为 0,而变量方差则尽可能大(在正交的约束下,取最大的 K 个方差)。

3.3协方差矩阵

针对我们给出的优化目标,接下来我们将从数学的角度来给出优化目标。

我们看到,最终要达到的目的与变量内方差及变量间协方差有密切关系。因此我们希望能将两者统一表示,仔细观察发现,两者均可以表示为内积的形式,而内积又与矩阵相乘密切相关。于是我们有:

假设我们只有 a 和 b 两个变量,那么我们将它们按行组成矩阵 X:

然后:

我们可以看到这个矩阵对角线上的分别是两个变量的方差,而其它元素是 a 和 b 的协方差。两者被统一到了一个矩阵里。

我们很容易被推广到一般情况:

设我们有 n 个 m 维数据记录,将其排列成矩阵 Xn,m,设,则 C 是一个对称矩阵,其对角线分别对应各个变量的方差,而第 i 行 j 列和 j 行 i 列元素相同,表示 i 和 j 两个变量的协方差

3.4矩阵对角化

根据我们的优化条件,我们需要将除对角线外的其它元素化为 0,并且在对角线上将元素按大小从上到下排列(变量方差尽可能大),这样我们就达到了优化目的。这样说可能还不是很明晰,我们进一步看下原矩阵与基变换后矩阵协方差矩阵的关系。

设原始数据矩阵 X 对应的协方差矩阵为 C,而 P 是一组基按行组成的矩阵,设 Y=PX,则 Y 为 X 对 P 做基变换后的数据。设 Y 的协方差矩阵为 D,我们推导一下 D 与 C 的关系:

这样我们就看清楚了,我们要找的 P 是能让原始协方差矩阵对角化的 P。换句话说,优化目标变成了寻找一个矩阵 P,满足 是一个对角矩阵,并且对角元素按从大到小依次排列,那么 P 的前 K 行就是要寻找的基,用 P 的前 K 行组成的矩阵乘以 X 就使得 X 从 N 维降到了 K 维并满足上述优化条件

至此,我们离 PCA 还有仅一步之遥,我们还需要完成对角化

由上文知道,协方差矩阵 C 是一个是对称矩阵,在线性代数中实对称矩阵有一系列非常好的性质:

  1. 实对称矩阵不同特征值对应的特征向量必然正交。
  2. 设特征向量λ重数为 r,则必然存在 r 个线性无关的特征向量对应于λ,因此可以将这 r 个特征向量单位正交化。

由上面两条可知,一个 n 行 n 列的实对称矩阵一定可以找到 n 个单位正交特征向量,设这 n 个特征向量为 ,我们将其按列组成矩阵: 

则对协方差矩阵 C 有如下结论:

其中Λ为对角矩阵,其对角元素为各特征向量对应的特征值(可能有重复)。

到这里,我们发现我们已经找到了需要的矩阵 P:P=ET

P 是协方差矩阵的特征向量单位化后按行排列出的矩阵,其中每一行都是 C 的一个特征向量。如果设 P 按照 Λ中特征值的从大到小,将特征向量从上到下排列,则用 P 的前 K 行组成的矩阵乘以原始数据矩阵 X,就得到了我们需要的降维后的数据矩阵 Y。

3.5补充数学推导过程

x 投影后的方差就是协方差矩阵的特征值。我们要找到最大方差也就是协方差矩阵最大的特征值,最佳投影方向就是最大特征值所对应的特征向量,次佳就是第二大特征值对应的特征向量,以此类推。至此我们完成了基于最大可分性的 PCA 数学证明.

3.6、PCA求解步骤

3.7、降维过程简单举例

以上关于PCA的数学推导过程每个参数的意义和运用都很难,因为几乎每个参数都涉及到高深的数学原理。为了参数的运用和意义变得明朗,我们来看一组简单的二维数据的降维。我们来看一组简单的二维数据的降维。

(1)我们现在有一组简单的数据,有特征x1和x2,三个样本数据的坐标点分别为(1,1),(2,2),(3,3)。我们可以让x1和x2分别作为两个特征向量,很轻松地用一个二维平面来描述这组数据。这组数据现在每个特征的均值都为2,方差则等于:

(2)每个特征的数据一模一样,因此方差也都为1,数据的方差总和是2。现在我们的目标是:只用一个特征向量来描述这组数据,即将二维数据降为一维数据,并且尽可能地保留信息量,
即让数据的总方差尽量靠近2。于是,我们将原本的直角坐标系逆时针旋转45°,形成了新的特征向量组成的新平面,方差为:
 

(3)通过旋转原有特征向量组成的坐标轴来找到新特征向量和新坐标平面,我们将三个样本点的信息压缩到了一条直线上,实现了二维变一维,并且尽量保留原始数据的信息。一个成功的降维,就实现了。

四、PCA算法实现

4.1算法步骤

标准化数据: 首先,对数据进行标准化,使得每个特征都具有相同的尺度。这可以通过减去均值并除以标准差来实现。



计算协方差矩阵: 根据标准化后的数据计算协方差矩阵。



特征值分解: 对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。



选择主成分: 选择最大的特征值对应的特征向量,构成主成分矩阵。



降维: 将数据投影到主成分矩阵上,实现降维。
4.2手动实现PCA
import numpy as np
import matplotlib.pyplot as plt

def manual_pca(X, num_components):
    # 1. 标准化数据
    mean_vals = np.mean(X, axis=0)
    std_vals = np.std(X, axis=0)
    standardized_X = (X - mean_vals) / std_vals
    
    # 2. 计算协方差矩阵
    cov_matrix = np.cov(standardized_X, rowvar=False)
    
    # 3. 计算特征值和特征向量
    eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
    
    # 4. 选择主成分
    sorted_indices = np.argsort(eigenvalues)[::-1]
    selected_indices = sorted_indices[:num_components]
    principal_components = eigenvectors[:, selected_indices]
    
    # 5. 将数据投影到主成分上
    reduced_X = np.dot(standardized_X, principal_components)
    
    return reduced_X, principal_components


# X 是数据矩阵,每一行是一个样本,每一列是一个特征
# num_components 是要保留的主成分数量
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 手动PCA
reduced_X, principal_components = manual_pca(X, num_components=2)


print("原始数据矩阵:\n", X)
print("\n降维后的数据矩阵:\n", reduced_X)
print("\n选定的主成分:\n", principal_components)

可视化:

4.3人脸识别降维

1.查看原图

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)
# print(faces.data.shape)
faces = fetch_lfw_people(data_home = "D:\\Download\\",download_if_missing=False,min_faces_per_person=60)
X = faces.data
#print(faces.data.shape)     (1348,2914) 1348是图像的个数
#print(faces.images.shape)   (1348, 62, 47)返回数据图片个数,每个数据特征矩阵行和列



fig, axes = plt.subplots(3,8
                         ,figsize=(8,4) #大小
                         ,subplot_kw = {"xticks":[],"yticks":[]} #不要显示坐标轴
                        )

#对axes对象进行处理
for i, ax in enumerate(axes.flat): #axes.flat后变成了一维
   ax.imshow(faces.images[i,:,:]  #索引为i的图,取出所有行和所有列,对应(1348, 62, 47)
             ,cmap="gray")
plt.show()

2.进行降维后的图像

pca = PCA(150).fit(X)
V = pca.components_
V.shape
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")
plt.show()

3.逆变换还原图像

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(data_home = "D:\\Download\\",download_if_missing=False,min_faces_per_person=60)
X = faces.data
pca = PCA(150)
X_dr = pca.fit_transform(X)

X_inverse = pca.inverse_transform(X_dr)

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")
plt.show()

结论

可以明显看出,这两组数据可视化后,由降维后再通过inverse_transform转换回原维度的数据画出的图像和原数据画的图像大致相似,但原数据的图像明显更加清晰。这说明inverse_transform并没有实现数据的完全逆转。这是因为,在降维的时候,部分信息已经被舍弃了,X_dr中往往不会包含原数据100%的信息,所以在逆转的时候,即便维度升高,原数据中已经被舍弃的信息也不可能再回来了。所以,降维不是完全可逆的。Inverse_transform的功能,是基于X_dr中的数据进行升维,将数据重新映射到原数据所在的特征空间中,而并非恢复所有原有的数据。但同时,我们也可以看出,降维到300以后的数据,的确保留了原数据的大部分信息,所以图像看起来,才会和原数据高度相似,只是稍稍模糊罢了。

五、总结

PCA的应用:

  • 降维: 通过去除冗余信息,减少数据的维度,提高计算效率和模型训练速度。

  • 特征提取: 选择主成分相当于选择了原始特征中最具代表性的信息,有助于提取关键特征。

  • 噪音过滤: PCA可以帮助去除数据中的噪音,提高模型的鲁棒性。

PCA的局限性:

  • 线性假设: PCA基于线性变换,可能无法很好地处理非线性关系。

  • 敏感性: 对异常值敏感,可能受到极端值的影响。

  • 23
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值