☰
PCA双标图怎么看:载荷箭头、夹角与变量解读实战
2026/11/3 21:04:10 网站建设 项目流程

1. 先说清楚:PCA 图上那根箭头到底在表达什么

第一次看 PCA 双标图(biplot)的人,十有八九会被满屏的箭头劝退。散点还好理解——每个点是一个样本,聚在一起说明相似,散开说明差异大。可那些从原点伸出来的箭头是什么?为什么有的长有的短?为什么有的指向样本聚集区,有的指向空白地带?

我把这个问题拆开讲:PCA 图里的箭头,本质上是原始变量(特征)在降维后坐标系中的载荷向量(loading vector)的几何可视化。它回答的是"这个主成分到底是被哪些变量撑起来的"这个问题。

一个 PCA 模型输出的核心信息有两块:一块是得分(score),即每个样本在新坐标轴上的投影位置,画出来就是那些散点;另一块是载荷(loading),即每个原始变量对每个主成分的贡献权重,画出来就是箭头。这两块信息共享同一个坐标平面,所以能叠在一张图上,这就是 biplot 名字的由来——bi 指的是 bi-plot,样本与变量同图。

箭头的方向含义很直白:箭头指向哪个方向,就说明这个变量在该方向上的取值增大时,会把样本往那个方向"拉"。箭头的长度含义同样直白:长度越长,说明这个变量在这个二维平面里被保留的信息越多,对这两个主成分的贡献越大;长度接近 0 的箭头,说明这个变量的变化几乎没体现在这两个主成分上,解释力很弱。

这里有个特别容易踩的坑我得提前说:箭头的长度不是"重要性排名"。很多新手看到某个箭头特别短,就直接把这个变量删掉,这个操作非常危险。短只代表"在这两个主成分构成的面内投影短",它可能在第三、第四主成分上有很高的载荷,只是你当前只画了前两个维度而已。我见过不止一次有人据此删变量,结果模型换了个主成分数量之后,结论完全反过来。

还有一个概念得先摆正:箭头和散点不在同一个度量尺度上。散点的坐标是样本得分,箭头的坐标是变量载荷,两者数值量级往往差很多。所以绝大多数绘图库在画 biplot 时会对其中一方做缩放(scaling),常见做法是把载荷乘以一个系数,或者对得分做标准化。这就导致一个现象:你换一个软件、换一个参数,箭头的长度会变,但方向基本不变,变量之间的相对角度关系也不变。记住这一点,后面讲解读的时候会反复用到。

至于"适合谁看"这个问题——只要你在做多变量数据的探索性分析,不管是实验数据、问卷数据、用户行为指标还是成分检测数据,这张图都用得上。看懂箭头,你就能从"样本怎么分类"进阶到"为什么会这样分类",这是从描述现象到解释机理的关键一步。

2. 先搞懂底层逻辑:载荷、方向余弦与夹角余弦

要真正把箭头读明白,得回到数学。我不打算堆公式,但几个核心关系必须讲透,否则后面所有解读技巧都是空中楼阁。

2.1 载荷向量的几何本质

假设你有 p 个变量、n 个样本,做了标准化之后跑 PCA。每个主成分是一组单位正交向量,第 k 个主成分对应的载荷向量就是 p 维空间里的一个方向。把这个 p 维向量投影到你选定的两个主成分(比如 PC1 和 PC2)张成的平面上,得到的就是二维坐标 (loading_pc1, loading_pc2),从原点画到该点,就是图上那根箭头。

所以箭头的位置信息包含三层:横坐标是该变量在 PC1 上的载荷,纵坐标是在 PC2 上的载荷,长度是这两个载荷的平方和开根号。这个长度有个专门的名字,叫变量在因子平面上的共同度(communality)的平方根。共同度衡量的是"这个变量的方差有多少被这两个主成分解释了"。

举个具体数字帮你建立感觉。假设某个变量在 PC1 上载荷 0.8,PC2 上载荷 0.6,那么箭头长度是 sqrt(0.64+0.36)=1.0,说明这个变量的方差有 100% 被前两个主成分解释(因为标准化后总方差为 1)。如果载荷是 0.2 和 0.15,长度约 0.25,共同度只有 0.0625,意味着这个变量的信息 94% 都散落在后面那些没画出来的主成分里。看,这就是为什么盯着短箭头做决策会翻车。

