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つの変数に明確な関係性はない。
- 共分散は、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に近い: ほとんど相関がない。
- 相関係数は、-1から1の範囲の値を取ります。
相関行列は、分散共分散行列 Σ
を使って計算できます。
具体的には、Σ
の各要素 σᵢⱼ
を、対応する変数の標準偏差 sᵢ
と sⱼ
の積で割ることで得られます。
rᵢⱼ = σᵢⱼ / (sᵢ * sⱼ)
(ここで s = √分散
)
2. Rによるシミュレーション
Rを使って、データ行列から偏差行列、分散共分散行列、相関行列を段階的に計算し、Rの組み込み関数(cov()
, cor()
)の結果と一致することを確認します。
Rコード
# --------------------------------------------------
# 偏差行列、分散共分散行列、相関行列のシミュレーション
# --------------------------------------------------
# --- 準備: データ行列の作成 ---
# サンプル数 n=5, 変数の数 p=3
# 5人の生徒の「数学」「理科」「英語」の点数をイメージ
<- 20250624
seed set.seed(seed)
<- matrix(round(runif(15, min = 50, max = 100)), nrow = 5, ncol = 3)
X 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) 各列(変数)の平均を計算
<- colMeans(X)
col_means cat("各変数の平均:\n")
print(col_means)
# (b) Rのsweep()関数を使って、各要素から列平均を引く
# sweep(X, 2, STATS, FUN) は、行列Xの各行/列(2は列)にSTATSを適用する
<- sweep(X, 2, col_means, FUN = "-")
D cat("\n偏差行列 D:\n")
print(round(D, 2))
#
cat("\n(参考) Rのscale()関数も利用できます:\n")
scale(X, center = TRUE, scale = FALSE)
# --- 2. 分散共分散行列 Σ の計算 ---
cat("\n--- 2. 分散共分散行列 Σ の計算 ---\n")
<- nrow(X) # サンプル数
n
# (a) D^T * D を計算(偏差平方和・積和行列)
<- t(D) %*% D
DtD cat("偏差平方和・積和行列 (D^T * D):\n")
print(round(DtD, 2))
# (b) サンプル数-1 (n-1)で割る
<- (1 / (n - 1)) * DtD
Sigma_manual cat("\n手計算による分散共分散行列 Σ:\n")
print(round(Sigma_manual, 2))
# (c) Rの組み込み関数 cov() の結果と比較
<- cov(X)
Sigma_builtin cat("\nRのcov()関数による分散共分散行列:\n")
print(round(Sigma_builtin, 2))
cat("→ 手計算の結果と一致しました。\n")
# --- 3. 相関行列 R の計算 ---
cat("\n--- 3. 相関行列 R の計算 ---\n")
# (a) 各変数の標準偏差を計算 (分散の平方根)
<- sqrt(diag(Sigma_manual))
sds cat("各変数の標準偏差:\n")
print(sds)
# (b) 標準偏差の逆数からなる対角行列を作成
# D_inv_sd = diag(1/s)
<- diag(1 / sds)
D_inv_sd
# (c) R = D_inv_sd * Σ * D_inv_sd で計算
<- D_inv_sd %*% Sigma_manual %*% D_inv_sd
R_manual cat("\n手計算による相関行列 R:\n")
print(round(R_manual, 2))
# (d) Rの組み込み関数 cor() の結果と比較
<- cor(X)
R_builtin 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から1の範囲の関係性の強さ(相関係数)を示すこと。
- これらの手計算による導出プロセスが、Rの組み込み関数
cov()
やcor()
が内部で行っている計算と一致していること。
以上です。