第七部分 · 表示与几何
SVD 与 PCA:把高维数据压扁而不失真
特征向量给了方阵一副骨架,但真实数据矩阵又长又方、还带噪声,特征分解直接用不了。这一课我们把"找主轴"推广到任意矩阵,再用它把几百维的数据压成几维——丢掉的几乎全是噪声,留下的几乎全是信息。
留下的问题:可特征分解有个死穴——Av = λv 要求 A 是方阵。而现实里的数据矩阵几乎从不是方阵:一万张图、每张一千个像素,那是 10000×1000 的长方形;一千个用户、各五十个特征,那是 1000×50。对一个又长又方、还脏兮兮的矩阵,怎么找它的主轴?而且维度这么高,能不能砍掉一大半还几乎不丢东西?
本课新增:奇异值分解(SVD)——任何矩阵都能拆成"旋转 → 沿轴拉伸 → 旋转";以及主成分分析(PCA)——沿数据摊得最开的方向投影,把高维压低维。
特征分解为什么卡住了
上一课的 Av = λv 漂亮,但它默认变换把空间映回自己——输入输出同维,所以矩阵是方的。可数据矩阵 A 是 m × n(m 个样本、n 个特征),它代表的是"从 n 维映到 m 维",进出维度都不一样,根本谈不上"方向不变"——一支箭从 n 维出发,落到的是另一个空间,没法跟自己比。
但"找主轴"这个念头不该就此放弃。退一步想:哪怕进出空间不同,一个变换总该有它最使劲的几个方向吧——某些输入方向被它放得最大,某些被压得最小。这就是 SVD 要捕捉的东西。它不要求"方向不变",只问:哪些互相垂直的输入方向,被映成了互相垂直的输出方向,各自放大了多少倍?
SVD:任何矩阵 = 旋转 · 拉伸 · 旋转
奇异值分解的断言惊人地干净:任何矩阵 A(哪怕又长又方)都能写成三个简单变换接力:
A = U Σ Vᵀ (读作"A 等于 U 乘 Σ 乘 V 的转置")
逐块读懂这三步——把它想成对一个箭依次做三件事:
- Vᵀ(读作"V 转置"):一次旋转。它把输入空间转到一套"恰当的"互相垂直的坐标轴上,不改变长度,只摆正方向。
- Σ(读作"sigma",大写):一次纯拉伸。它是个对角矩阵,沿每根新轴各乘一个数 σ₁, σ₂, …(读作"sigma 1, sigma 2…")。这些数叫奇异值,全都 ≥ 0,而且从大到小排好队。维度不够的部分在这一步被补零或截断。
- U:又一次旋转,把拉伸后的结果摆进输出空间。
换句话说,世上没有"乱七八糟"的线性变换。任何一个,剥开来看都只是"转一下 → 沿几根互相垂直的轴各拉一拉 → 再转一下"。剪切、投影、压扁……所有复杂相,全是这三步的合成。这是线性代数最深的结构定理之一,比特征分解更普适——它对每个矩阵都成立,不挑方阵、不挑对称。
奇异值排队,扔掉小的 = 低秩近似
奇异值从大到小排队这件事,是整堂课的发动机。σ₁ 告诉你"这个变换最使劲的方向放大了多少倍",σ₂ 是第二使劲的……越往后越小,到后面常常是接近 0 的零碎。
于是有个大胆的主意:只保留前 k 个最大的奇异值,把后面的小尾巴全设成 0。这样重建出来的矩阵 Aₖ,秩只有 k(回扣上一课的"秩"——它只活在一个 k 维子空间里),却最大限度地逼近原矩阵。数学上有个漂亮的保证(Eckart–Young 定理):在所有秩为 k 的矩阵里,这个截断 SVD 是离原矩阵最近的——没有比它更好的低秩近似了。
这就是低秩近似,也是压缩的灵魂:图像压缩、推荐系统补全用户没打过的分、把一个巨大词向量表压小……背后都是"留大奇异值、砍小奇异值"。被砍掉的小奇异值方向,通常正是噪声和无关细节所在——所以压缩往往还顺手去了噪。
换个视角:PCA 找数据"摊得最开"的方向
现在把镜头从"矩阵"转向"数据云"。设想平面上一团点(每个点是一个二维样本),它们不是均匀散开的,而是沿某个斜方向拉成一条胖椭圆——这说明两个特征是相关的。问题来了:如果只准保留一个数来描述每个点,该怎么选这个"方向"才丢得最少?
直觉是对的:选数据摊得最开(方差最大)的那个方向。把所有点投影到这条线上,它们彼此还离得最远、最分得清——保留的信息最多。这条方向叫第一主成分 PC1。然后在与它垂直的方向里,再找摊得第二开的,叫 PC2……主成分一根根都互相垂直,按"摊开程度"排队。这套操作就是主成分分析(PCA):给数据云重新找一套贴身的、互相垂直的坐标轴。
注意 PCA 和 SVD 是同一件事的两副面孔。把数据先中心化(每个特征减掉它的均值),再做 SVD:右奇异向量(V 的列)就是主成分方向,奇异值的平方就是各方向上的方差。"摊得最开的方向"=最大奇异值方向,分毫不差。"砍掉小奇异值"=扔掉方差最小、最不值钱的几根主成分=降维。SVD 是引擎,PCA 是它在数据分析里的名字。
主成分就是协方差矩阵的特征向量
这里,上一课埋的那句话终于兑现。怎么量"数据沿各方向怎么一起波动"?用协方差矩阵 C(它的第 i 行第 j 列,是第 i 个特征和第 j 个特征一起波动的程度)。它是个对称矩阵——而上一课我们证过:对称矩阵的特征向量互相垂直、特征值全是实数。
把这两件事拼起来:协方差矩阵的特征向量,就是主成分方向;对应的特征值,就是数据在那个方向上的方差。"互相垂直"保证了主成分确实是一套干净的正交轴;"特征值=方差"保证了"特征值大=摊得开=信息多"。上一课你可能觉得"对称矩阵正交特征向量"只是个漂亮性质,这一课它直接变成了从数据里提取主结构的整套机器。这就是线性思维的回报——前面铺的每块砖,后面都要踩上去。
降维:用几维冒充几百维
把这套搬到高维,就是机器学习天天在做的事。一张人脸照片是几千维(每个像素一维),但人脸的"真正自由度"——光照、姿态、表情——其实只有几十个。对一堆人脸做 PCA,前几十个主成分(著名的"特征脸")就能重建出认得出的脸,几千维压到几十维,丢的几乎全是噪声。
降维的回报是多重的:省存储、省算力(维度少了)、去噪(噪声多藏在被砍掉的小方差方向里)、能可视化(压到二三维就能画出来看)、还能缓解后面要讲的"维度灾难"。我们当年补线性代数是为了"一次处理很多维";这一课反过来——一次砍掉很多没用的维。能这么砍,全靠数据真实地活在一个低维子空间附近,而 SVD/PCA 正是把那个子空间找出来的工具。
常见误解
- "PCA 是在挑选最重要的几个原始特征。"不是挑选,是重新组合。主成分是原始特征的线性混合(一根新轴=原始各特征按某些权重加起来),是新造的坐标轴,而不是从原有列里选几列。所以降维后的维度通常没有直白的现实名字,但它们最大限度地装住了方差。
- "方差大的方向一定最有用。"PCA 的全部假设是"方差大=信息多",这常常对,但不总对。如果你真正关心的差异恰好藏在一个低方差方向里(比如类别的细微区别),PCA 可能会把它当噪声砍掉。PCA 是无监督的——它只看数据怎么摊开,不看你的标签或目标。用之前先想清楚"方差"是不是你要的那种"重要"。
- "用 PCA 前不用管量纲。"大错。方差对单位极其敏感:把一列"身高"从米换成毫米,它的方差暴涨一百万倍,PCA 就会被它绑架、第一主成分几乎只剩这一列。所以做 PCA 前通常要标准化(每列除以自己的标准差),让各特征站在同一起跑线,否则你量出来的"最大方差方向"只是"单位最大的那一列"。