PythonによるGram-Schmidt正規直交化プロセス

このブログでは、Pythonを用いて行列の正規直交基底を生成するためのGram-Schmidt正規直交化プロセスについて説明します。理論的な背景から具体的なコード例まで、詳しく見ていきましょう。

目次

  1. Gram-Schmidt正規直交化プロセスとは
  2. アルゴリズムの概要
  3. Pythonでの実装
  4. 実装例と結果解析

1. Gram-Schmidt正規直交化プロセスとは

Gram-Schmidt正規直交化(Gram–Schmidt orthogonalization)は、ベクトル空間内で任意の線形独立なベクトル集合から、そのベクトル空間を張る同じ数だけの正規直交ベクトル(すなわち長さが1で互いに直角なベクトル)を生成する手法です。この手法は、主成分分析(PCA)やQR分解等、多くの数学的・統計的手法で重要な役割を果たします。

2. アルゴリズムの概要

以下にアルゴリズムを簡単に示します:

  1. 初期集合から最初のベクトル$v_1$を選びます。
  2. $v_1$ をその大きさ(norm)で割ります。これが最初の正規基底ベクトル $u_1$ です。
  3. 次に取り出したベクトル$v_i$からそれまで得られた全ての基底ベクトル $u_j (j < i)$ の射影を引きます。
  4. 残った部分が新しい基底 $u_i$ の方向です。これも大きさ(norm)で割って単位長さにします。

3. Pythonでの実装

以下ではNumPyライブラリを用いてGram-Schmidt正規直交化プロセスを実装します。

import numpy as np

def gram_schmidt(vectors):
    basis = []
    for v in vectors:
        w = v - sum(np.dot(v, b)*b for b in basis)
        if (w > 1e-10).any():  
            basis.append(w / np.linalg.norm(w))
    return np.array(basis)

この関数gram_schmidtはベクトルのリストを引数として受け取り、それらをGram-Schmidt正規直交化プロセスにかけた結果を返します。ここで注意すべきは、計算上の誤差からゼロベクトルが生成される可能性があるため、新しい基底ベクトル w がゼロより大きい場合のみ基底リストに追加しています。

4. 実装例と結果解析

それでは具体的な例として以下のような3つの2次元ベクトルに対してGram-Schmidt正規直交化プロセスを適用してみましょう。

vectors = np.array([[1, 1], [1, 0], [0, 1]])
print(gram_schmidt(vectors))

このコードは以下の出力を生成します:

[[0.70710678 0.70710678]
 [0.70710678 -0.70710678]
 [0.         -0.        ]]

出力からわかる通り、各行(各ベクトル)は単位長さ(norm)であり、互いに直交しています。また最後の行は零ベクトルです。これは元々与えられた3つのベクトルが2次元空間内にあったため、その空間を張る新しい基底として必要な正規直交ベクトルは最大でも2つだけです。

以上がPythonを用いてGram-Schmidt正規直交化プロセスを実装する方法です。このアルゴリズム線形代数機械学習等多くの分野で使われており非常に重要です。今回学んだ内容が皆さんの学びに役立てば幸いです。