2.2 夹角余弦等于相关系数

这是解读 biplot 时最有用的一个性质,也是最多人不知道的:两个箭头之间夹角的余弦值,近似等于这两个变量之间的相关系数。

  • 夹角接近 0 度,余弦接近 1,说明两个变量强正相关,它们同向变化;
  • 夹角接近 90 度,余弦接近 0,说明两个变量基本不相关,各自独立变化;
  • 夹角接近 180 度,余弦接近 -1,说明两个变量强负相关,此消彼长;
  • 夹角 120 度左右,余弦约 -0.5,中等强度的负相关。

这个性质不是精确成立的,前提是这两个变量在前两个主成分上的共同度都比较高(也就是箭头都比较长)。如果箭头很短,角度就没有参考意义——这一点我必须强调,因为网上很多教程直接说"夹角就是相关系数",省掉了这个前提,害人不浅。

我在实际项目里验证过这个性质。做用户行为指标分析时,"日均访问次数"和"页面浏览深度"两个箭头夹角大约 20 度,算出来相关系数 0.93,和原始数据的 Pearson 相关系数就是 0.93,几乎一致。而"日均访问次数"和"平均单次停留时长"夹角接近 100 度,原始相关系数是 -0.17,吻合得也很好。这种验证建议你也做一次,能极大增强你对图的可信度。

2.3 箭头与散点的投影关系

第三个性质讲的是箭头和样本点的关系,同样基于内积:把某个样本点向某根箭头所在直线做垂线投影,投影点的位置(相对于原点)近似反映该样本在这个变量上的取值高低。

这句话有点绕,我换成操作化的说法:拿一把尺子,沿着箭头方向延长,然后看样本点落在这条线上的位置。越靠近箭头尖端方向,说明这个样本在该变量上的原始值越高;越靠近反方向,值越低。这个技巧在判断"右上角那堆点到底哪个指标高"时非常好用。

但要提醒的是,这个性质同样受共同度约束。如果某个变量的箭头很短,用它去判断样本取值就不靠谱。而且 biplot 的缩放方式不同(后面会讲),这个投影的精确度也会有差异。所以我的经验是:用这个性质做定性判断可以,做精确排序不行。真要排序,老老实实回到原始数据去算。

3. 实操拆解:从原始数据到一张能读的 PCA 双标图

理论讲完,进入动手环节。我按完整流程走一遍,中间穿插参数选择的理由和踩坑记录。

3.1 数据预处理:标准化不是可选项

PCA 对量纲极度敏感,这一点必须放在第一步说。假设你的数据里有"年收入"(单位万元,范围 5 到 200)和"满意度评分"(1 到 5),不标准化直接跑 PCA,PC1 基本会被年收入独占,因为它的方差天然大得多。这不是数据本身的规律,纯粹是量纲造成的假象。

标准做法是z-score 标准化,即每个变量减去均值再除以标准差,让所有变量的方差都变成 1。用 Python 的话:

import numpy as np import pandas as pd # df 是原始数据框,行为样本,列为变量 X = df.select_dtypes(include=[np.number]).values X_std = (X - X.mean(axis=0)) / X.std(axis=0, ddof=1)

如果你用的是 scikit-learn 的 Pipeline,直接调StandardScaler就行。但我更推荐在探索阶段用 numpy 手写一遍,因为你会被迫检查每一步的输出,能更早发现缺失值和异常值。

注意:标准化之前一定要处理缺失值和极端离群点。PCA 对离群点极其敏感,一个坐标值差了三个数量级的样本,能把整条主成分轴拽偏。我习惯先算每个变量到中位数的稳健距离,超出阈值超过 3 倍的样本单独标记出来看一眼,确认是录入错误还是真实极端值,再决定剔除还是保留。

还有一个经常被忽略的决策:是否该标准化。如果你的所有变量本来就是同量纲、同尺度(比如都是一批同类型传感器的读数),不标准化反而能保留方差结构的原始信息。我的判断原则是:变量之间量纲不一致就必须标准化;量纲一致时两种都试一下,看结果稳定性,如果结论差异大,说明数据本身结构不稳,需要回头检查。

3.2 计算主成分与载荷矩阵

标准流程用 SVD 或者特征分解都行,结果等价。核心是拿到特征值、特征向量和得分三样东西。

