【CCA(典型相关分析)】第五章 经典CCA的实操实现

第五章 经典 CCA 的实操实现

本章要点

  • 一套贯通思路:同一份数据、同一套检验逻辑,在 SPSS / R / Python 三平台跑通
  • 三份对照代码:菜单路径、包函数、类接口的"翻译对照表"
  • 四个输出模块:典型相关系数、显著性检验、权重系数、载荷矩阵
  • 一条验证底线:三大平台的典型相关数值必须一致,符号约定必须对齐
  • 一个自动化工序:把分析写成可复现脚本,而不是手工菜单点击记录

前四章完成了从数学到检验的全部理论装备,本章把它们落到键盘上。全章使用同一份示范数据——"生理指标组对体测成绩组"的简化设定(16 名运动员的 3 项生理指标:肺活量、最大摄氧量、体脂率;2 项体测成绩:百米用时、耐力跑用时),样本量小仅用于演示流程,真实分析请按第三章准则放大样本。三平台的流程骨架完全同构,如图 5-1 所示。

数据读入

变量分组

典型相关求解

显著性检验

载荷与权重

结果导出

图 5-1 三平台共用的 CCA 流程总体结构(图注:本图给出平台无关的分析流水线,蓝色结构节点按数据加工次序排列。请重点看三个关键节点:数据读入与标准化是各平台差异最大的环节,也是出错高发区;典型相关求解之后的三步(检验、载荷、导出)三平台几乎一一对应;结果导出环节的分叉最大——SPSS 输出在查看器里、R 输出在对象里、Python 输出在属性里,理解各自的"出口"是本章实操的关键。)

5.1 SPSS 实现

5.1.1 菜单操作路径(分析 → 相关 → 典型相关性)

SPSS 的经典 CCA 主路径为:分析 → 相关 → 典型相关性,弹出对话框后:把生理指标组的三个变量放入"集合 1(X 组)“,体测成绩组放入"集合 2(Y 组)”,点击确定执行。若菜单中没有"典型相关性"项(旧版本或精简安装),两条等价替代路径可任选其一:

  • 语法路线:调用官方宏 CANCORR——在语法窗口运行 INCLUDE '...\Canonical correlation.sps'. CANCORR SET1 = 肺活量 最大摄氧量 体脂率 / SET2 = 百米用时 耐力跑用时 .(宏文件路径随安装目录而定);
  • MANOVA 路线:在旧版中通过 MANOVA 百米用时 耐力跑用时 WITH 肺活量 最大摄氧量 体脂率 / DISCRIMINANT STAN CORR ALPHA(1) . 获得等价的典型相关输出。

三条路径的数值结果一致,区别只在输出组织方式与是否顺带给出交叉载荷——建议新用户直接用主菜单路径,老数据文件则用语法路径保证可复现。菜单与语法的入口分工如图 5-2 所示。

原始数据

菜单路径

语法路径

输出查看器

图 5-2 SPSS 双入口的接口对接(图注:本图展示菜单与语法两条入口到输出查看器的信号流向,蓝色是输入接口,紫色是输出端。请重点看三个关键节点:两条入口共享同一套数据与同一计算内核,输出文件在查看器中汇总;菜单路径适合探索与教学,语法路径适合批量与复现;把菜单操作粘贴回语法窗口(点击"粘贴"按钮),是 SPSS 用户从交互走向可复现的最低成本过渡——本节的语法示例全部以该方式获得。)

5.1.2 变量分组与参数设置

执行前需要确认四个设置点:变量角色——被解释方向不预设,X 组/Y 组仅表示配对结构,不表达因果;缺失值策略——对话框默认逐对删除(pairwise),需要与第三章的缺失机制判断对齐;标准化——SPSS 的典型相关过程基于相关矩阵还是协方差矩阵由版本默认决定,建议在语法中显式要求标准化后再分析(对原始变量先执行"描述统计 → 描述 → 另存为标准化值"),保证输出可直接读权重;统计输出项——选择输出相关系数、载荷(structure coefficients)与交叉载荷(cross-loadings),这是第六章解读的原材料。参数语义的对应关系随平台而变,完整的对照表在 5.4.3 节给出。

5.1.3 输出结果解读(典型相关系数表 / 标准化系数表 / 载荷矩阵)

