Numpyで固有値と固有ベクトルを取得する方法 – linalg.eig

NumPy で行列の固有値と固有ベクトルを取得するには、linalg.eig を使う方法と linalg.eigvals を使う方法があります。前者は固有値と固有ベクトルの両方を取得するのに対して、後者は固有値のみを取得します。それぞれ見ていきましょう。

目次

1. 固有値・固有ベクトルとは

最初に固有値と固有ベクトルについて軽くおさらいしましょう。固有ベクトルはある行列による線形変換で向きを変えないベクトルであり、固有値は線形変換のときの固有ベクトルの倍数です。以下のアニメーションですぐに確認することあができます。

なお「固有値と固有ベクトルとは何か?幾何学的意味と計算方法」で詳しく解説しているので、ぜひご確認ください。

これらを計算で求めるときは、まず以下の固有方程式から固有値を求めます。

固有方程式

\[
|A−\lambda I| = 0
\]

実際の計算を確認する

以下の行列の固有値を求めるとします。

\[
A=\left[ \begin{array}{cc}3&1 \\ 0&2 \end{array} \right]
\]

これを固有方程式に当てはめると以下のようになります。

\[\begin{eqnarray}
|A−\lambda I|
&=&
\left|
\left[\begin{array}{cc} 3 & 1 \\ 0 &2 \end{array} \right]

\lambda
\left[\begin{array}{cc} 1 & 0 \\ 0 & 1 \end{array}\right]
\right|\\
&=&
\left|
\left[\begin{array}{cc} 3 & 1 \\ 0 &2 \end{array} \right]

\left[\begin{array}{cc} \lambda & 0 \\ 0 & \lambda \end{array}\right]
\right|\\
&=&
\left|\begin{array}{cc} 3−\lambda & 1 \\ 0 & 2−\lambda \end{array} \right|\\
&=&
(3-\lambda)(2-\lambda)-(1)(0) \\
&=&(3-\lambda)(2-\lambda) \\
&=&0
\end{eqnarray}\]

ここから \(\lambda=3, 2\) ということがわかります。

次に求めた固有値を代入して以下の連立方程式を解けば、固有ベクトルが得られます。

固有ベクトルを求めるための連立方程式

\[
[A-\lambda I]
\left[ \begin{array}{cc} x \\ y \end{array} \right]
=
0
\]

実際の計算を確認する

この連立方程式に上で求めた \(\lambda=3 , 2\) を代入して解くだけです。\(\lambda=2\) の場合を解いてみましょう(「連立方程式を行列で解く方法」を参考にしてください)。。

\[\begin{eqnarray}
A-\lambda I \left[\begin{array}{cc} x \\ y \end{array} \right]
=
\left[ \begin{array}{cc} 0 \\ 0 \end{array} \right] \\
\rightarrow
\left[ \begin{array}{cc} 3−\lambda & 1 \\ 0 &2−\lambda \end{array} \right]
\left[ \begin{array}{cc} x \\ y \end{array} \right]
=
\left[ \begin{array}{cc} 0 \\ 0 \end{array} \right]\\
\rightarrow
\left[ \begin{array}{cc} 3−2 & 1 \\ 0 & 2−2 \end{array} \right]
\left[ \begin{array}{cc} x \\ y \end{array} \right]
=
\left[ \begin{array}{cc} 0 \\ 0 \end{array} \right]\\
\rightarrow
\left[ \begin{array}{cc} 1 & 1 \\ 0 &0 \end{array} \right]
\left[ \begin{array}{cc} x \\ y \end{array} \right]
=
\left[ \begin{array}{cc} 0 \\ 0 \end{array} \right]\\
\end{eqnarray}\]

これによって以下の解が導かれます。

\[
\begin{cases}
1x+1y = 0 \\
0x+0y = 0 \\
\end{cases}
\rightarrow
y = −x
\]