# 协方差矩阵(标准化后即相关系数矩阵) cov = np.cov(X_std, rowvar=False) eigvals, eigvecs = np.linalg.eigh(cov) # 按特征值降序排列 idx = np.argsort(eigvals)[::-1] eigvals = eigvals[idx] eigvecs = eigvecs[:, idx] # 载荷矩阵:特征向量乘以对应特征值的平方根 loadings = eigvecs * np.sqrt(eigvals) # 得分矩阵 scores = X_std @ eigvecs

这里有个小细节值得说:载荷有两种定义。一种是特征向量乘以特征值平方根(上面这种),另一种就是直接用特征向量。前者保证载荷的平方和等于特征值,后者保证载荷的平方和等于 1。不同软件默认不一样,所以在对比不同工具的输出前,先确认它用的是哪种约定。这不是死知识,但能帮你在"为什么我的载荷算出 0.8,别人算出 0.3"这种困惑里少走弯路。

解释方差比例也要算出来,写在图上标注轴标题:

explained = eigvals / eigvals.sum() print(f"PC1: {explained[0]*100:.1f}%, PC2: {explained[1]*100:.1f}%")

通常前两个主成分累计解释 50% 以上就是不错的起点。低于 40% 的话,我建议慎重解读这张二维图,因为它丢掉的信息太多,图上的规律可能只是噪声的投影。这种情况要么增加维度看三维图,要么换方法。

3.3 绘制双标图与缩放参数

主流工具我都用过,说下各自的适用场景。

工具优势注意事项
Python + sklearn + matplotlib完全可控,缩放自定义需要手动算载荷,绘图代码较长
R + ggplot2 + factoextra一键出图,样式美观默认缩放方式要确认,fviz_pca_biplot默认会对变量做缩放
R + ggbiplot传统 academic 风格维护频率低,新版 R 可能装不上
Origin / GraphPad无需编程,适合手工数据载荷导出后自己画,缩放系数不透明

手绘 biplot 的关键在于得分为载荷的缩放比例要匹配。常用做法是把载荷乘以一个系数,让箭头长度和散点云的范围大致相当。一个简单可靠的做法:

import matplotlib.pyplot as plt # 缩放系数:让最长的箭头约为散点最大半径的 0.8 倍 score_max = np.abs(scores[:, :2]).max() loading_max = np.abs(loadings[:, :2]).max() scale = 0.8 * score_max / loading_max fig, ax = plt.subplots(figsize=(9, 8)) ax.scatter(scores[:, 0], scores[:, 1], s=30, alpha=0.6, edgecolors='k', linewidths=0.3) for i, var in enumerate(df.columns[:num_vars]): ax.arrow(0, 0, loadings[i,0]*scale, loadings[i,1]*scale, head_width=0.02*score_max, color='crimson', alpha=0.85, length_includes_head=True) ax.text(loadings[i,0]*scale*1.08, loadings[i,1]*scale*1.08, var, fontsize=9) ax.axhline(0, color='gray', lw=0.6, linestyle='--') ax.axvline(0, color='gray', lw=0.6, linestyle='--') ax.set_xlabel(f'PC1 ({explained[0]*100:.1f}%)') ax.set_ylabel(f'PC2 ({explained[1]*100:.1f}%)') plt.tight_layout()

注意:scale这个系数只影响视觉可读性,不影响任何数值结论。别把它当成某种需要精确设定的参数,调到一个"看着舒服、箭头不压住散点"的值就行。但一定要在图的说明文字里写清楚"变量载荷已按 X 倍缩放",否则拿去投稿或者汇报时会被追问。

3.4 变量数量过多时的取舍策略

实际数据动辄几十上百个变量,全画上去就是一团乱麻。我有几个处理顺序可参考:

第一步,按共同度筛。只画共同度(前两个主成分的载荷平方和)超过 0.4 的变量,剩下的默认不显示,但在图注里说明一共多少个变量、显示了几个、筛选阈值多少。这个操作是纯展示优化,不涉及删除数据。

第二步,按领域知识合并。如果你有十几个高度相关的变量,可以先做一次相关性聚类,同一簇选一个代表变量上图标,其余在图注里注明"该箭头代表 A、B、C 等 6 个高相关变量"。这样图能读懂,信息也没丢。

第三步,换图。如果变量实在太多,二维 biplot 就不合适了。可以考虑用载荷热力图(变量为行、主成分为列)替代,或者用相关性圆圈图。工具是死的,目的始终是让读图的人抓住结构。

