查看全课大纲(第 68 / 82 节)
- 1.函数与数据泛化
- 2.向量:从几何直觉到高维空间
- 3.矩阵与张量
- 4.特征值与特征向量:矩阵变换的不动方向
- 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
- 6.概率与统计:机器学习的数学基础
- 7.独立性与随机变量:贝叶斯公式与二项分布
- 8.期望、方差与协方差:随机变量的数字画像
- 9.联合概率:当一条轴不够用的时候
- 10.概率分布(一):从伯努利到伽马函数
- 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
- 12.机器学习的模型:找输入与输出的关系
- 13.机器学习的应用
- 14.过拟合
- 15.机器学习的分类
- 16.有监督学习:从房价预测说起
- 17.损失函数
- 18.梯度下降(上):更新规则与学习速率
- 19.梯度下降(2)
- 20.牛顿方法
- 21.KNN简介
- 22.距离测算
- 23.朴素贝叶斯
- 24.朴素贝叶斯的实际应用
- 25.信息熵:决策树构建的度量基础
- 26.信息增益与决策树的构建
- 27.ID3算法
- 28.决策树节点的划分
- 29.CART树
- 30.Bagging
- 31.Boosting:自适应提升算法
- 32.Gradient Boosting
- 33.线性模型:回归与分类的同一副骨架
- 34.最小二乘:把最优参数直接解出来
- 35.最小二乘法的几何与概率视角
- 36.极大似然:给最小二乘一个概率出身
- 37.逻辑回归(1):把线性模型接到分类上
- 38.逻辑回归(2):损失函数与多分类
- 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
- 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
- 41.优化方法(1):坐标下降与前向选择
- 42.优化方法(2):前向策略与最小角回归
- 43.拉格朗日乘子法(1):从无约束到等式约束
- 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
- 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
- 46.最大间隔:把分类问题变成优化问题
- 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
- 48.支持向量:边界上的少数派
- 49.SVM 计算过程:一笔到底算完,再走进核方法
- 50.贝叶斯公式:概率即信念
- 51.隐含变量和概率模型:给看不见的原因建模
- 52.EM 算法:期望与最大化的迭代
- 53.琴生不等式:EM 的数学钥匙
- 54.三个硬币问题:EM 的复盘与衔接
- 55.高斯混合模型:用隐变量解释双峰数据
- 56.隐马尔可夫模型
- 57.隐马尔可夫模型(2):前向算法与动态混合模型
- 58.隐马尔可夫模型在 NLP 中的运用
- 59.EM 算法:把「为什么收敛」推到底
- 60.HMM 在 NLP 中的运用:从分词到机器翻译
- 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
- 62.高维下的高斯模型
- 63.主题模型:从词袋到隐含主题
- 64.Dirichlet 分布(1)
- 65.Dirichlet 分布(2)
- 66.统计学习内容回顾
- 67.K-means 算法
- 68.PCA 降维
- 69.SVD 降维
- 70.从聚类到流形
- 71.局部线性嵌入
- 72.随机邻域嵌入:SNE 与 t-SNE
- 73.无参模型:让数据自己说话
- 74.高斯过程:函数空间里的正态分布
- 75.高斯过程(2):噪声、正则化与核的线性组合
- 76.神经网络简介:从感知器到自编码器
- 77.反向传播:把误差一层层传回去
- 78.卷积神经网络(CNN):让特征自己学出来
- 79.循环神经网络(RNN):给网络装上记忆
- 80.深度学习回顾:静态一类,动态一类
- 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
- 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传
PCA 降维
约 28 分钟
小象实战讲义 · 机器学习算法精讲
上一节我们讲完了最简单的聚类算法 K-means。无监督学习还有很大的一块——降维(dimension reduction)。面对动辄成千上万维的数据,我们能不能「乘一个矩阵」就把它压小、还尽量不丢信息?本节讲最经典、应用最广的降维算法:主成分分析(PCA)。它要做的事一句话就能说清——找到数据分布最「开阔」的那条轴,把所有点投影上去。
💡 核心导读
- 降维 = 乘一个矩阵: 维数据乘上一个 的变换矩阵 (),本质是高维到低维的线性投影。
- 为什么压:对抗维度的诅咒(curse of dimensionality)、剔除冗余与噪声维度——信号处理里大部分信号都是冗余的。
- PCA 的直觉:二维数据投影到一维,往长轴上映射是好选择(不同点还散得开),往短轴上映射是差选择(一堆点挤成一个点)。
- 四步算法:去中心化 → 算协方差矩阵 → 特征值分解 → 取最大特征值对应的特征向量做投影。
- 零损失的极限:当数据完美落在一条线上,第二特征值恰为 0——一个维度被另一个完全线性表出,压掉它一点信息都不损失。
为何需要降维:乘一个矩阵的事
先把降维这件事的形态看清楚。给定最原始的数据——original data,它是 维空间里的高维数据。我们可以给它乘上一个矩阵 ——一个 transform 矩阵,维度是 。矩阵乘上去之后,它就变成了一个 维的数据。当然我们认为 是远小于 的。
这种形式,就是通过一种线性的方式,把原先的 压缩到 ——,把高维空间的数据映射到低维空间。这种线性变换其实有个特别简单的描述:在高维空间里,通过投影的方式把数据投到低维空间。大家可以想象:二维空间里的一个面,可以映射到某条线上;线再映射到线段上——一个 shadow(影子),这就是投影。
那做这个压缩的目的是什么?两点:
- 对抗维度的诅咒。在高维空间里数据太繁琐,有 curse of dimensionality(维度的诅咒),所以我们希望尽量保留原有的信息、尽量减少信息的损失,再去做一个很好的线性映射。
- 关键信息往往藏在低维里。很多情况下你会发现,数据虽然很高维,但起到关键作用的部分往往是低维的。信号处理里有个经验:大部分信号其实都是冗余信号——所以才有了稀疏编码(Sparsity Coding)、后来的压缩感知(Compressive Sensing),它们都是想在复杂信号里找到最重要、最核心的那部分。
而 的选择本身就是一门学问。假设 和 都已经确定——从 维压到 维——怎么压?选什么样的矩阵? 这就需要一个标准,这个标准就是减少信息的损失。我们这一节要讲的 PCA,它定的标准是:保持原有数据的方差最大。
哪些维度是「头发长度」:数据里的冗余
什么时候压得动、什么时候压不动?讲师用了一个贯穿全段的例子——预测小学生的考试成绩。
先看哪些维度是纯噪声。头发的颜色——越黑的小朋友学得越好?你会发现没有什么关联。那头发的长度呢?听起来也没有关联,但你拿实际数据一算,还真有正相关:长头发的小朋友,一般学习好一点。但这并不是头发长度的功劳——它侧面上暴露了另一件事:长头发的小朋友经常是小女孩,而小学生阶段的小女孩特别听话、特别认真,考试这种形式特别适合她们,所以成绩好一些。主要原因是性别,还真不是头发长度。你想想:同样都是小女孩,有长发有短发——你区分不出头发更长的就成绩更好。
所以在这种程度上,有些维度会引入更多的噪声。对于预测学习成绩这件事,头发长度、头发颜色这两个维度就可以全部压缩掉。压缩有两种方式:一种直接剔除;另一种是在线性变换里把这个维度的权重减小。
权重是什么意思?把 维数据的每一维排开:第一维、第二维、第三维……一直到第 维。乘上矩阵 的时候, 的每一行就是一个权重向量 ,每个分量对应一个原始维度。权重的大小,就代表你对那个维度特征的重视程度。假如第三维是「每天学习时间」——重要——那对应的权重 就会比较大;第一维是「头发长度」——不重要——那对应的 可能就只有 0.005 甚至更小。压缩时,不重要的维度就被压到一个很小的空间里去。也可以理解为:在调整、旋转这个子空间的时候,偏向重要的特征方向去旋转,而不是偏向不重要的。
(此处原为课件图示,现用文字描述:一份数据在两个维度上作散点。三种典型形态——第一种,一个维度上的取值完全随机,散点铺满整个平面,两个维度互不表示;第二种,两个维度明显负相关,散点呈一条下倾的带状;第三种,散点几乎完美落在一条直线上。)
散点图上通常有三种形态:
- 随机:两个维度各走各的,谁也说不清谁;
- 负相关:讲师举的例子是玩游戏时长与学习成绩——玩游戏时间越长、成绩越差,不绝对、不是严格的反比,但趋势明显。某些压缩会损失一些信息,但大量的信息得以保留;
- 完美落线:几乎可以完美地落在一条线上。这时其中一个维度的信息,可以完全用另外一个(或几个)维度的线性变换表示——这个维度就是冗余(redundant)的,直接通过映射去掉它。反过来,第一种形态里一个特征没办法用其他特征表示,每个信息都很重要。(讲师讲到这先说「A 的冗余信息比较多」,马上自我纠正:「啊,错了 Sorry,是 C 的」——完美落线的那种才是冗余最重的。)
再感受一下高维数据有多吓人。人脸图像是高维像素矩阵,但这都不算高——想象一个视频:一秒 24 帧,每一帧假设是 的(讲师口算先说成 400,当场纠正:Sorry, 是 4000 个点),每个点有 RGB 三个通道,那就是一帧 12000 个数据,一秒再乘上 24——接近 30 万个数据。这么庞大的数据,怎么有效地压缩、还能看到图像里最重要的内容?这就是我们要研究的部分。做 face recognition 的人都知道:同一个人在不同表情、不同光照、不同角度下,还是那一个人——我们要把高维空间里最核心的部分提取出来。识别一个人的时候,面目特征比「这张照片的光照特点」重要得多。
(至于「哪些特征重要」这件事,讲师顺带提了一句:现在也可以自动地通过深度学习去学到——与本课程 11.4 里对深度学习的诚实对照呼应;PCA 则代表了另一条路:用数学标准显式地把这个「重要」定义出来。)
往长轴上投影:PCA 的直觉
第一个要讲的降维算法叫 Principal Component Analysis。principle 是「主」,component 是「成分、部分」——找到最重要的组成部分来分析,中文叫主成分分析法。它是一个非常 classical 的 multivariate method(多变量分析)——统计里叫多变量分析或高维变量分析,机器学习里很多最原始的东西,都是从 Multivariate Analysis 这边来的。
它是卡尔·皮尔逊(Karl Pearson)1901 年首先研究的,后来 Harold Hotelling 在 1933 年独立发展。皮尔逊这个人特别有意思:他 1911 年在 UCL(University College London)建立了世界上第一个大学统计系——他意识到统计可以应用到政治、经济、社会、文化、水文、天文等各个方面,是很重要的应用数学分支。到今天,UCL 仍然是英国计算机、统计方向最好的学校之一:DeepMind 的创始人 Hassabis 就是在 UCL 读的博士,David Silver、DeepMind 的很多人,都跟 UCL 和 Edinburgh 有很大关联。英国最好的学校当然是牛津剑桥,但做 AI、机器学习的很多人,来源恰恰是 UCL、Edinburgh 这些学校。
那 PCA 的道理是什么?拿最简单的二维数据来看:把它压缩到一维,投到哪条线上?大家可以先想一个极端问题:如果压缩到零维,是什么东西?——不用想了,所有东西都是一个点。零维空间就是一个点,甚至你没有数据、做了压缩之后还是这个点。一维空间是一条线,线上有些区域有数据、有些没有。二维是个面。现在我们要把面里的数据映射到一条线上去,还得保住数据的基本特性——什么样的映射算好?
原始空间里不同的数据,映射之后还是不同的点——这就代表原始数据的某些特性得以保留。往哪个方向映射能做到这一点?你会发现:往长轴方向映射时,原本不同的数据点大多还散得开;而往短轴(比如横着的那条线)方向映射,数据全被压进一个很小的区域——实际上原始空间里可能有 10 个、8 个点被映射到了同一个点上;而往长轴上映射,只有大概两三个、四五个点撞到一起。往长轴上映射是更好的选择,往短轴上是差的选择——这就是我们的直觉。(二维是这样,三维就是在空间中的一堆点里找一个最合适的面,把点都映射到那个平面上去。)
把这个直觉翻成数学标准就是课件里给 PCA 的两条准则:投影后保留的方差最大化;同时最小二乘重构误差最小化(从投影还原回去,丢的平方误差最小)。有了直觉,接下来就是怎么通过数学的方法,把这个「最好的方向」学出来。
PCA 的四步:均值、协方差、特征分解、投影
在讲步骤之前,先回顾一件老事:线性变换主要就是通过矩阵乘积来压缩,而矩阵最重要的两个特征,就是它的特征向量和特征值。给定矩阵 、向量 ,乘上矩阵变成 ;如果 恰好落在 的特征向量方向上,那么乘上 就代表在这个方向上扩大 倍——这个倍数就是对应的特征值。(这是整个课程第一次课讲线性代数时给过的图景,忘记的同学可以回去复习。)
第一步:减去均值(去中心化)
给定了最原始的数据——比如 11 个数据(课件里的例子是 个对象),每个是二维的。第一件事:求它的均值。均值 本身是一个二维向量,比如大概在 这个位置;然后每一个数据都减去均值。减完之后,均值就变成了 ,所有数据都围着原点基本均等地分布。
第二步:算协方差矩阵
现在要求这个新矩阵(每个点都减完均值之后)的协方差矩阵 (covariance matrix)。先回忆协方差怎么写。方差 variance 是:
协方差就是把它推广到两个变量——「co」表示两者相差相交的关系:
现在是两个维度 、,就可以求一个 的协方差矩阵。板书上是这么摆的——四个元素:
对角线 、 是各自的方差;、 是两个方向的协方差。 跟 的协方差和 跟 的是一样的——因为这两部分可以互相调换、左右相乘——所以这个矩阵一定是对称的。板书上这个例子:非对角是 0.615 和 0.615(对称),一个对角线元素 0.716 代表 方向自己的方差。
第三步:特征值分解
有了协方差矩阵,做一件非常简单的事:求它的特征向量和特征值。(讲师说「求它的特征值和特征根」,随即自我纠正——特征根就是特征值的旧称,同一个东西。)这个矩阵最多有两个特征对。板书例子的完整数字如下(对角 0.716 与非对角 0.615 为逐字稿口播数字,另一个对角 0.616 由板书特征值 1.28 与 0.049 反推重建):
用代码把这个板书例子的特征分解完整算一遍—— 对称矩阵用迹(trace)和行列式(det)的求根公式手算即可,不依赖任何库:
import math
# 板书例:11 个二维数据减去均值后的协方差矩阵
# (0.615 / 0.716 为逐字稿口播数字,0.616 由特征值 1.28 与 0.049 反推重建)
C = [[0.616, 0.615],
[0.615, 0.716]]
# 对称性检查:X 跟 Y 的协方差 = Y 跟 X 的协方差
print(f"对称性检查: C[0][1] = {C[0][1]}, C[1][0] = {C[1][0]}")
# 2x2 特征值:lambda^2 - trace*lambda + det = 0 的求根公式
trace = C[0][0] + C[1][1]
det = C[0][0] * C[1][1] - C[0][1] * C[1][0]
disc = math.sqrt(trace * trace - 4 * det)
lambda1 = (trace + disc) / 2
lambda2 = (trace - disc) / 2
print(f"trace = {trace:.4f}, det = {det:.4f}")
print(f"lambda1 = {lambda1:.4f} (讲师板书: 约 1.28)")
print(f"lambda2 = {lambda2:.4f} (板书: 约 0.049, 口播读作 0.49)")
# 特征向量 v1: 解 (C - lambda1*I) v = 0, 取 v = [C12, lambda1 - C11] 再归一化
v1 = [C[0][1], lambda1 - C[0][0]]
norm = math.sqrt(v1[0] ** 2 + v1[1] ** 2)
v1 = [x / norm for x in v1]
v2 = [-v1[1], v1[0]] # 与 v1 正交的第二个特征向量
print(f"v1 = [{v1[0]:.4f}, {v1[1]:.4f}] (课件 Page 11: 约 [-0.677, -0.735], 同一条方向线)")
print(f"v2 = [{v2[0]:.4f}, {v2[1]:.4f}]")
# 三项核验: 单位长度 / 互相垂直 / Cv = lambda*v 回代
print(f"|v1| = {math.sqrt(v1[0]**2 + v1[1]**2):.4f}, |v2| = {math.sqrt(v2[0]**2 + v2[1]**2):.4f}")
print(f"v1.v2 = {v1[0]*v2[0] + v1[1]*v2[1]:.4f}")
Cv1 = [C[0][0]*v1[0] + C[0][1]*v1[1], C[1][0]*v1[0] + C[1][1]*v1[1]]
print(f"Cv1 = [{Cv1[0]:.4f}, {Cv1[1]:.4f}] = lambda1*v1 = [{lambda1*v1[0]:.4f}, {lambda1*v1[1]:.4f}]")
# 方差分配: 两个特征值之和 = 总方差, lambda1 就是投影到 v1 后的方差
print(f"第一主成分保留的方差比例: {lambda1 / trace:.4f}")对称性检查: C[0][1] = 0.615, C[1][0] = 0.615
trace = 1.3320, det = 0.0628
lambda1 = 1.2830 (讲师板书: 约 1.28)
lambda2 = 0.0490 (板书: 约 0.049, 口播读作 0.49)
v1 = [0.6779, 0.7352] (课件 Page 11: 约 [-0.677, -0.735], 同一条方向线)
v2 = [-0.7352, 0.6779]
|v1| = 1.0000, |v2| = 1.0000
v1.v2 = 0.0000
Cv1 = [0.8697, 0.9433] = lambda1*v1 = [0.8697, 0.9433]
第一主成分保留的方差比例: 0.9632几何上:协方差矩阵的两个特征向量 、,长度代表对应 的大小—— 对应的方向比 的长(实算 1.2830 对 0.0490)。我们要投的,就是 这个方向。(课件 Page 11 印的 ,与实算的 是同一条方向线的两端——特征向量取正向取负向是同一个方向;逐字稿口播「0.677 和 −0.753」里的 0.753 是 0.735 的口误。)
第四步:排序、选方向、投影
特征值从大到小排列: 的问题就是 从大到小排。板书例只有两个值:1.28 和 0.049——很显然 1.28 大,保留 这个方向,每个数据乘上 ,就压缩到一维空间里去了。刚才那 11 个数据,都比较完美地映射到了 这条线上——这条线保证投影后的方差最大;往横线上、往其他方向上映射,都不是好选择。
- 三维压到一维:取最大的 对应的 ;
- 三维压到二维:去掉最小的 ,保留 对应的 ——它们两个构成的那个矩阵,就是我们刚才说的转移矩阵 ,所有数据乘上它,就映射到 所代表的新二维空间。
原始数据多少维、要压到多少维,就选多少个最大的 对应的特征向量。 而且 和 一定是垂直的——对称矩阵不同特征值的特征向量相乘为 0,orthogonal(上面的实算也验证了 )。课件还补了一个很好的性质:如果保留的维数 等于数据的秩 rank(X),就没有任何信息损失——下面用代码亲眼看一次这个「零损失」什么时候发生。
均值、方差、标准差:一段直觉回顾
把这几个量在几何上再看一眼:均值相当于期望,就是这一堆点的中心点。方差呢?每一个点到中心点做一个距离,把所有距离的平均值求出来——那是标准差;这些距离平均的平方,就是方差。一堆数据、一个中心点、每个点拉一条线到中心——这就是均值和方差该有的画面感。
完美落线:冗余维度的零损失压缩
回到前面三种数据形态里「完美落线」的那一种——它值得用代码亲手验证一次。取 4 个点,恰好落在 这条直线上(一维信息用两维存放),完整走一遍 PCA 的四步:
import math
# 「完美落线」数据: 4 个点恰好在 y = 2x 上
X = [[0, 0], [1, 2], [2, 4], [3, 6]]
N = len(X)
# 第一步: 去中心化
mean = [sum(X[i][j] for i in range(N)) / N for j in range(2)]
Xc = [[X[i][j] - mean[j] for j in range(2)] for i in range(N)]
print("去中心化后的数据:")
for row in Xc:
print(" ", [f"{v:.1f}" for v in row])
# 第二步: 协方差矩阵 (N-1 分母)
C = [[sum(Xc[k][i] * Xc[k][j] for k in range(N)) / (N - 1) for j in range(2)] for i in range(2)]
print("协方差矩阵:")
for row in C:
print(" ", [f"{v:.4f}" for v in row])
# 第三步: 特征分解 (2x2 求根公式)
trace = C[0][0] + C[1][1]
det = C[0][0] * C[1][1] - C[0][1] * C[1][0]
disc = math.sqrt(trace * trace - 4 * det)
lambda1, lambda2 = (trace + disc) / 2, (trace - disc) / 2
print(f"lambda1 = {lambda1:.4f}, lambda2 = {lambda2:.4f}")
# 第四步: 投影到第一主成分
v1 = [C[0][1], lambda1 - C[0][0]]
norm = math.sqrt(v1[0] ** 2 + v1[1] ** 2)
v1 = [x / norm for x in v1]
print(f"v1 = [{v1[0]:.4f}, {v1[1]:.4f}] (正是 y=2x 方向的单位向量 (1,2)/sqrt(5))")
Y = [sum(Xc[i][j] * v1[j] for j in range(2)) for i in range(N)]
print(f"压缩到 1 维后的数据: {[f'{y:.4f}' for y in Y]}")
# 对比: 给 y 加一点噪声再算一遍
Xn = [[0, 0.1], [1, 1.9], [2, 4.1], [3, 5.9]]
meann = [sum(Xn[i][j] for i in range(N)) / N for j in range(2)]
Xcn = [[Xn[i][j] - meann[j] for j in range(2)] for i in range(N)]
Cn = [[sum(Xcn[k][i] * Xcn[k][j] for k in range(N)) / (N - 1) for j in range(2)] for i in range(2)]
tracen = Cn[0][0] + Cn[1][1]
detn = Cn[0][0] * Cn[1][1] - Cn[0][1] * Cn[1][0]
discn = math.sqrt(tracen * tracen - 4 * detn)
l1n, l2n = (tracen + discn) / 2, (tracen - discn) / 2
print(f"加噪声后: lambda1 = {l1n:.4f}, lambda2 = {l2n:.4f} (微小的 lambda2 就是噪声的方差)")
print(f"第一主成分保留的方差比例: {l1n / tracen:.4f} (大量信息保留, 压掉的只是噪声)")去中心化后的数据:
['-1.5', '-3.0']
['-0.5', '-1.0']
['0.5', '1.0']
['1.5', '3.0']
协方差矩阵:
['1.6667', '3.3333']
['3.3333', '6.6667']
lambda1 = 8.3333, lambda2 = 0.0000
v1 = [0.4472, 0.8944] (正是 y=2x 方向的单位向量 (1,2)/sqrt(5))
压缩到 1 维后的数据: ['-3.3541', '-1.1180', '1.1180', '3.3541']
加噪声后: lambda1 = 8.0778, lambda2 = 0.0022 (微小的 lambda2 就是噪声的方差)
第一主成分保留的方差比例: 0.9997 (大量信息保留, 压掉的只是噪声)三个看点:
- (实算印出 0.0000——真实值是 量级的浮点毛边,比第一特征值小 16 个数量级;8.3 节见过它落成 的兄弟,本质都是机器零)。协方差矩阵是奇异的—— 这一维的信息完全被 线性表出(),这就是「完美落线」的数学形态:保留维数 恰好等于数据的秩 rank,压缩到一维,零信息损失。
- 正是直线方向 的单位向量——PCA 找到的「最重要的方向」,就是数据铺开的那条线。
- 加了一点噪声( 各偏 )之后, 变成微小的 0.0022——噪声被隔离在第二主成分里,第一主成分保留 99.97% 的方差。这就是「压缩损失少量信息、保留大量信息」的定量版本。
手写数字降到二维:PCA 真的管用
课件里还有一段 pseudo code,讲师明说不展开细讲——「任何代码里边都会有这种实现」。但例子值得看:用 PCA 做手写数字(MNIST 那样的数据)的投影,把每个手写数字的高维像素降到二维。你会发现,即使这么复杂的问题压到二维空间里:这一片区域是 3、那一块是 1、这边是 0、4 在那边、5 在中间——大的区域仍然各自聚在一起,在二维空间里仍然能看出这些数据的特征。这说明两件事:第一,这些数据之间的特征本身比较明显;第二,我们确实找到了一个比较好的投影方向。
PCA 用特征值分解把「最重要的方向」找了出来;而实际计算中它还有一个更稳定的数值搭档——奇异值分解(SVD),它跟降维的关系比这里展示的更深。这正是下一节的主角。
📝 动手练一练
- 概念辨析:三份数据的协方差矩阵如下,哪一份存在「一个维度可以完全用另一个维度线性表示」的关系?哪一份压缩到一维会零信息损失?为什么剩下那份每个维度都动不得?
👉 点击查看参考答案
丙存在完全线性表出的关系:两行完全相同,行列式 ,矩阵奇异,——正是代码里「完美落线」的形态(),压缩到一维零信息损失(保留维数等于秩)。乙是强负相关(「玩游戏时长 vs 成绩」的形态): 一大一小,压到一维会损失少量信息但保留大部分。甲两个维度互不相关、方差相等,任何一个维度都无法用另一个表示——每个信息都重要,硬压到一维就要丢掉整整一半的方差。
- 手动演算:对协方差矩阵 手算特征值和特征向量,并把去中心化后的数据点 投影到第一主成分上。
👉 点击查看参考答案
迹 ,行列式 。特征方程 ,即 ,得 。对 : 给出 ,即 ,归一化后 ; 与之正交:。投影:。投影后方差为 ,占比 。
本章小结
PCA 是无监督降维里最经典的方法:先把数据减去均值(去中心化),算出对称的协方差矩阵,做特征值分解,把特征值从大到小排序,取前若干个最大特征值对应的特征向量构成投影矩阵——每一个特征值,就是数据投影到对应特征向量方向后的方差;要压到多少维,就取多少个。它的准则是双生的:投影后保留的方差最大、最小二乘重构误差最小。数据越「完美落线」,压得越无损;数据越随机,每个维度越动不得。
📋 行动清单
- 复习第一课:特征值、特征向量的几何含义(:乘矩阵等于在特征向量方向上伸缩 倍)——讲师原话「忘记的话可以看我们整个课程的第一次课」。
- 手动演算:把练一练第 2 题完整推一遍,再用本节的求根公式代码核对自己的手算结果。
- 思考应用:找一份你熟悉的数据(用户行为、图像、成绩单),想想哪些维度是「头发长度」式的伪相关维度?哪些是「玩游戏时长」式的强相关维度?PCA 会把哪一维压掉?
- 预习下一节:SVD(奇异值分解)——PCA 在实际计算里最稳定的数值搭档,也是下一节的主角。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第16章课件:无监督学习(k-means/PCA/SVD/Isomap)