ノイマン級数
大学院の研究において、$(\mathbf{I} - a\mathbf{A})^{-1}$ を展開することができないか悩んでいて、ノイマン級数に知見を得たので、その内容をまとめる。
この記事では、ノイマン級数の定義、性質、および応用例について詳述する。特に、機械学習や推薦システムにおける利用例に焦点を当てる。数式とPythonのコードを用いて具体的な計算例を示す。
ソースコード
github
- jupyter notebook形式のファイルはこちら
google colaboratory
- google colaboratory で実行する場合はこちら
実行環境
OSはmacOSである。LinuxやUnixのコマンドとはオプションが異なることに注意。
!sw_vers
ProductName: macOS
ProductVersion: 13.5.1
BuildVersion: 22G90
!python -V
Python 3.9.17
基本的なライブラリをインポートし watermark を利用してそのバージョンを確認する。 ついでに乱数のseedの設定を行う。
import random
import numpy as np
seed = 123
random_state = 123
random.seed(seed)
np.random.seed(seed)
from watermark import watermark
print(watermark(python=True, watermark=True, iversions=True, globals_=globals()))
Python implementation: CPython
Python version : 3.9.17
IPython version : 8.17.2
numpy: 1.25.2
Watermark: 2.4.3
$(\mathbf{I} - a\mathbf{A})^{-1}$ のノイマン級数について
ノイマン級数を用いて $(\mathbf{I} - a\mathbf{A})^{-1}$ を表す方法は、行列 $\mathbf{A}$ と定数 $a$ に対して有用な逆行列の計算方法である。この展開は特に、$\mathbf{A}$ のスペクトル半径が小さい場合に有効である。見てわかるとおり、ノイマン級数は等比数列の和の公式:
$$ \sum_{n=0}^{\infty} a^n = \frac{1}{1 - a} $$
の行列への拡張版である。
定義
定数 $a$ と行列 $\mathbf{A}$ に対して、ノイマン級数を用いた $(\mathbf{I} - a\mathbf{A})^{-1}$ の展開は次のように表される:
$$ (\mathbf{I} - a\mathbf{A})^{-1} = \sum_{n=0}^{\infty} (a\mathbf{A})^n $$
収束条件
この級数が収束するためには、次の条件が必要である:
$$ |a| \cdot \rho(\mathbf{A}) < 1 $$
ここで、$\rho(\mathbf{A})$ は行列 $\mathbf{A}$ のスペクトル半径、つまり $\mathbf{A}$ の固有値の絶対値の最大値を表す。
Pythonによる実装例
以下のPythonコードは、ノイマン級数を用いて $(\mathbf{I} - a\mathbf{A})^{-1}$ を近似計算する例である。 3次のノイマン級数を計算するために、行列 $\mathbf{A}$ と定数 $a$ を定義し、ノイマン級数の和を計算する。
記載する意味があるかは不明だが、一応記載しておく。
import numpy as np
from pprint import pprint
# 適当な初期行列 A
A = np.array([[0.3, 0.2], [0.1, 0.4]])
# 適当な定数
a = 0.8
# スペクトル半径の計算
eigenvalues = np.linalg.eig(A)[0]
spectral_radius = max(abs(eigenvalues))
print(f"spectral_radius : {spectral_radius}")
# 収束条件
if abs(a) * spectral_radius < 1:
I = np.eye(A.shape[0])
# 逆行列の近似を計算
n_iter = 3
A_inv_approx = np.zeros_like(A)
for n in range(n_iter):
A_inv_approx += np.linalg.matrix_power(a * A, n)
# 最終的な逆行列の近似
A_inv_approx = np.dot(A_inv_approx, I)
print("=" * 20)
print("近似逆行列 : ")
pprint(A_inv_approx.round(2))
else:
print("収束条件 |a| * ρ(A) < 1 を満たしていない")
# 行列 A の逆行列を計算
A_inv = np.linalg.inv(I - a * A)
print("=" * 20)
print("逆行列 : ")
pprint(A_inv.round(2))
spectral_radius : 0.5
====================
近似逆行列 :
array([[1.31, 0.25],
[0.12, 1.44]])
====================
逆行列 :
array([[1.35, 0.32],
[0.16, 1.51]])
結論
ノイマン級数は、特定の条件下で効率的に逆行列を求める方法である。$(\mathbf{I} - a\mathbf{A})^{-1}$ のノイマン級数展開は、行列 $\mathbf{A}$ のスペクトル半径が小さい場合に有効であり、機械学習や線形代数の問題において広く応用されるらしい(知らなかったが…)。
参考文献
- Wikipedia: Neumann Series