PCA 与经典模型
本章目录
学完后,你应能独立完成
- 推导PCA最大方差方向与SVD关系
- 构造高解释方差却丢信号的反例
- 比较SVM、KNN、NB与聚类的主要假设
前置建议:Ridge、Lasso 与因子合成
改变一个条件,观察发生什么
浏览器内即时教学计算;Python 实验结果另列于代码区。图形与数值一起核对。
PCA到底最大化什么
对中心化X,协方差S=X_cᵀX_c/(n−1)。单位方向v上的投影方差是vᵀSv。施加‖v‖=1,Lagrange一阶条件得到Sv=λv,选最大特征值方向;后续方向与前面正交。
目标没有y。因此输入方差解释得多,不等于目标收益解释得多。PCA可压缩冗余,也可能把预测方向删掉。是否标准化会改变优化目标,是设计选择。
SVD给方向、得分和方差
X_c=UDVᵀ,因此S=V D²Vᵀ/(n−1)。V列是主方向,X_cV=UD是得分,解释比例d_j²/Σd_l²。方向符号任意,重复特征值下子空间基也不唯一,核查投影或重建比逐元素符号更合理。
n_components与缩放方式在开发折选择,训练均值与主方向只能fit训练X。没用y不等于没有未来信息。
一个能手算的反例
S=diag(9,1)时第一方向是x₁,解释90%输入方差。如果y=x₂+噪声,保留第一主成分就丢掉预测力。页面改变协方差尺度与相关后,观察主方向和解释比例;这仍只回答X的结构。
下方脚本用实际下游留出MSE比较保留一维与全部特征。对因子库可同时比较PCA压缩、Ridge收缩和相关组筛选,使用相同时间折,不提前宣布压缩一定更稳。
SVM与KNN:尺度影响几何
SVM软间隔最小化‖w‖²/2+CΣξ,约束y_i(wᵀx_i+b)≥1−ξ_i。C大更看重违约损失;核用隐式特征内积,不是任何相似度都构成有效半正定核。margin不自动是校准概率。
KNN在成熟训练库里找邻居。k小局部方差高,k大更平滑;无参数优化不意味着无泄漏。高维噪声会稀释距离,单位变化也改变邻域。大面板的预测成本与尺度需一起考虑。
NB、LDA与聚类:先看假设
NB要求给定类别后的条件独立;重复相关证据可能让概率过度自信。LDA共享类别协方差给线性边界,QDA允许各类协方差但参数更多。Logistic则直接建条件概率。
K-means交替最近中心分配与均值更新,目标每步不增加,但不证明全局最优;簇标签可交换,空簇需声明处理。GMM、DBSCAN与复杂聚类放扩展阅读,不把统计结构直接称为经济行业或Alpha。
从算法到一次真实运行
代码在本地 Python 中执行,HTML 内展示参考实现和本轮运行结果。请先独立完成练习,再展开完整参考文件。
def pca_fit(X, components):
X = np.asarray(X,float)
if X.ndim!=2 or len(X)<2 or not 1<=components<=min(X.shape):
raise ValueError("Invalid data or component count")
mean = X.mean(0)
_, singular, vt = np.linalg.svd(X-mean,full_matrices=False)
variance = singular**2/(len(X)-1)
ratio = variance/variance.sum() if variance.sum()>0 else np.zeros_like(variance)
return mean, vt[:components].T, ratio[:components]"""Standalone synthetic teaching example. Run locally with Python, not in the HTML."""
import json
import numpy as np
import pandas as pd
from scipy.special import expit
def clean(value):
if isinstance(value, dict): return {str(k):clean(v) for k,v in value.items()}
if isinstance(value,(list,tuple,np.ndarray)): return [clean(v) for v in value]
if isinstance(value,(np.integer,)): return int(value)
if isinstance(value,(float,np.floating)): return float(value) if np.isfinite(value) else None
if isinstance(value,(np.bool_,)): return bool(value)
return value
def print_result(result):
print(json.dumps(clean(result),ensure_ascii=False,allow_nan=False))
def pca_fit(X, components):
X = np.asarray(X,float)
if X.ndim!=2 or len(X)<2 or not 1<=components<=min(X.shape):
raise ValueError("Invalid data or component count")
mean = X.mean(0)
_, singular, vt = np.linalg.svd(X-mean,full_matrices=False)
variance = singular**2/(len(X)-1)
ratio = variance/variance.sum() if variance.sum()>0 else np.zeros_like(variance)
return mean, vt[:components].T, ratio[:components]
if __name__ == "__main__":
from sklearn.linear_model import Ridge
rng=np.random.default_rng(42)
X=rng.normal(size=(1200,2));X[:,0]*=10
y=2*X[:,1]+rng.normal(0,.2,len(X))
tr,te=np.arange(800),np.arange(800,1200)
mean,directions,ratio=pca_fit(X[tr],1)
one=Ridge(alpha=1).fit((X[tr]-mean)@directions,y[tr])
full=Ridge(alpha=1).fit(X[tr],y[tr])
one_mse=np.mean((one.predict((X[te]-mean)@directions)-y[te])**2)
full_mse=np.mean((full.predict(X[te])-y[te])**2)
np.testing.assert_allclose(directions.T@directions,np.eye(1),atol=1e-12)
print_result({"explained_ratio":ratio,"one_component_mse":one_mse,
"full_features_mse":full_mse,"direction":directions[:,0]})
查看本轮本地运行记录 · 2026-10-12
{
"explained_ratio": [
0.9903404391617024
],
"one_component_mse": 4.188302218548662,
"full_features_mse": 0.03799782507463552,
"direction": [
-0.9999477019266413,
-0.010227092041661766
]
}先回答,再看提示和答案
第一主成分解释90%方差,就解释90%收益吗?
一级提示
令y=x₂且S=diag(9,1)。
参考答案与条件
不是,PCA目标只看X。y可能由剩余低方差方向决定。
两次PCA方向符号反了,代码错了吗?
一级提示
先写出目标、信息集和所需条件。
参考答案与条件
未必,特征向量符号不唯一。比较vvᵀ、子空间、重建或同步变换后的预测。
K-means目标单调下降,是否保证全局最优?
一级提示
先写出目标、信息集和所需条件。
参考答案与条件
不保证,只说明交替步骤不增目标。初始化、空簇规则和多初值影响局部解。
把知识迁移到一个新任务
实现中心化PCA,用SVD与协方差特征分解核对同一子空间。造y依赖低方差方向的数据,在同一留出集合中比较一维PCA与全特征预测。
这里保存学习笔记,不在浏览器执行 Python。A/B/C 由你按独立完成程度填写。
参考与进一步阅读
在线文档可能比本地固定版本更新;API 行为以已验证代码和版本记录为准。
掌握状态与复习
关掉资料独立完成后记 A;提示后完成记 B;需要重学记 C。
记录尽量保存在当前浏览器,建议定期导出备份。