Rで線形代数:偏差行列、分散共分散行列、相関行列

Rで 線形代数:偏差行列、分散共分散行列、相関行列 を確認します。

1. 偏差行列、分散共分散行列、相関行列の説明

偏差行列、分散共分散行列および相関行列の3つの行列により、データが持つばらつきや変数間の関係性を捉えられ、それらは 「データ行列 → 偏差行列 → 分散共分散行列 → 相関行列」の順番で導出されます。

準備:データ行列 (Data Matrix)

まず、すべての計算の出発点となるデータ行列 X を考えます。

これは、n個のサンプル(個体)と p個の変数(特徴量)からなる n × p の行列です。

  • : 各サンプル(例:生徒A, 生徒B, …)
  • : 各変数(例:数学の点数, 理科の点数, …)

a. 偏差行列 (Deviation Matrix)

偏差行列とは、データ行列の各要素から、その列(変数)の平均値を引いた行列です。

偏差行列の要素 = 元のデータ - その変数の平均値

つまり、各データ点が「平均からどれだけ離れているか」を表す偏差を集めた行列です。

この操作を中心化 (Centering) と呼びます。

偏差行列は、データのばらつきを分析する上での下準備となります。

b. 分散共分散行列 (Variance-Covariance Matrix)

分散共分散行列は、データのばらつき具合と、変数間の関係性を数値化した行列です。

p × p の正方行列になります。

  • 対角成分: 各変数の分散 (Variance) が入ります。

    • 分散は、その変数が単体でどれだけばらついているかを示す指標です。値が大きいほど、ばらつきが大きくなります。
  • 非対角成分: 2つの変数間の共分散 (Covariance) が入ります。

    • 共分散は、2つの変数が「一緒に動く」傾向を示す指標です。
      • 正の値: 一方が増えると、もう一方も増える傾向がある(例:身長と体重)。
      • 負の値: 一方が増えると、もう一方は減る傾向がある(例:勉強時間とゲーム時間)。
      • 0に近い値: 2つの変数に明確な関係性はない。

分散共分散行列 Σ は、偏差行列 D を使って以下のように計算できます。

Σ = (1 / (n-1)) * DᵀD

  • DᵀD: 偏差行列とその転置行列の積。これを偏差平方和・積和行列と呼びます。
  • 1 / (n-1): 不偏分散を計算するために n-1 で割ります(nはサンプル数)。

c. 相関行列 (Correlation Matrix)

分散共分散行列の共分散の値は各変数の単位(スケール)に依存します。(例:「身長(cm)と体重(kg)の共分散」と「身長(m)と体重(g)の共分散」では値が全く異なる)

そこで、単位の影響を取り除き、-1から1の範囲に正規化したものが相関行列 R です。

p × p の正方行列になります。

  • 対角成分: 必ず 1 になります。(自分自身との相関は完璧なので1)
  • 非対角成分: 2つの変数間の相関係数 (Correlation Coefficient) が入ります。

    • 相関係数は、-1から1の範囲の値を取ります。
      • +1に近い: 強い正の相関がある。
      • -1に近い: 強い負の相関がある。
      • 0に近い: ほとんど相関がない。

相関行列は、分散共分散行列 Σ を使って計算できます。

具体的には、Σ の各要素 σᵢⱼ を、対応する変数の標準偏差 sᵢsⱼ の積で割ることで得られます。

rᵢⱼ = σᵢⱼ / (sᵢ * sⱼ) (ここで s = √分散


2. Rによるシミュレーション

Rを使って、データ行列から偏差行列、分散共分散行列、相関行列を段階的に計算し、Rの組み込み関数(cov(), cor())の結果と一致することを確認します。

Rコード

# --------------------------------------------------
# 偏差行列、分散共分散行列、相関行列のシミュレーション
# --------------------------------------------------

# --- 準備: データ行列の作成 ---
# サンプル数 n=5, 変数の数 p=3
# 5人の生徒の「数学」「理科」「英語」の点数をイメージ
seed <- 20250624
set.seed(seed)
X <- matrix(round(runif(15, min = 50, max = 100)), nrow = 5, ncol = 3)
colnames(X) <- c("Math", "Science", "English")
rownames(X) <- paste0("Student", 1:5)

cat("--- 0. 元のデータ行列 X ---\n")
print(X)

# --- 1. 偏差行列 D の計算 (中心化) ---
cat("\n--- 1. 偏差行列 D の計算 ---\n")

# (a) 各列(変数)の平均を計算
col_means <- colMeans(X)
cat("各変数の平均:\n")
print(col_means)

# (b) Rのsweep()関数を使って、各要素から列平均を引く
# sweep(X, 2, STATS, FUN) は、行列Xの各行/列(2は列)にSTATSを適用する
D <- sweep(X, 2, col_means, FUN = "-")
cat("\n偏差行列 D:\n")
print(round(D, 2))

#
cat("\n(参考) Rのscale()関数も利用できます:\n")
scale(X, center = TRUE, scale = FALSE)


# --- 2. 分散共分散行列 Σ の計算 ---
cat("\n--- 2. 分散共分散行列 Σ の計算 ---\n")
n <- nrow(X) # サンプル数

# (a) D^T * D を計算(偏差平方和・積和行列)
DtD <- t(D) %*% D
cat("偏差平方和・積和行列 (D^T * D):\n")
print(round(DtD, 2))

# (b) サンプル数-1 (n-1)で割る
Sigma_manual <- (1 / (n - 1)) * DtD
cat("\n手計算による分散共分散行列 Σ:\n")
print(round(Sigma_manual, 2))

# (c) Rの組み込み関数 cov() の結果と比較
Sigma_builtin <- cov(X)
cat("\nRのcov()関数による分散共分散行列:\n")
print(round(Sigma_builtin, 2))
cat("→ 手計算の結果と一致しました。\n")


# --- 3. 相関行列 R の計算 ---
cat("\n--- 3. 相関行列 R の計算 ---\n")

# (a) 各変数の標準偏差を計算 (分散の平方根)
sds <- sqrt(diag(Sigma_manual))
cat("各変数の標準偏差:\n")
print(sds)

# (b) 標準偏差の逆数からなる対角行列を作成
# D_inv_sd = diag(1/s)
D_inv_sd <- diag(1 / sds)

# (c) R = D_inv_sd * Σ * D_inv_sd で計算
R_manual <- D_inv_sd %*% Sigma_manual %*% D_inv_sd
cat("\n手計算による相関行列 R:\n")
print(round(R_manual, 2))

# (d) Rの組み込み関数 cor() の結果と比較
R_builtin <- cor(X)
cat("\nRのcor()関数による相関行列:\n")
print(round(R_builtin, 2))
cat("→ 手計算の結果と一致しました。\n")
--- 0. 元のデータ行列 X ---
         Math Science English
Student1   72      94      85
Student2   81      73      94
Student3   91      69      71
Student4   54      74      87
Student5   67      50      75

--- 1. 偏差行列 D の計算 ---
各変数の平均:
   Math Science English 
   73.0    72.0    82.4 

偏差行列 D:
         Math Science English
Student1   -1      22     2.6
Student2    8       1    11.6
Student3   18      -3   -11.4
Student4  -19       2     4.6
Student5   -6     -22    -7.4

(参考) Rのscale()関数も利用できます:
         Math Science English
Student1   -1      22     2.6
Student2    8       1    11.6
Student3   18      -3   -11.4
Student4  -19       2     4.6
Student5   -6     -22    -7.4
attr(,"scaled:center")
   Math Science English 
   73.0    72.0    82.4 

--- 2. 分散共分散行列 Σ の計算 ---
偏差平方和・積和行列 (D^T * D):
        Math Science English
Math     786      26  -158.0
Science   26     982   275.0
English -158     275   347.2

手計算による分散共分散行列 Σ:
         Math Science English
Math    196.5    6.50  -39.50
Science   6.5  245.50   68.75
English -39.5   68.75   86.80

Rのcov()関数による分散共分散行列:
         Math Science English
Math    196.5    6.50  -39.50
Science   6.5  245.50   68.75
English -39.5   68.75   86.80
→ 手計算の結果と一致しました。

--- 3. 相関行列 R の計算 ---
各変数の標準偏差:
     Math   Science   English 
14.017846 15.668440  9.316652 

手計算による相関行列 R:
      [,1] [,2]  [,3]
[1,]  1.00 0.03 -0.30
[2,]  0.03 1.00  0.47
[3,] -0.30 0.47  1.00

Rのcor()関数による相関行列:
         Math Science English
Math     1.00    0.03   -0.30
Science  0.03    1.00    0.47
English -0.30    0.47    1.00
→ 手計算の結果と一致しました。

実行結果と解説

このシミュレーションを通じて、以下のことが確認できます。

  1. 偏差行列は、元のデータから平均を引くことで、データのばらつきそのものに焦点を当てるための前処理であること。
  2. 分散共分散行列は、偏差行列を使って計算され、各変数のばらつき(分散)と変数間の関係(共分散)を表すこと。
  3. 相関行列は、分散共分散行列を各変数の標準偏差で正規化することで、単位に依存しない-1から1の範囲の関係性の強さ(相関係数)を示すこと。
  4. これらの手計算による導出プロセスが、Rの組み込み関数 cov()cor() が内部で行っている計算と一致していること。

以上です。