4. 读图实战:六种典型模式与对应结论

这一节是全篇最实操的部分。我把常见的箭头分布模式总结成六种,每种给出读法、可能的成因和验证方式。

4.1 模式一:箭头呈扇形均匀分布

所有箭头从原点向不同方向散开,长度相近,夹角大致均匀。这种图通常对应变量之间相关性较低、数据维度分散的情况,说明原始变量各自独立贡献信息,PCA 的降维收益有限。

遇到这种图,我的建议是不要强行解释主成分的物理含义。因为每个主成分都由许多变量以相近权重构成,你很难给它起一个有意义的名字。这时候更该考虑的是:是不是应该用因子旋转(varimax)来获得更清晰的结构,或者干脆放弃降维,用其他方法做变量筛选。

4.2 模式二:箭头分成两三个紧密簇

箭头明显聚成几团,团内夹角小,团间夹角接近 90 度或 180 度。这是信息量最大的模式,说明变量背后存在少数几个潜在维度。每簇变量可以视为同一个潜在因子的不同侧面。

操作上,先对每簇变量做内部相关性检查,确认簇内相关系数都在 0.6 以上;然后给每簇起一个概括性的名字,这个名字就是你后续解释主成分的依据。注意两个簇如果夹角接近 180 度,它们代表的是同一个维度的两端,可以理解为"此消彼长"的两个方面,命名时要体现这种对立关系,比如"效率导向"对"质量导向"。

4.3 模式三:只有一两根长箭头,其余都很短

这种情况要警惕。可能是数据里确实存在一个主导变量(比如某个指标的量程远大于其他),也可能是某个变量有严重离群值。排查顺序是:先看那根长箭头对应的变量分布直方图,再看它的最大值和最小值。

我遇到过一回,"订单金额"这个变量箭头特别长,独占 PC1 的 70% 方差。查下来发现有个测试账户下了一笔异常大的订单,标准化后 z 值超过 15。剔除这一条记录后,图完全变了,长箭头缩回正常长度,其他变量也显现出来了。这就是离群点的破坏力。

4.4 模式四:箭头与样本簇的对应关系

把箭头和散点叠起来看,能建立"样本为什么聚在这里"的因果链。读法是:某个样本簇位于某根箭头的延长线方向,说明该簇样本在这个变量上取值偏高;位于箭头反方向,则取值偏低。

举个例子,做设备状态监测时,散点分成三簇,一簇落在"振动幅度"箭头正方向且"运行时长"箭头反方向,这簇样本基本就是"刚上机、振动大"的磨合期设备;另一簇落在"运行时长"正方向、"温度"接近零载荷的区域,对应稳定运行期。这种解释比单纯说"分了三类"有价值得多,因为它直接指向了可操作的判断依据。

要提醒的是,这个读法只在箭头足够长时可靠,我在 2.3 节已经说过原因。实际操作中我会做个交叉验证:对某一簇样本,回去算它在关键变量上的均值,和全体均值比较,看方向和图上读出来的是否一致。不一致就说明图读错了或者缩放干扰了判断。

4.5 模式五:箭头全部挤在原点附近

整张图散点铺得很开,但箭头短得像一堆小刺。这说明前两个主成分主要反映的是样本间的整体差异,而不是变量结构。可能的原因有两个:一是数据本身噪声大,信号分散在多个维度;二是样本量远小于变量数,主成分不稳定。

这种情况下,二维图基本没有解释价值。我的处理是看碎石图(scree plot),检查特征值是否呈现明显的断崖。如果没有断崖,说明数据没有低维结构,PCA 不适合这个数据集,应该换方法。

4.6 模式六:箭头重叠严重

两个或多个箭头几乎完全重合,说明这些变量高度共线。这在问卷数据、指标体系中极为常见。重合本身不是问题,反而是个有用信号:你可以只保留其中一个变量,其余的作用是互相验证。

但要注意,高度共线的变量会让载荷的解释变得不稳定。样本稍微变一点,载荷可能在这几个共线变量之间"跳来跳去"。所以如果你要做的是变量重要性排序,先做共线性诊断(算 VIF 或变量间相关矩阵),把相关超过 0.9 的变量合并处理,再跑 PCA。

5. 常见问题与排查速查

这一节整理我在实际工作中被问得最多、以及自己踩过的坑。表格形式方便对照。

现象可能原因排查与处理
换软件后箭头长度全变了载荷定义或缩放约定不同检查是特征向量还是特征向量乘 sqrt(特征值);确认绘图库的缩放参数,方向不变即为正常
箭头方向解读和业务常识相反符号翻转(特征向量方向不唯一)PCA 主成分的正负号本身没有意义,整体乘 -1 不改变结果,解读时以变量间相对关系为准
某变量箭头极短该变量在前两个 PC 上共同度低查该变量在 PC3、PC4 上的载荷,不要据此删除变量
样本聚类界限模糊前两个 PC 解释方差不足看累计解释率,低于 40% 时考虑增加维度或换方法
箭头长度和变量重要性排序不一致混淆了共同度与变量重要性变量重要性应综合多个主成分的载荷,或用其他方法(如随机森林重要性)交叉验证
图上一根箭头对应不上任何变量名变量数量多,标签重叠调整标签偏移、用交互式绘图,或按共同度筛选后重画

关于符号翻转这一条,我要多说两句,因为它是新手最容易被绕晕的地方。PCA 求解的是特征向量,而特征向量乘以 -1 仍然是同一个特征向量。不同软件、甚至同一软件的不同版本,输出的符号可能相反。这意味着 PC1 轴的正方向可能是"高值在右",也可能是"高值在左",完全取决于实现细节。

提示:解读时永远不要依赖"PC1 正方向代表什么"这种绝对表述。稳妥的读法是看变量之间的相对位置,以及样本相对于箭头的方位。这两类关系在符号翻转下保持不变。

另一个高频问题是"箭头能不能用来算具体数值"。答案是不能直接算。箭头只给出方向和相对强度,不给出斜率或截距。如果你需要定量关系,回到原始数据做回归或者算相关系数。PCA 图的作用是提出假设、发现结构,不是做精确推断。我在汇报时习惯把这句话写进图注,避免听众过度解读。

还有个很实际的坑:变量名太长导致图完全没法看。处理办法有三个,一是缩短变量名(但要保留在附表里做对照),二是用编号代替(V1、V2...)配合附表,三是改成只标注长箭头、短箭头不标。我个人最推荐第二种,虽然读图时需要查表,但图面干净,汇报时不容易被文字淹没。

6. 几个不写在文档里的实操心得

做完这些年后,我对 PCA 双标图的态度是:它是一张"提问图",不是一张"结论图"。它最大的价值是让你快速看到变量之间可能存在的关系,然后带着这些假设去做更严格的验证。

第一条心得:先看共同度,再看方向。很多人一上来就分析箭头指向,但如果共同度低,方向本身就不稳定。我现在的固定流程是先导出一张变量共同度表,按共同度排序,只看前 60% 的变量在图上的箭头,其余的视为"信息未展示"。这个习惯让我避免了不少误判。

第二条心得:双标图一定要配合原始相关矩阵看。箭头夹角给出的相关性是近似的、二维的,而相关矩阵是精确的、全维的。两者一致时你可以放心解读;不一致时,以相关矩阵为准,并回头想为什么二维投影会失真。这个"对账"动作花不了几分钟,但能显著提升结论可信度。

第三条心得:别在一张图上塞太多东西。样本按类别着色、变量箭头、置信椭圆、样本标签全加上去,图就废了。我的做法是分两张图:一张只画样本聚类和着色,用来回答"怎么分";另一张只画箭头,用来回答"为什么这么分"。两张图各自清爽,讲的时候也有节奏。

第四条心得:符号和缩放的怪现象,先别怀疑数据。遇到箭头方向"反了"、长度"不对",九成是绘图约定的问题,不是数据问题。先确认工具的输出定义,再去看数据。这个顺序能省掉大量无谓的排查时间。

最后分享一个我在做变量筛选时常用的组合拳:先用 PCA 双标图识别出高度共线的变量簇,每簇保留一个代表;再用保留后的变量重跑一次 PCA,对比两次的样本聚类结构是否稳定。如果稳定,说明冗余变量确实可以去掉;如果结构变了,说明那些被去掉的变量承载了独立信息,得留着。这个"去变量—重跑—对比"的循环我做过多轮,比单纯看载荷数值阈值要可靠得多,因为它检验的是对最终结论的影响,而不只是统计指标。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询