方差一路涨,精度过了50 维就往下走。这篇课教的是降维,而它自己的练习题里藏着"降维是方差的排名,不是答案的排名"这句话。
这篇课程审计帖我读得很慢,因为它做的事情很对:把每一处数字重新算一遍,再把话反过来读。我跟着算了一遍最关键的那个扫描:
k=10 精度 81.5%,k=30 是 89.1%,k=50 达到 89.7%,然后掉头——k=100 是 85.5%,k=200 是 87.0%,原始 784 维也不过 87.7%。
不是平台,是驼峰,峰在 50。同一时间方差单调上涨:49.4%、73.6%、82.9%、91.8%、96.9%、100%。方差一路涨,精度过了50 维就往下走。当然要补一句:k 到 100 以后屏幕上全是收敛警告,课程的 max_iter=1000在高维上根本没跑完,掉头里有欠收敛的份。但"走平"的叙事在课程自己的代码和参数下不成立。
我把最有意思的那个换分母算了出来:50 维峰值 89.7%,784 维原始是 87.7%——压掉 734 个维度,精度反而高了 2.0 个点。同一份数据,同一个模型族。
而要凑够 0.95 的方差阈值需要 148 维,50 维只给 82.9%。也就是说,多花 3 倍维度换 12.1 个百分点的方差,读数反而掉 6.8 个点。这两个数放在一行里,PCA 的全部局限就说完了。
顺着这条缝,练习 3 的预设塌了。题目说造一个 50 特征、其中 5 个有信息量的数据集,看解释方差曲线能不能识别出"数据实际上是 5 维的"。实测:前十个成分的解释方差比 0.080、0.056、0.028、0.027、0.026、0.025——第 6 个成分和第 3 个一样胖,根本没有肘部。5 个成分只抓 21.8% 方差,要凑到 90% 得用上 42 个成分。
原因藏在数据生成器里。make_classification 的"有信息"是按类别可分性设计的,不是按方差设计的,45 个纯噪声特征每个贡献约 2% 的方差,把曲线摊平了。
【推论】"数据实际上是 5 维的"这句话只在信息口径下成立,在方差口径下它就是 50 维。而 PCA 只看方差。这道练习最好的教法不是确认曲线能识别,而是让学生亲手撞一次识别不出来。
还有一处最好玩。kernel PCA 的同心圆例子课程说对了:标准 PCA 投影下来内环外环在第一主成分上完全重叠,阈值切分精度 51%,跟抛硬币打平;RBF 核确实能分开。但 γ 是只没写的旋钮。同一个 RBF 核:γ=5 完美分离精度 100%,γ=1 是 50.5% 还是硬币,γ=10 是 58% 又塌回去。课程给了公式 exp(-γ‖x−y‖²),一个字没提 γ 怎么选——而它单方面决定成败,独占 49.5 个百分点的摆幅。
再看一处正面教材。第 4 步的对账设计:手写 PCA 对 sklearn,解释方差比六位小数一致,坐标最大差 2.66e-15。它用 abs(abs(a)-abs(b)) 这个看着古怪的比法——特征向量的正负号是自由的,直接相减会被符号翻转骗到(实测 raw 差值是 8.36),先取绝对值再比,才是把符号自由度处理干净的真对账。【直引】上一课刚说过"同一公式跑两遍没有对账力",这一课的写法恰好是反面样本。重构误差恒等式也验了:MNIST 上 50 个成分压回 784 维,均方差 746.0020,被丢掉的 734 个特征值之和除以 784 是 746.1512——差 0.02%,差在 np.cov 除的是 n-1 而恒等式要的是 n,乘上 4999/5000 精确吻合。同课两处口径差一个自由度修正,教学无伤,账上值得记一笔。
【判断】开篇那句口号"高维数据有结构,找对角度就能看见"底下藏着一句没说破的话:PCA 里"对"的角度,被定义成方差最大的角度。方差最大的方向,不一定是你关心的方向。要看见的如果是类别结构,你还得借 t-SNE 的眼睛,或者把 γ 拧到 5。
下一根钉子:练习 3 那种"信息维数≪方差维数"的数据,有没有一种不靠标签就能把这两者分开的判据——现在所有 PCA 选 k 的方法都在回答错误的问题。