Godot性能优化三步法:定位瓶颈、节流调度、渲染提效
2026/5/22 21:30:24
降维是高维数据处理的核心手段,通过保留数据核心信息(方差最大的方向),将高维特征映射到低维空间,解决“维度灾难”(计算量激增、过拟合、数据稀疏),同时尽可能保留原始数据的特征。
PCA是无监督线性降维算法,核心思想是:找到一组正交的“主成分”(数据方差最大的方向),将数据投影到这组主成分构成的低维空间,实现降维且信息损失最小。
设原始数据矩阵X∈Rn×dX \in \mathbb{R}^{n \times d}X∈Rn×d(nnn个样本,ddd个特征):
SVD是通用的矩阵分解方法,适用于任意矩阵(非方阵、奇异矩阵均可),是PCA的底层实现(更稳定)。
对任意矩阵X∈Rn×dX \in \mathbb{R}^{n \times d}X∈Rn×d,SVD分解为:
X=UΣVTX = U \Sigma V^TX=UΣVT
PCA的协方差矩阵C=1n−1XstdTXstdC = \frac{1}{n-1} X_{std}^T X_{std}C=n−11XstdTXstd,对XstdX_{std}Xstd做SVD分解后:
因此,PCA可通过SVD直接实现(无需计算协方差矩阵,避免高维下的数值不稳定),步骤简化为:
| 维度 | PCA | SVD |
|---|---|---|
| 适用对象 | 仅用于降维(无监督) | 通用矩阵分解(降维/压缩/推荐等) |
| 输入要求 | 需标准化数据 | 无强制标准化(但PCA用SVD时仍需) |
| 计算方式 | 协方差矩阵的特征值分解 | 直接分解原始矩阵 |
| 数值稳定性 | 高维下易不稳定(协方差矩阵计算) | 更稳定(无需构造协方差矩阵) |
| 核心输出 | 主成分(特征向量)、降维数据 | 奇异值、左右奇异向量 |
| 关系 | PCA可通过SVD实现(推荐方式) | SVD是PCA的底层数学工具 |
| 功能 | 库/函数 | 关键参数说明 |
|---|---|---|
| 数据标准化 | sklearn.preprocessing.StandardScaler | fit_transform(X):拟合并转换数据;inverse_transform(Y):逆转换(恢复原始尺度) |
| sklearn实现PCA | sklearn.decomposition.PCA | n_components:降维后的维度(int/浮点数,如0.9表示保留90%方差);whiten:是否白化 |
| numpy实现SVD | numpy.linalg.svd | full_matrices:是否返回完整矩阵(False则返回精简版);compute_uv:是否计算U/V |
fromsklearn.preprocessingimportStandardScalerfromsklearn.decompositionimportPCA# 1. 数据标准化scaler=StandardScaler()X_std=scaler.fit_transform(X)# 2. 初始化PCA(n_components可设为维度/方差比例)pca=PCA(n_components=2)# 降维到2维# pca = PCA(n_components=0.9) # 保留90%方差# 3. 拟合+降维X_pca=pca.fit_transform(X_std)# 关键属性print("解释方差比:",pca.explained_variance_ratio_)# 各主成分解释的方差占比print("累计方差比:",sum(pca.explained_variance_ratio_))# 累计解释方差print("投影矩阵(主成分):",pca.components_)# 形状(k,d),k为降维后维度importnumpyasnp# 1. 数据标准化X_std=(X-np.mean(X,axis=0))/np.std(X,axis=0,ddof=1)# ddof=1对应样本标准差# 2. SVD分解U,sigma,Vt=np.linalg.svd(X_std,full_matrices=False)# 精简版分解# 3. 基于SVD实现PCA(取前k个奇异值对应的右奇异向量)k=2W=Vt.T[:,:k]# 投影矩阵(右奇异向量的前k列)X_svd_pca=X_std @ W# 降维后数据将鸢尾花数据集(4维特征)降维到2维,可视化分类效果。
importnumpyasnpimportmatplotlib.pyplotaspltfromsklearn.datasetsimportload_irisfromsklearn.preprocessingimportStandardScalerfromsklearn.decompositionimportPCA# 1. 加载数据iris=load_iris()X=iris.data# (150,4),4个特征:花萼长/宽、花瓣长/宽y=iris.target# 3类鸢尾花# 2. 数据标准化scaler=StandardScaler()X_std=scaler.fit_transform(X)# 3. PCA降维(保留2维)pca=PCA(n_components=2)X_pca=pca.fit_transform(X_std)# 4. 结果分析print("=== PCA结果 ===")print("各主成分解释方差比:",pca.explained_variance_ratio_)# [0.7296, 0.2285]print("累计解释方差比:",sum(pca.explained_variance_ratio_))# ~95.8%(保留95.8%信息)print("投影矩阵(主成分):\n",pca.components_)# 5. 可视化降维结果plt.figure(figsize=(8,6))colors=['red','green','blue']labels=['Setosa','Versicolor','Virginica']foriinrange(3):plt.scatter(X_pca[y==i,0],X_pca[y==i,1],c=colors[i],label=labels[i])plt.xlabel('PC1 (72.96%)')plt.ylabel('PC2 (22.85%)')plt.title('PCA降维:鸢尾花数据集(4→2维)')plt.legend()plt.show()手动实现PCA(基于特征值分解),验证与sklearn结果一致。
importnumpyasnpfromsklearn.datasetsimportload_irisfromsklearn.preprocessingimportStandardScalerfromsklearn.decompositionimportPCA# 1. 加载并标准化数据iris=load_iris()X=iris.data scaler=StandardScaler()X_std=scaler.fit_transform(X)# 2. 手动实现PCA(特征值分解法)# 步骤1:计算协方差矩阵cov_mat=np.cov(X_std,rowvar=False)# rowvar=False:每列是一个特征# 步骤2:特征值分解eigen_values,eigen_vectors=np.linalg.eig(cov_mat)# 步骤3:按特征值降序排序,选择前2个sorted_idx=np.argsort(eigen_values)[::-1]top2_eigen_vectors=eigen_vectors[:,sorted_idx[:2]]# 步骤4:投影降维X_pca_manual=X_std @ top2_eigen_vectors# 3. sklearn PCA对比pca_sklearn=PCA(n_components=2)X_pca_sklearn=pca_sklearn.fit_transform(X_std)# 4. 验证结果(因特征向量符号可能相反,需检查绝对值是否一致)print("=== 手动PCA vs sklearn PCA ===")print("手动PCA前5行:\n",np.round(X_pca_manual[:5],4))print("sklearn PCA前5行:\n",np.round(X_pca_sklearn[:5],4))print("绝对值是否一致:",np.allclose(np.abs(X_pca_manual),np.abs(X_pca_sklearn)))# True用SVD实现PCA降维,并演示SVD的压缩功能。
importnumpyasnpfromsklearn.datasetsimportload_irisfromsklearn.preprocessingimportStandardScaler# 1. 加载并标准化数据iris=load_iris()X=iris.data scaler=StandardScaler()X_std=scaler.fit_transform(X)# 2. SVD分解实现PCAU,sigma,Vt=np.linalg.svd(X_std,full_matrices=False)# 步骤1:取前2个奇异值对应的右奇异向量(投影矩阵)k=2W=Vt.T[:,:k]# 步骤2:降维X_svd_pca=X_std @ Wprint("=== SVD-PCA降维结果(前5行)===")print(np.round(X_svd_pca[:5],4))# 3. SVD数据压缩演示# 原始矩阵形状:(150,4)print("\n=== SVD数据压缩 ===")# 保留前2个奇异值,重构矩阵sigma_k=np.diag(sigma[:k])# 构建k阶奇异值对角矩阵X_recon=U[:,:k]@ sigma_k @ Vt[:k,:]# 重构压缩后的矩阵print("原始矩阵形状:",X_std.shape)print("压缩后重构矩阵形状:",X_recon.shape)print("重构误差(MSE):",np.mean((X_std-X_recon)**2))# ~0.041(仅损失4.1%信息)用SVD对用户-物品评分矩阵降维,实现简单的评分预测。
importnumpyasnp# 1. 构建用户-物品评分矩阵(5个用户,4个物品,0表示未评分)ratings=np.array([[5,3,0,1],[4,0,0,1],[1,1,0,5],[1,0,0,4],[0,1,5,4]])# 2. SVD分解(精简版)U,sigma,Vt=np.linalg.svd(ratings,full_matrices=False)# 3. 降维(保留2个奇异值)k=2U_k=U[:,:k]sigma_k=np.diag(sigma[:k])Vt_k=Vt[:k,:]# 4. 重构评分矩阵(预测未评分项)ratings_recon=U_k @ sigma_k @ Vt_kprint("=== 原始评分矩阵 ===")print(ratings)print("\n=== SVD重构评分矩阵(预测未评分项)===")print(np.round(ratings_recon,1))通过以上梳理,你可掌握PCA与SVD的理论基础、实现方法和实战技巧,后续可结合具体场景(如图像降维、推荐系统)进一步深化应用。