如何用PCA获取两个主成分?Python实现疑问及数据示例
嘿,我来帮你搞定PCA里主成分向量和旋转角度的问题,结合你的两组功率数据一步步拆解~
1. 先把数据搭起来,跑通PCA流程
首先假设你已经把数据加载成了DataFrame,我们先写个完整的代码示例,把PCA跑起来:
import pandas as pd from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler # 加载你的数据(实际替换成你的文件路径或数据来源) data = pd.read_csv("your_power_data.csv", header=0, names=["Index", "GarageMudroomLights", "DiningRoomOutlets"]) # 提取特征列,去掉索引列 X = data[["GarageMudroomLights", "DiningRoomOutlets"]].values # 关键:PCA对数据尺度敏感,先做标准化(均值为0,方差为1) scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 初始化PCA,保留2个主成分(你的数据是2维的,刚好覆盖所有成分) pca = PCA(n_components=2) X_pca = pca.fit_transform(X_scaled)
2. 获取正交的主成分向量
你要的主成分正交向量,直接存在PCA模型的components_属性里,它是一个(n_components, n_features)形状的数组——每一行就是一个主成分的单位向量,而且这些向量天生是正交的(PCA的核心就是找正交的特征向量,保证成分间无冗余)。
打印看看:
print("主成分正交向量:") print(pca.components_)
输出会是类似这样的2行2列数组:
[[0.85 0.53] [-0.53 0.85]]
- 第一行是**主成分1(PC1)**的向量,代表原始两个特征的线性组合权重:
PC1 = 0.85*GarageMudroomLights + 0.53*DiningRoomOutlets - 第二行是**主成分2(PC2)**的向量,和PC1正交,组合方式是
PC2 = -0.53*GarageMudroomLights + 0.85*DiningRoomOutlets
另外,pca.explained_variance_ratio_能告诉你每个主成分解释的方差占比,比如输出[0.91, 0.09]就说明PC1解释了91%的数据变异,是最核心的成分。
3. 计算旋转角度(主成分与原始坐标轴的夹角)
因为你的数据是2维的,我们可以计算主成分相对于原始特征坐标轴的旋转角度:
- 对于PC1的向量
(a, b),它和原始X轴(GarageMudroomLights)的夹角θ,用反正切函数计算:θ = arctan(b/a),再转成角度(乘以180/np.pi) - 因为PC1和PC2正交,PC2与X轴的夹角就是θ ± 90°(具体方向看向量符号)
代码示例:
import numpy as np # 获取PC1的向量 pc1 = pca.components_[0] # 计算PC1与X轴的夹角(弧度转角度) angle_rad = np.arctan(pc1[1]/pc1[0]) angle_deg = np.degrees(angle_rad) print(f"PC1相对于GarageMudroomLights坐标轴的旋转角度:{angle_deg:.2f}°") print(f"PC2相对于GarageMudroomLights坐标轴的旋转角度:{angle_deg + 90:.2f}°")
这里要再强调:一定要先标准化数据,不然PCA结果会偏向数值范围大的特征,导致主成分向量和旋转角度都失去参考意义。
额外验证:确认正交性
如果你想验证两个主成分真的正交,可以计算它们的点积,结果应该接近0(因为是单位向量,正交的话点积严格为0,浮点运算可能有微小误差):
dot_product = np.dot(pca.components_[0], pca.components_[1]) print(f"主成分向量点积:{dot_product:.6f}") # 输出应该接近0
内容的提问来源于stack exchange,提问作者Ameko
相关产品推荐
相关产品推荐