SPSS 输出的核心表组共五张,对应第 4、6 章的全部概念:

  • 典型相关系数表:列出 r1,r2r_1,r_2r1,r2(本例 min⁡(p,q)=2\min(p,q)=2min(p,q)=2),通常附带特征值 λi=ri2/(1−ri2)\lambda_i=r_i^2/(1-r_i^2)λi=ri2/(1ri2) 与 Wilks’ Lambda 的逐级检验列;
  • 显著性检验表:给出 Λ\LambdaΛ、Bartlett 近似的 χ2\chi^2χ2 值、自由度与 ppp 值——整体检验 p<0.05p<0.05p<0.05 才进入下一步解读(4.1 节);
  • 标准化系数表:两侧各自的权重向量 a\boldsymbol{a}ab\boldsymbol{b}b(标准化数据上),各列对应 U1U_1U1U2U_2U2V1V_1V1V2V_2V2
  • 载荷矩阵表:原始变量与典型变量的相关(structure coefficients),以及交叉载荷(原始变量与对侧典型变量的相关);
  • 冗余度表:两侧方向的方差解释比例与冗余指数(4.3 节)。

解读顺序建议严格按"先检验、再载荷、后权重"推进:ppp 值不显著就停止;显著后先看载荷识别"每个典型变量实质携带哪些变量"(载荷绝对值 > 0.5 为显性成员,6.3.3 节),再看权重确认合成公式——先载荷后权重的次序能避开共线环境下的权重误读。

5.1.4 SPSS 结果导出与三线表制作

SPSS 原生输出是图文混排的查看器格式,不适合直接进论文。导出流程分三步:其一,在查看器里对目标表格右键"复制"或以 .spv 文件保存;其二,把数值粘贴到 Excel/WPS 中,按中文期刊三线表规范重新排版——顶线粗、栏目线细、底线粗,无线条封口与竖线;其三,把显著性符号(∗^*∗∗^{**}∗∗)与检验统计量标注为表注放在表下方。为降低手工出错率,建议在语法中直接输出到 Excel(OUTPUT MODIFYOMS 子系统可将指定表块导出为 .xls),再以脚本统一格式化——第 6.5.1 节给出三线表的完整排版规范与模板。

认知检查点: SPSS 的实操心法是"菜单探索、语法固化":先点菜单看结果形态,再把关键操作粘贴为语法存档——输出查看器里的每一张表都能在语法中定位到对应命令,分析报告的可复现性由此而来。

5.2 R 语言实现

5.2.1 基础包 stats::cancor 的使用

R 基础包 stats 自带的 cancor 函数是零依赖的最简入口:

# 数据:x 为生理指标组数据框(3 列),y 为体测成绩组数据框(2 列)
res <- cancor(x = as.matrix(physio), y = as.matrix(score))
res$cor          # 典型相关系数 r1, r2
res$xcoef        # X 组权重矩阵(每列一个典型方向)
res$ycoef        # Y 组权重矩阵
res$xcenter; res$ycenter   # 中心化偏移(用于新样本打分)

cancor 的数值底层正是 2.3.4 节的相干矩阵 SVD 路径:对标准化后的数据做 QR 分解、再对相干矩阵取奇异值,因此它不需要显式求逆,数值稳健。它的主要短板是不输出显著性检验、载荷矩阵与冗余度——需要后续手工补充,因此在教学与快速检查中好用,论文级分析推荐 5.2.2 的 CCA 包。

5.2.2 CCA 包的 cc() 函数完整流程

CCA 包(González 等)的 cc 函数把检验、载荷与冗余一次配齐,是 R 端经典 CCA 的主力接口。完整流程:

library(CCA)
res <- cc(X = physio, Y = score)     # 返回典型相关、权重与载荷

# 显著性检验(整体 + 逐级):借助 CCP 包
library(CCP)
p_asym <- p.asym(rho = res$cor, N = nrow(physio), p = 3, q = 2, tstat = "Wilks")
p_asym$p.value                      # 各"至少保留前 k 对"的 p 值序列

# 冗余分析
r1 <- comput(res, X = physio, Y = score)   # 载荷与交叉载荷
rd <- r1$Rdx2 %*% (res$cor^2); rd          # 冗余指数(X 对 Y 方向)

解读输出时注意 cc 返回的 xcoef/ycoef 默认针对原始(未标准化)数据,comput 给出的载荷基于标准化相关;若需要标准化权重,先对两数据框做 scale() 再调用 cc。各对象在内存中的对应关系是本章"结果出口"的核心:res$cor 是系数表、p_asym$p.value 是检验表、r1 是载荷表,三个对象拼起来就是 SPSS 五张表的内容。