つまり、\(y = −x\) 上にあるすべてのベクトル (\(\left[ \begin{array}{cc} 1 \\ -1 \end{array} \right] \)など)が、行列 \(A\) の固有ベクトルであり、その固有値は \(2\) であるということです。

このように手計算は面倒ですが、numpy.linalg.eignumpy.linalg.eigvals で簡単に求めることができます。

2. linalg.eig の使い方

linalg.eig の書き方は以下の通りです。

numpy.linalg.eig

書き方

LA.eig(a)

パラメーター

引数 解説
a   array_like or
list of array_like    
固有値と固有ベクトルを求めたい行列を渡します。

公式ドキュメント:numpy.linalg.eig

早速サンプルコードで使い方を確認しましょう。

以下の行列の固有値と固有ベクトルを求めてみます。

\[
\left[ \begin{array}{cc}3&1 \\ 0&2 \end{array} \right]
\]

次のようになります。

In [1]:
import numpy as np
import numpy.linalg as LA
a=np.array([[3,1],[0,2]])
LA.eig(a)
Out[1]:
(array([3., 2.]),
 array([[ 1.        , -0.70710678],
        [ 0.        ,  0.70710678]]))

このように戻り値は2種類あります。最初の配列には固有値が、2つ目の配列には固有ベクトルが格納されています。具体的には2つ目の配列の列ベクトルがそうです。

つまり、固有値 \(3\) の固有ベクトルが \(\left[ \begin{array}{cc} 1 \\ 0 \end{array} \right] \) で、固有値 \(2\) の固有ベクトルが \(\left[ \begin{array}{cc} -0.707… \\ 0.707… \end{array} \right] \) ということです。なお固有ベクトルは、ベクトルの長さが1になるように正規化されたものです。

以下のように、この2つの戻り値を別々の代数に編入するとさらに確認しやすくなります。

In [2]:
# 固有値をv、固有ベクトルをwに代入
w,v = LA.eig(a)
w
Out[2]:
array([3., 2.])
In [3]:
v
Out[3]:
array([[ 1.        , -0.70710678],
       [ 0.        ,  0.70710678]])

また固有ベクトルが複素数になるような場合(回転行列など)も対応してくれます。

In [4]:
a=np.array([[0,0, 1],[0,1,0],[-1,0,0]])
w,v = LA.eig(a)
print("w\n",w)
print("v\n",v)
w
 [0.+1.j 0.-1.j 1.+0.j]
v
 [[0.70710678+0.j         0.70710678-0.j         0.        +0.j        ]
 [0.        +0.j         0.        -0.j         1.        +0.j        ]
 [0.        +0.70710678j 0.        -0.70710678j 0.        +0.j        ]]

3. linalg.eigvals の使い方

なお固有値のみを取得したい場合は、linalg.eigvals が便利です。

numpy.linalg.eigvals

書き方

LA.eigvals(a)

パラメーター

引数 解説
a   array_like or
list of array_like    
固有値と固有ベクトルを求めたい行列を渡します。

公式ドキュメント:numpy.linalg.eigvals

以下のように固有値のみを返します。

In [1]:
import numpy as np
import numpy.linalg as LA
a=np.array([[3,1],[0,2]])
LA.eigvals(a)
Out[1]:
array([3., 2.])
In [2]:
a=np.array([[0,0, 1],[0,1,0],[-1,0,0]])
LA.eigvals(a)
Out[2]:
array([0.+1.j, 0.-1.j, 1.+0.j])

複数の行列の固有値を一括取得することもできます(linalg.eig でもできますが…)。

In [3]:
a=np.array([[[3,1],[0,2]],[[1,1],[0,1]],[[0,0],[0,0]]])
LA.eigvals(a)
Out[3]:
array([[3., 2.],
       [1., 1.],
       [0., 0.]])

4. まとめ

以上が行列の固有値と固有ベクトルを取得する linalg.eig の使い方です。



よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる