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 の使い方です。

Python初心者におすすめのプログラミングスクール

「未経験からでもPythonを学べるプログラミングスクールを探しているけど、色々ありすぎてわからない」なら、次の3つのプログラミングスクールから選んでおけば間違いはありません。

Aidemy Premium:全くの初心者ができるだけ効率よく短期間で実務的に活躍できるAI人材になることを目的とした講座。キャリアカウンセリングや転職エージェントの紹介などの転職支援も充実しており、受講者の転職成功率が高い。

AIジョブカレPythonの基本をおさえた人が、実際に機械学習やディープラーニングを活用できるようになるための講座。転職補償型があるなどキャリア支援の内容が非常に手厚く、講師の質も最高クラス。コスパ最高。Python初心者用の対策講座もある。

データミックスプログラミング経験者のビジネスマンが、更なるキャリアアップのためにデータの処理方法を学んでデータサイエンティストになるための講座。転職だけでなく起業やフリーランスとして独立する人も多い。Python初心者用の対策講座もある。

特に、あなたが以下のような目標を持っているなら、この中から選んでおけば間違いはないでしょう。

・未経験からPythonエンジニアとして就職・転職したい
・AIエンジニアやデータサイエンティストとしてキャリアアップしたい
・起業やフリーランスを視野に入れたい

理由は「Python初心者のためのおすすめプログラミングスクール3選」で解説しています。



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

この記事を書いた人

コメント

コメントする

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

目次
閉じる