5.2.3 自定义显著性检验与冗余分析代码

不依赖 CCP 时,Bartlett 检验与冗余指数各用十余行即可手写,既加深理解也便于移植:

wilks_seq <- function(rho, n, p, q) {
  m <- length(rho)
  out <- data.frame(k = 0:(m - 1), Lambda = NA, chisq = NA, df = NA, p = NA)
  for (k in 0:(m - 1)) {                       # 从全对开始逐级剔除
    Lam <- prod(1 - rho[(k + 1):m]^2)          # 剩余对的乘积
    df  <- (p - k) * (q - k)
    chisq <- -(n - 1 - (p + q + 1) / 2) * log(Lam)
    out[k + 1, -1] <- c(Lam, chisq, df, pchisq(chisq, df, lower.tail = FALSE))
  }
  out                                          # 对应执行快照:逐行给出逐步检验表
}

该函数的实现与 4.1.3、4.2.1 的公式一一对应——循环变量 k 每推进一档,检验对象就从"全体相关"剔除当前最大的那一对,这与图 4-5 的状态机逐状态同步,代码中的每次循环即图中的一个"剔除最大对"转移。

5.2.4 可视化:典型载荷图 / 双标图(Biplot)

解读辅助图建议两张。其一,载荷双线图:用 matplot 分别绘制 X 组、Y 组的载荷向量随典型轴变化的折线,直观显示"哪个变量在哪一对上贡献大";其二,典型得分双标图

U <- as.matrix(scale(physio)) %*% res$xcoef   # 样本的 U1, U2 得分
V <- as.matrix(scale(score))  %*% res$ycoef   # 样本的 V1, V2 得分
plot(U[, 1], V[, 1], xlab = "U1", ylab = "V1") # 每点一个样本
abline(lm(V[, 1] ~ U[, 1]))                    # 回归线斜率即相关结构

散点围绕对角线方向的伸展程度直观呈现第一典型相关的大小;若有颜色可分组的类别变量(如训练组别),按组着色还能顺带检查关联结构是否由某子群主导。

5.3 Python 实现

5.3.1 scikit-learn 的 CCA 类(sklearn.cross_decomposition.CCA)

Python 生态的主入口是 scikit-learn 的 CCA 类(位于 sklearn.cross_decomposition),它的接口遵循机器学习惯例:fit 拟合、transform 投影、score 打分。与 R 端"一次调用返回全表"的风格不同,sklearn 默认只做"求方向 + 打分",检验与载荷需要围绕其属性手工组装——这是两平台体验差异的最大来源,先建立预期再上手。

5.3.2 完整流程:数据准备 → 拟合 → 变换 → 结果提取

import numpy as np, pandas as pd
from sklearn.cross_decomposition import CCA
from scipy.stats import chi2

X = df[["肺活量", "最大摄氧量", "体脂率"]].values   # X 组
Y = df[["百米用时", "耐力跑用时"]].values           # Y 组

model = CCA(n_components=2, scale=True)     # scale=True 即标准化
model.fit(X, Y)                             # 拟合:求解典型方向
U = model.transform(X)                      # 样本典型得分 U1, U2
V = model.transform(X, Y)                   # 注意接口:需同时传 X 定位

fit 完成后,方向向量在 model.x_rotations_(权重,符号与 model.y_rotations_ 已按"使 U、V 相关为正"对齐)。典型相关系数不在属性里,需要显式计算:

# 每列一个典型方向:对样本得分求相关
r = [np.corrcoef(U[:, i], V[:, i])[0, 1] for i in range(2)]

5.3.3 典型相关系数 / 载荷矩阵 / 交叉载荷的计算

sklearn 不直接给载荷,需要两步补全:先算"原始变量与自身侧典型得分的相关"(载荷),再算"与对侧典型得分的相关"(交叉载荷):

def loadings(A, S):
    # A: 标准化原始数据 (n x d);S: 典型得分 (n x k)
    A = (A - A.mean(0)) / A.std(0)
    return np.corrcoef(A.T, S.T)[:A.shape[1], A.shape[1]:]

Lx = loadings(X, U)   # X 组载荷:Lx[j, i] = corr(变量 j, U_i)
Ly = loadings(Y, V)   # Y 组载荷
CLx = loadings(X, V)  # 交叉载荷:corr(X 变量, V_i)
CLy = loadings(Y, U)

