[吴恩达机器学习]12·主成分分析

吴恩达机器学习系列课程:https://www.bilibili.com/video/BV164411b7dx

参考文章:https://www.zhihu.com/question/41120789/answer/481966094

数据降维

我们的数据特征常常包含众多维度,但它们中的有些维度其实没有存在的必要。最极端的情况就是某一维度是其他若干维度的线性组合,那么这一维度就完全可以丢掉;但现实不会这么精准,如果某一维度是其他若干维度的线性组合加上微小的扰动,我们其实也可以将其丢掉。这就是数据降维。

数据降维有众多算法可以完成,主成分分析即是其中之一。

主成分分析

主成分分析(Principal Component Analysis)的基本思想是:假设原始数据的特征有 n 维,我们想将其缩减到 k 维,那么我们只需要在原来的 n 维空间中找到一个 k 维的子空间,使得所有数据到这个子空间的距离平方和最小;此时,原数据在这个子空间上的投影就是我们新的 k 维的数据。

数学推导

为方便,我们首先将数据中心化,即使得数据的平均值在原点处。一个获得所需要的 k 维子空间的简单方式是:找到一个合适的 n 维空间,直接选取前 k 维作为子空间。具体而言,对于一个数据点 x=[x1x2xn]Rn,设我们要找的 n 维空间的规范正交基为 u1,u2,,un,则 x 在其中的新坐标为: yj=xuj=x1uj1+x2uj2++xnujn 它到前 k 维形成的子空间(即以 为基底的子空间)的距离之平方为: 假设我们有 个数据 ,于是我们的优化目标为: 又由于在不同的基下 都是一个定值,于是最小化上述距离等价于: 其充分条件为: 这就是我们要解决的问题。


由于 这是一个正定二次型, 是一个正定矩阵,可以进行奇异值分解: 其中, 是正交矩阵, 是对角矩阵 是奇异值,.

,由于 正交,所以 也是单位向量,代回得到: 所以我们的优化目标变成了: 很显然,它的解是:,即 。又由于 所以我们要找的 维空间的各个基向量就是矩阵 的各个奇异值对应的奇异向量,我们要降维到的 维子空间的各个基向量就是前 个奇异向量,对原来的数据进行基变换,就得到了降维后的数据。

步骤总结

总结一下,主成分分析的推导过程稍显复杂,但是它的实现很简单,主要是以下步骤:

  1. 计算矩阵

    更简单的表达是:设矩阵 为数据集,那么计算矩阵 即可。

  2. 进行奇异值分解,得到奇异向量;

  3. 选取前 个奇异向量作为降维后的空间的基向量,构成基变换矩阵

  4. 对于原数据 ,取 为其降维后的数据。

    更简单的表达是:取 ,则 是降维后的数据集。

主成分数量的选择

那么在实践中,我们到底选择多大的 值比较好呢?对此,我们定义一个平均误差为: 其中, 表示数据 在我们找到的 维子空间上的投影。再定义一个总方差为: 则一般的,我们会选择最小的 使得: 并称之为「 的方差得以保留」。

这个式子看起来并不好计算,但事实上,借助我们的奇异值,可以证明,对于给定的 这就好算了。

实现

二维压缩为一维

二维平面上的原始数据:

主成分分析代码:

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
def PCA(X, dim = -1):
"""
X is the input data: (m, n)

dim is the dimension after reduction
if dim=-1, then the program select the smallest dim
such that 99% of variance is retained

return the data after reduction: (m, dim)
and the data recovered from reduced data: (m, n)
"""
Xmean = np.empty((1, X.shape[1]))
Xstd = np.empty((1, X.shape[1]))
def normalization(X, k):
global Xmean, Xstd
if k == 1:
Xmean = np.mean(X, axis=0)
Xstd = np.std(X, axis=0, ddof=1)
return (X - Xmean) / Xstd
else:
return X * Xstd + Xmean

Xnorm = normalization(X, 1)
u, s, v = np.linalg.svd(Xnorm.T @ Xnorm)
if dim == -1:
dim = 1
while s[:dim].sum() / s.sum() < 0.99:
dim += 1
return Xnorm @ u[:, :dim], normalization(Xnorm @ u[:, :dim] @ u[:, :dim].T, 0)
PYTHON

得到映射的点:

人脸特征压缩

我们给出了 张人脸照片,每张照片含有 的灰度像素,形成维度为 的向量作为其特征。前 张照片如图所示:

现在将其压缩为 维的数据,恢复后结果如下:


[吴恩达机器学习]12·主成分分析
https://xyfjason.github.io/blog-main/2021/01/26/吴恩达机器学习-12·主成分分析/
作者
xyfJASON
发布于
2021年1月26日
许可协议