如何对协方差法实现的PCA结果做3D可视化并理解各输出变量含义
变量含义说明
Eigen Values:协方差矩阵分解得到的特征值,每个值对应对应主成分可解释的原始数据方差量,数值越大说明对应主成分携带的原始信息越多Eigen Vectors:特征向量矩阵,每一列对应一个主成分的投影轴,原始数据与该矩阵相乘即可得到降维后的投影结果Key:特征值排序后的索引值。eigh函数返回的特征值默认按从小到大排序,argsort(E)[::-1]会得到特征值从大到小排列对应的原始索引,截取前pc_count个就得到前N个主成分对应的特征值位置。你输出的[439 438 437]说明你的原始输入数据共有440个特征维度,前三个方差最大的主成分对应原始特征值序列的最后三位U:PCA降维后的结果矩阵,每一行对应一个原始样本,每一列对应一个主成分的得分,你指定了保留3个主成分,所以输出shape为40个样本×3个主成分
累积解释方差计算说明
使用协方差法实现PCA完全可以计算累积解释方差,和SVD实现没有本质差异,你没有得到累积方差是因为缺少了归一化计算步骤:
总方差为所有特征值的和,单个主成分的解释方差为对应特征值除以总方差,逐位累加即得到累积解释方差。
注:累积解释方差与主成分数量是明确的二维对应关系,无需绘制成3D图,常规二维折线图即可清晰展示规律。
3D可视化&累积方差绘图代码补全
from numpy import array, dot, mean, std, empty, argsort, cumsum from numpy.linalg import eigh from matplotlib.pyplot import subplots, figure, show from mpl_toolkits.mplot3d import Axes3D def cov(X): """ Covariance matrix note: specifically for mean-centered data note: numpy's `cov` uses N-1 as normalization """ return dot(X.T, X) / X.shape[0] def pca(data, pc_count = None): """ Principal component analysis using eigenvalues note: this mean-centers and auto-scales the data (in-place) """ data -= mean(data, 0) data /= std(data, 0) C = cov(data) E, V = eigh(C) # 先对所有特征值降序排序,方便后续计算全部主成分的解释方差 key = argsort(E)[::-1] E, V = E[key], V[:, key] # 只取前pc_count个主成分生成投影结果 U = dot(data, V[:, :pc_count]) return U, E, V # 你的原始数据 data = dftransformed.transpose() # df转置后转换为numpy数组 # 计算PCA trans, all_E, V = pca(data, 3) # 1. PCA结果3D可视化 fig = figure(figsize=(12,5)) ax1 = fig.add_subplot(121, projection='3d') # 按你原逻辑分组上色 ax1.scatter(trans[:50, 0], trans[:50, 1], trans[:50, 2], c = 'r', label='分组1') ax1.scatter(trans[50:, 0], trans[50:, 1], trans[50:, 2], c = 'b', label='分组2') ax1.set_xlabel('主成分1') ax1.set_ylabel('主成分2') ax1.set_zlabel('主成分3') ax1.legend() ax1.set_title('PCA结果3D可视化') # 2. 累积解释方差折线图 explained_var_ratio = all_E / all_E.sum() cum_explained_var = cumsum(explained_var_ratio) ax2 = fig.add_subplot(122) ax2.plot(range(1, len(cum_explained_var)+1), cum_explained_var, marker='o') ax2.set_xlabel('主成分数量') ax2.set_ylabel('累积解释方差') ax2.grid(True) ax2.set_title('累积解释方差曲线') show()
内容的提问来源于stack exchange,提问作者rubengavidia0x
相关产品推荐
相关产品推荐

