固有値・固有ベクトルの意味と計算|Python
固有値と固有ベクトルは線形代数の中心的な概念であり、主成分分析(PCA)、振動解析、量子力学など幅広い分野で応用される。その意味を理解し、Python での計算方法を学ぼう。
固有値・固有ベクトルとは
正方行列 に対して、次の関係を満たすスカラー とベクトル ()を考える。
このとき を固有値(eigenvalue)、 を固有ベクトル(eigenvector)と呼ぶ。
直感的には、行列 による変換で方向が変わらず、長さだけが 倍になるベクトルが固有ベクトルだ。
幾何学的な意味
2×2 行列で固有値の意味を視覚化してみよう。
import numpy as np
A = np.array([[2, 1], [1, 2]])
# 固有値と固有ベクトル
eigenvalues, eigenvectors = np.linalg.eig(A)
print(f'固有値: {eigenvalues}') # [3. 1.]
print(f'固有ベクトル:\n{eigenvectors}')この行列 は固有値 と を持つ。固有値 に対応する方向は 3 倍に伸び、固有値 に対応する方向は長さが変わらない。
その方向に伸びる
その方向に縮む
固有方程式
固有値は特性方程式(固有方程式)から求まる。
2×2 行列の場合、これは二次方程式になる。
# A = [[a, b], [c, d]] の固有値を求める公式
# λ² - (a+d)λ + (ad - bc) = 0
def eigenvalues_2x2(A):
"""2×2 行列の固有値を求める"""
a, b = A[0]
c, d = A[1]
trace = a + d # トレース(対角成分の和)
det = a * d - b * c # 行列式
# 二次方程式の解の公式
discriminant = trace**2 - 4 * det
if discriminant < 0:
# 複素固有値
real = trace / 2
imag = (-discriminant)**0.5 / 2
return (complex(real, imag), complex(real, -imag))
else:
sqrt_d = discriminant**0.5
return ((trace + sqrt_d) / 2, (trace - sqrt_d) / 2)
A = [[2, 1], [1, 2]]
print(eigenvalues_2x2(A)) # (3.0, 1.0)べき乗法(Power Method)
一般の行列に対して最大固有値を求める反復法がべき乗法だ。任意のベクトルに行列を繰り返し掛けると、最大固有値に対応する固有ベクトルの方向に収束する。
def power_method(A, max_iter=100, tol=1e-10):
"""べき乗法で最大固有値と固有ベクトルを求める"""
n = len(A)
# 初期ベクトル(ランダムでもよい)
v = [1.0] * n
for _ in range(max_iter):
# A @ v を計算
Av = [sum(A[i][j] * v[j] for j in range(n)) for i in range(n)]
# 最大成分で正規化
norm = max(abs(x) for x in Av)
v_new = [x / norm for x in Av]
# 収束判定
if all(abs(v_new[i] - v[i]) < tol for i in range(n)):
break
v = v_new
# 固有値はレイリー商で計算
Av = [sum(A[i][j] * v[j] for j in range(n)) for i in range(n)]
eigenvalue = sum(Av[i] * v[i] for i in range(n)) / sum(v[i]**2 for i in range(n))
return eigenvalue, v
A = [[2, 1], [1, 2]]
eigenvalue, eigenvector = power_method(A)
print(f'最大固有値: {eigenvalue:.6f}') # 3.000000
print(f'固有ベクトル: {eigenvector}')べき乗法は最大固有値しか求められないが、シンプルで大規模疎行列にも適用できる。
NumPy による計算
実務では NumPy の linalg.eig を使う。
import numpy as np
A = np.array([[4, -2], [1, 1]])
eigenvalues, eigenvectors = np.linalg.eig(A)
print(f'固有値: {eigenvalues}') # [3. 2.]
print(f'固有ベクトル:\n{eigenvectors}')固有ベクトルは列ベクトルとして返される。eigenvectors[:, i] が eigenvalues[i] に対応する固有ベクトルだ。
import numpy as np
A = np.array([[4, -2], [1, 1]])
eigenvalues, eigenvectors = np.linalg.eig(A)
# 検証: A @ v = λ * v
for i in range(len(eigenvalues)):
lam = eigenvalues[i]
v = eigenvectors[:, i]
Av = A @ v
lam_v = lam * v
print(f'λ={lam}: A@v = {Av}, λ*v = {lam_v}')対称行列の固有値
対称行列()は特別な性質を持つ。固有値はすべて実数で、固有ベクトルは互いに直交する。
import numpy as np
# 対称行列
A = np.array([[4, 2, 1],
[2, 5, 3],
[1, 3, 6]])
eigenvalues, eigenvectors = np.linalg.eigh(A) # eigh は対称行列専用
print(f'固有値: {eigenvalues}') # すべて実数
# 固有ベクトルの直交性を確認
print(f'直交性: {eigenvectors.T @ eigenvectors}') # 単位行列に近いlinalg.eigh は対称行列専用の関数で、linalg.eig より高速で数値的に安定だ。
応用例:主成分分析(PCA)
PCA はデータの共分散行列の固有値問題を解くことに帰着される。
import numpy as np
# サンプルデータ(3 次元、5 サンプル)
X = np.array([[2.5, 2.4, 1.0],
[0.5, 0.7, 0.3],
[2.2, 2.9, 1.5],
[1.9, 2.2, 1.2],
[3.1, 3.0, 1.8]])
# 中心化
X_centered = X - X.mean(axis=0)
# 共分散行列
cov_matrix = np.cov(X_centered.T)
# 固有値分解
eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)
# 固有値を降順にソート
idx = np.argsort(eigenvalues)[::-1]
eigenvalues = eigenvalues[idx]
eigenvectors = eigenvectors[:, idx]
print(f'固有値(寄与度): {eigenvalues}')
print(f'第 1 主成分: {eigenvectors[:, 0]}')固有値の大きい順に主成分を取ることで、次元削減が行える。
固有値の応用分野
PCA、特異値分解(SVD)、スペクトラルクラスタリング
振動解析、量子力学のシュレディンガー方程式
PageRank アルゴリズム、グラフのラプラシアン
システムの安定性解析
固有値・固有ベクトルは抽象的に見えるが、「行列が何をしているか」を本質的に理解するための鍵だ。線形代数を深く学ぶほど、その重要性が実感できるだろう。













