Rで線形代数:冪等行列

Rで 線形代数:冪等行列 を確認します。

1. 冪等行列(Idempotent Matrix)とは

定義

ある正方行列 A が、自分自身との積(2乗)をとっても結果が変わらないとき、その行列 A冪等行列と呼びます。数式で書くと以下のようになります。

A² = A

ここで A × A を意味します。

「冪等(べきとう)」という言葉は、数学や計算機科学の分野で「ある操作を何度行っても、結果が同じである」という性質を指す言葉です。

簡単な例

最も単純な冪等行列は単位行列 Iゼロ行列 O です。

  • 単位行列 I: I × I = I なので、冪等行列です。
  • ゼロ行列 O: O × O = O なので、冪等行列です。

もう少し具体的な例を見てみましょう。

A = [[1, 0], [0, 0]] という行列の場合、

A² = [[1, 0], [0, 0]] × [[1, 0], [0, 0]]
   = [[1*1 + 0*0, 1*0 + 0*0], [0*1 + 0*0, 0*0 + 0*0]]
   = [[1, 0], [0, 0]]

となり、A² = A が成り立つため、この行列 A も冪等行列です。

幾何学的な意味:射影

冪等行列を理解する上で最も重要なのが、「射影(Projection)」という幾何学的なイメージです。

冪等行列は、あるベクトルを特定の空間(部分空間)に射影(影を落とす)する操作と考えることができます。

例えば、3次元空間の点 v を xy平面に射影する操作を行列 P で表したとします。

  1. vP を作用させると、xy平面上の点 v' に移ります (v' = Pv)。
  2. この v' は既にxy平面上にあるので、もう一度xy平面に射影しても位置は変わりません。
  3. つまり、P(Pv) = Pv が成り立ちます。これは行列で書くと P²v = Pv となり、P² = P を意味します。

このように、冪等行列は「一度、射影したら、何度射影しても同じ場所」という性質を持つ射影行列として解釈できます。

主な性質

冪等行列には、以下のような重要な性質があります。

  1. 固有値は 0 または 1 のみ: 冪等行列の固有値は必ず 0 か 1 のどちらかになります。
  2. ランクとトレースが等しい: 行列のランク(rank)とトレース(trace: 対角成分の和)が等しくなります。 rank(A) = tr(A)
  3. I - A も冪等行列: A が冪等行列ならば、I - AIは単位行列)もまた冪等行列になります。
  4. 正則性: 冪等行列が正則(逆行列を持つ)であるのは、それが単位行列 I である場合だけです。

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

ハット行列 H を例にシミュレーションします。ハット行列は以下の式で定義されます。

H = X (XᵀX)⁻¹ Xᵀ

  • X: デザイン行列(説明変数のデータ)
  • Xᵀ: Xの転置行列
  • (XᵀX)⁻¹: XᵀXの逆行列

このハット行列 H が冪等行列であること(H² = H)と、その性質を確認します。

Rコード

# --------------------------------------------------
# 冪等行列のシミュレーション
# --------------------------------------------------

# 1. データの準備(デザイン行列 X の作成)
seed <- 20250623
set.seed(seed)

# 観測数 n=10, 説明変数の数 p=3 のランダムな行列Xを作成
X <- matrix(rnorm(10 * 3), nrow = 10, ncol = 3)

# 2. ハット行列 H の計算
# H = X %*% solve(t(X) %*% X) %*% t(X)
#   t(X): Xの転置
#   solve(): 逆行列を計算
#   %*%: 行列の積
XtX_inv <- solve(t(X) %*% X)
H <- X %*% XtX_inv %*% t(X)

cat("ハット行列 H (最初の5x5部分) を表示:\n")
print(round(H[1:5, 1:5], 4))


# 3. 冪等性の確認 (H^2 = H)
cat("\n--- 1. 冪等性の確認 (H^2 = H) ---\n")

# Hの2乗を計算
H2 <- H %*% H

# H と H2 が等しいかを確認
check_idempotent <- all.equal(H, H2)

if (isTRUE(check_idempotent)) {
  cat("確認結果: H^2 = H が成り立ちます。Hは冪等行列です。\n")
} else {
  cat("確認結果: H^2 = H は成り立ちませんでした。\n")
  print(check_idempotent) # 差分を表示
}


# 4. 性質の確認
cat("\n--- 2. 性質の確認 ---\n")

# (a) 固有値が 0 または 1 であることの確認
eigen_values <- eigen(H)$values

cat("(a) 固有値の確認:\n")
# 計算誤差を考慮して、小数点以下6桁で丸めて表示
print(round(eigen_values, 6))
cat("→ 固有値がすべて 0 または 1 になっていることがわかります。\n\n")

# (b) rank(H) = tr(H) であることの確認
# ランクの計算
rank_H <- qr(H)$rank

# トレースの計算 (対角成分の和)
trace_H <- sum(diag(H))

cat("(b) ランクとトレースの確認:\n")
cat("ランク (rank):", rank_H, "\n")
cat("トレース (trace):", trace_H, "\n")
cat("→ ランクとトレースが一致していることがわかります。\n")
# 理論上、ハット行列のランクとトレースは説明変数の数(p=3)に等しくなります。


# (c) I - H も冪等行列であることの確認
cat("\n--- 3. (おまけ) I - H の冪等性の確認 ---\n")

# Hと同じサイズの単位行列Iを作成
I <- diag(nrow(H))
ImH <- I - H

# (I-H)の2乗を計算
ImH2 <- ImH %*% ImH

check_ImH <- all.equal(ImH, ImH2)

if (isTRUE(check_ImH)) {
  cat("確認結果: (I - H)^2 = (I - H) が成り立ちます。I - H も冪等行列です。\n")
} else {
  cat("確認結果: (I - H)^2 = (I - H) は成り立ちませんでした。\n")
}
ハット行列 H (最初の5x5部分) を表示:
        [,1]    [,2]    [,3]    [,4]    [,5]
[1,]  0.0697 -0.0479  0.0053 -0.1107  0.0239
[2,] -0.0479  0.1138 -0.0806  0.0415 -0.2203
[3,]  0.0053 -0.0806  0.0812  0.0174  0.2004
[4,] -0.1107  0.0415  0.0174  0.1973  0.0449
[5,]  0.0239 -0.2203  0.2004  0.0449  0.5251

--- 1. 冪等性の確認 (H^2 = H) ---
確認結果: H^2 = H が成り立ちます。Hは冪等行列です。

--- 2. 性質の確認 ---
(a) 固有値の確認:
 [1] 1 1 1 0 0 0 0 0 0 0
→ 固有値がすべて 0 または 1 になっていることがわかります。

(b) ランクとトレースの確認:
ランク (rank): 3 
トレース (trace): 3 
→ ランクとトレースが一致していることがわかります。

--- 3. (おまけ) I - H の冪等性の確認 ---
確認結果: (I - H)^2 = (I - H) が成り立ちます。I - H も冪等行列です。

シミュレーションから、数式で定義されたハット行列が、実際に冪等行列の性質(A²=A、固有値が0か1、ランク=トレース)をすべて満たしていることが確認できました。

以上です。