典型相关分析(canonical correlation analysis, CCA) - ricket-sjtu/bi028 GitHub Wiki

CCA的定义

虽然缩写都是CCA,但典型相关分析(canonical correlation analysis)与典型对应分析(canonical correspondence analysis)不同,前者的目的是识别并量化两个数据集之间的相关关系,关注的是两数据集各自的线性组合的相关关系(the correlation between the linear combination of the variables in one set and the linear combination of the variables in another set)

典型相关分析测定的是两个数据集(多个列向量)之间的相关程度,整个过程中试图把两高维数据的相关关系压缩到少数几个典型变量对之间(concentrate the relationship between two sets of variables into a few pairs of canonical variables)

CCA的基本思想

  1. 首先确定线性关系最强的“线性组合对”;
  2. 确定所有“线性组合对”中线性关系最强的,且与最初选出的“线性组合对”不相关的线性组合对

概念

  • 成对的线性组合称为典型变量(canonical variables)
  • 线性组合之间的相关性称为典型相关(canonical correlation)

假设第一组变量包含$p$个变量为随机向量$X^{(1)} \in \mathbb{R}^p \sim N(\mu^{(1)}, sigma_{11})$,第二组变量包含$q$个变量为随机向量$X^{(2)} \in \mathbb{R}^q \sim N(\mu^{(2)}, \sigma_{22})$,且有$p<q$,同时两者之间的协方差为$Cov(X^{(1)}, X^{(2)})=\sigma_{12} = \sigma_{21}$。

我们可以将两组变量写到一起,也就是: $$ X = \begin{pmatrix} X^{(1)}\ X^{(2)} \end{pmatrix} $$ 其期望值为: $$ \mu = \begin{pmatrix} E(X^{(1)})\ E(X^{(2)}) \end{pmatrix} = \begin{pmatrix} \mu^{(1)}\ \mu^{(2)} \end{pmatrix} $$ 以及协方差矩阵: $$ Cov(X) = \begin{pmatrix} \sigma_{11} & \sigma_{12}\ \sigma_{21} & \sigma_{22} \end{pmatrix} $$

分别构造$X^{(1)}$和$X^{(2)}$的线性组合,也就是 $$ \begin{array}{l} U = a^T X^{(1)}\ V = b^T X^{(2)}\ Var(U) = a^T Cov(X^{(1)}) a = a^T \sigma_{11} a\ Var(V) = b^T Cov(X^{(2)}) b = b^T \sigma_{22} b\ Cov(U, V) = a^T Cov(X^{(1)}, X^{(2)}) b = a^T \sigma_{12} b \end{array} $$

CCA的目的就是确定向量$a$, $b$,使得相关性系数最大化: $$ Corr(U, V) = \frac{a^T \sigma_{12} b}{\sqrt{a^T \sigma_{11} a} \sqrt{b^T \sigma_{22} b}} $$

第一组典型变量对,也就是具有单位方差的线性组合$U, V$,且$Corr(U, V)$

典型相关分析实例

一般典型相关分析可用cancor(x, y, xcenter=TRUE, ycenter=TRUE){stats}函数进行分析,函数的返回值包括

  • @cor: 典型相关系数;
  • @xcoef: 关于数据集x的典型载荷(canonical loading);
  • @xcenter: 数据集x的中心;
  • @ycoef:关于数据集y的典型载荷;
  • @ycenter:数据集y的中心

现对20名成年人测得

  • 三个生理指标:体重(X1,磅)、腰围(X2,英寸)、脉搏(X3,次/分);
  • 三个训练指标:引体向上(Y1)、仰卧起坐次数(Y2)、跳跃次数(Y3) 试分析这组数据的相关性
test.data <- data.frame(
  X1=c(191, 193, 189, 211, 176, 169, 154, 193, 176, 156, 189, 162, 182, 167, 154, 166, 247, 202, 157, 138),
  X2=c(36, 38, 35, 38, 31, 34, 34, 36, 37, 33, 37, 35, 36, 34, 33, 33, 46, 37, 32, 33),
  X3=c(50, 58, 46, 56, 74, 50, 64, 46, 54, 54, 52, 62, 56, 60, 56, 52, 50, 62, 52, 68),
  Y1=c( 5, 12, 13, 8, 15, 17, 14, 6, 4, 15, 2, 12, 4, 6, 17, 13, 1, 12, 11, 2),
  Y2=c(162, 101, 155, 101, 200, 120, 215, 70, 60, 225, 110, 105, 101, 125, 251, 210, 50, 210, 230, 110),
  Y3=c(60, 101, 58, 38, 40, 38, 105, 31, 25, 73, 60, 37, 42, 40, 250, 115, 50, 120, 80, 43)
  )
test.data <- scale(test.data)
ca <- cancor(test.data[, 1:3], test.data[, 4:6], 
             xcenter=TRUE, ycenter=TRUE)
ca
U <- as.matrix(test.data[, 1:3]) %*% ca$xcoef
V <- as.matrix(test.data[, 4:6]) %*% ca$ycoef
par(mfrow=c(1,3))
for (i in 1:3){
  plot(U[, i], V[, i], xlab=paste0('U', i), ylab=paste0('V', i))
}

相关系数检验

corcoef.test <- function(cor, n, p, q, alpha=.05) {
  #@cor - correlation coefficients;
  #@n - sample size; n>p+q
  #@p, q - number of variables in set 1 and set 2
  #@alpha - confidence level
  m <- length(cor)
  Q <- rep(0, m)
  lambda <- 1

  for (k in m:1) {
    lambda <- lambda * (1 - cor[k]^2)
    Q[k] <- -log(lambda)
  }

  s <- 0
  i <- m
  for (k in 1:m) {
    Q[k] <- (n-k+1-1/2*(p+q+3)+s)*Q[k]
    chi <- pchisq(Q[k], (p-k+1)*(q-k+1))
    if (chi > alpha) {
      i <- k-1; break
    }
    s <- s + 1/cor[k]^2
  }
  i
}

函数返回结果挑选第几对典型相关系数,以及典型相关对。