显著性检验同样手工组装(与 5.2.3 的 R 版逐行对应):

def wilks_seq(r, n, p, q):
    m, res = len(r), []
    for k in range(m):
        Lam  = np.prod(1 - np.array(r[k:]) ** 2)
        df   = (p - k) * (q - k)
        chisq = -(n - 1 - (p + q + 1) / 2) * np.log(Lam)
        res.append((k + 1, Lam, chisq, df, chi2.sf(chisq, df)))
    return pd.DataFrame(res, columns=["保留前k对", "Lambda", "chisq", "df", "p"])

5.3.4 可视化:matplotlib 绘制双标图与相关性热图

import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].scatter(U[:, 0], V[:, 0])          # 双标图:U1 vs V1
axes[0].set(xlabel="U1", ylabel="V1")
# 相关性热图:载荷矩阵 Lx 的行=变量、列=典型轴
im = axes[1].imshow(Lx, cmap="RdBu_r", vmin=-1, vmax=1, aspect="auto")
axes[1].set(yticks=range(X.shape[1]), yticklabels=cols_x, xlabel="典型轴")
plt.colorbar(im, ax=axes[1]); plt.tight_layout(); plt.show()

热图是载荷矩阵的"最速阅读形式":行变量、列典型轴,颜色深浅直接给出 6.3 节的显著载荷识别结果。

5.4 三大平台结果对比与一致性验证

5.4.1 典型相关系数的一致性

理论底线:三平台解同一数学问题,r1,r2r_1,r_2r1,r2 应一致到小数点后 6~8 位(差异源于 SVD 与广义特征路径的舍入次序)。将三处输出并排,若某平台的第一典型相关与其余平台差超过 10−410^{-4}104,先查数据读取(列序颠倒、缺失值处理口径不同),再查标准化开关,最后查是否对协方差而非相关矩阵求解。数据与统计量的接口流向如图 5-3 所示。

同一数据文件

SPSS求解

R求解

Python求解

系数对照表

图 5-3 三平台一致性验证的接口链路(图注:本图展示跨平台核验的数据流向,蓝色是各平台的求解接口,紫色是汇合后的对照表。请重点看三个关键节点:三路输入必须来自同一份清洗后的数据文件——数据在前端分叉,数值在后端就无法对齐;求解接口内部的路径不同(SPSS 广义特征、R 的 QR+SVD、sklearn 的迭代 NIPALS 类算法),但数学解唯一;对照表输出只需盯三个数字——第一、第二典型相关与整体检验 p 值,三者一致即判定通过。)

5.4.2 标准化系数的符号一致性

相关系数一致后,权重符号仍需对齐——因为特征向量差一个全局符号仍是特征向量,三个平台可能给出 +0.62+0.62+0.62−0.62-0.620.62 的同一权重。对齐约定:UUUVVV 的第一对典型相关为正(即若原始解的相关为负,把 a\boldsymbol{a}ab\boldsymbol{b}b 整体乘 −1-11)。sklearn 已内置该对齐;R 的 cancor 默认保证相关为正;SPSS 的输出符号约定在部分版本中与 R 相反——比对权重时先按"相关系数为正"重排符号再比较绝对值,避免误判平台差异。

5.4.3 平台间差异的来源分析

数值一致的结论背后,差异仍可能来自五个来源,排查顺序如表 5-1 所示。

表 5-1 跨平台差异来源排查表

排查层级差异来源症状处置
1 数据缺失值口径不同样本量对不上统一逐列删除或插补方案
2 数据列顺序/变量名错位载荷张冠李戴核对列名映射表
3 预处理标准化开关不一致权重尺度差若干倍统一 scale 后再比较
4 数学相关 vs 协方差路径系数轻微漂移显式指定用相关矩阵
5 数值迭代收敛阈值末位小数差异提高收敛精度/容忍 10−410^{-4}104

认知检查点: 跨平台验证的本质是"用同一份数据做控制实验":相关系数必须一致到浮点精度、权重允许整体符号翻转、载荷必须逐变量对齐;任何超出这三条的差异都指向数据或预处理层的错误,而不是平台"各有各的算法"——统计软件没有意见分歧的资格。

输出五张表各自承担一个解读任务,其归属关系、三平台的模块分工、跨平台验证的协同闭环以及实现的整体分层,分别如图 5-4、图 5-5、图 5-6 与图 5-7 所示。

