いろは2986023 views
LaTeX957300 views
小学社会308636 views
ヒストリア284143 views
中学英語808712 views
世界の国560595 views
高校化学2913383 views
中学社会667106 views
高校国語785655 views
高校生物549842 views
Help
Tools

English

固有値・固有ベクトルの意味と計算|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 倍に伸び、固有値 に対応する方向は長さが変わらない。

固有値 λ > 1

その方向に伸びる

固有値 0 < λ < 1

その方向に縮む

固有方程式

固有値は特性方程式(固有方程式)から求まる。

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 アルゴリズム、グラフのラプラシアン

制御工学

システムの安定性解析

固有値・固有ベクトルは抽象的に見えるが、「行列が何をしているか」を本質的に理解するための鍵だ。線形代数を深く学ぶほど、その重要性が実感できるだろう。