输出解读体系

系数表

检验表

权重表

载荷表

冗余表

排序解读

逐级判定

配方识别

成员认定

解释量化

图 5-4 输出表与解读任务的知识图谱(图注:本图展示五张输出表各自服务的解读环节,红色根节点是输出体系,蓝色是五张表,橙色是各表的解读产物。请重点看:系数表管强度排序、检验表管资格、权重表管合成配方、载荷表管成员认定、冗余表管解释量化——五表各司其职,正是第六章逐节展开的解读地图;任何一张表缺位,对应的解读环节就失去数据支撑。)

Python模块

fit与transform

检验载荷补装

R模块

cc求解

CCP与comput

SPSS模块

菜单或宏

查看器出品

图 5-5 三平台执行模块设计图(图注:本图并列三大平台的实现模块,每个模块内为"主入口—配套工序"的两级橙链。请重点看:SPSS 的配套工序在查看器导出,R 的配套工序由 CCP/comput 补齐检验与载荷,Python 的配套工序是手工补装代码——三个模块的主入口数学同解,差异全在"配套工序放哪个环节"。)

数据疑点反馈

三平台求解

系数比对

符号对齐

差异定位

验证通过

图 5-6 跨平台验证的协同闭环(图注:本图展示一致性验证的闭环,橙色是验证环节,紫色是放行输出,虚线是疑点反馈边。请重点看:系数比对与符号对齐两道工序拦截两类最典型差异;差异定位按表 5-1 的五层排查表逐层下探;疑点一旦定位到数据层,反馈虚线把流程送回求解起点——验证不是一次通过就结束,而是以"数据一致"为终止条件的循环。)

输出层

求解层

数据层

数据文件

预处理约定

典型求解

检验载荷

结果出口

可复现脚本

图 5-7 实操实现的三层架构总览(图注:本图分层展示实现全流程,分层配色——黄色数据层界定输入与预处理约定,蓝色求解层完成分析与检验,紫色输出层给出结果出口与可复现脚本。请重点看:预处理约定是数据层通住求解层的规格书,两个平台若在此处分叉,下游一切比对都失去意义;可复现脚本是输出层的最佳形态——"结果出口 + 脚本存档"齐备,分析才真正完成。)

本章小结:实操实现留下的四个判断

第一,流程骨架平台无关,差异全在"结果出口"。数据读入、标准化、求解、检验、载荷五步在三平台一一对应,真正的学习成本是记住各自的对象与属性:SPSS 看查看器、R 看 cc 对象、Python 看 model 属性。

第二,SPSS 的黄金习惯是"粘贴语法"。菜单用于探索、语法用于存档,OMS 导出是批量出表的捷径;只会点菜单的分析不可复现,等于没做。

第三,R 与 Python 的互补格局:R 的 CCA::cc + CCP 一条龙覆盖经典分析全流程;Python 的 sklearn 是工程化与机器学习的入口,检验与载荷需手工组装——5.3.3 节的 30 行补全代码应视作标准配置随项目存档。

第四,一致性验证是每次分析发布的"出厂质检"。系数一致、符号按约定对齐、差异按五层排查表定位——这三条工序加起来不超过十分钟,却能拦住绝大多数"换了个软件结果就变了"的冤案。

代码是语言的外壳,解读是分析的内核。下一章把注意力从"怎么算出来"转向"怎么说清楚":标准化系数的稳定性陷阱、载荷矩阵的显著性阈值、方差解释与冗余度在论文中的标准表述,以及 APA 格式的 CCA 结果报告模板。

参考文献(本章)

[1] González I, Déjean S, Martin P G P, Baccini A. CCA: An R package to extend canonical correlation analysis[J]. Journal of Statistical Software, 2008, 23(12): 1-14.

[2] scikit-learn developers. sklearn.cross_decomposition.CCA: Documentation[EB/OL]. https://scikit-learn.org.

[3] IBM SPSS Statistics Documentation: Canonical Correlation[EB/OL].

[4] Pedregosa F, et al. Scikit-learn: Machine learning in Python[J]. Journal of Machine Learning Research, 2011, 12: 2825-2830.

[5] 张文彤, 董伟. SPSS 统计分析高级教程[M]. 北京: 高等教育出版社.

[6] 何晓群. 多元统计分析[M]. 北京: 中国人民大学出版社.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorShift

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值