固有値と固有ベクトルは行列の演算では重要な意味合いを持ってきます。
今回はその2つを求めるための関数であるlinalg.eig()関数についてみていきましょう。

固有値と固有ベクトル

まずは線形代数の中における固有値と固有ベクトルの意味についておさらいしておきます。

固有値と固有ベクトルはある正方行列A \\\\ に対して、

A\vec{x} = \lambda\vec{x}

を満たすようなスカラー\lambda \\\\ とベクトル\vec{x} \\\\ をそれぞれ 行列A \\\\ に対する固有値と固有ベクトルという表現をします。
このとき\vec{x} \\\\ \vec{x} \not= \vec{0} \\\\ を満たします。

この式によって固有値と固有ベクトルが定義されます。
この式は、ベクトル\vec{x} \\\\ を正方行列A \\\\ で線形変換したものがベクトル\vec{x} \\\\ \lambda \\\\ 倍になっていると読み換えることができます。

この固有値と固有ベクトルを使うことで行列A \\\\ を対角化することも可能です。
例えば、2×2の正方行列B \\\\ があったとします。
これの固有値とそれに対応する固有ベクトルをそれぞれ\lambda_1, \lambda_2 \\\\ \vec{x_1}, \vec{x_2} \\\\ だとします。
すると、

\left( \begin{array}{cc} \lambda_1 & 0 \\ 0 & \lambda_2 \\ \end{array} \right) \ \ = \ \left[ \begin{array}{c} \vec{x_1} & \vec{x_2} \ \end{array} \right]^{\mathrm{T}} A \left(\begin{array}{c} \vec{x_1} & \vec{x_2} \ \end{array} \right)\\

という具合に対角行列を生成することができるのです。

統計学でも固有値、固有ベクトルを用いた主成分分析といったものが存在します。

固有値、固有ベクトルの求め方

ここで固有値と固有ベクトルを計算で求めてみましょう。

まず、I を単位行列として、先ほどの固有値、固有ベクトルの定義式を変形すると

(A - \lambda I)\vec{x} = \vec{0}\\

という風になります。

\vec{x} \not= \vec{0} \\\\

であるので、この式を満たすためには

(A - \lambda I)= \vec{0} \\

である必要があります。
よって、\lambda \\\\

det(A - \lambda I)= 0 \\

となればよく、これを解くとA \\\\ の要素数に応じた\lambda \\\\ が得られます。
これによって得られた\lambda \\\\ を先ほどの

(A - \lambda I)\vec{x} = \vec{0}\\

に代入することによって、固有ベクトル\vec{x} \\\\ を得ることができます。

以下のサイトで更に詳しく解説されているので、参考にしてみてください。

固有値、固有ベクトルの定義と具体的な計算方法 –高校数学の美しい物語–

np.linalg.eig()

早速、関数の使い方をみていきましょう。

APIドキュメント

まずはAPIドキュメントからです。

numpy.linalg.eig(a)

args:

パラメータ名 概要
a shape=(….,M,M)となっているような配列 固有値と固有ベクトルを求めたい配列を指定します。

returns:

パラメータ名 概要
w shape=(…,M)の配列 それぞれの行列の固有値を含んだ配列を返します。
v shape=(…,M,M)の配列) それぞれの行列の固有ベクトルを返します。

引数は固有値や固有ベクトルを求めたい行列を指定するだけです。
この関数は固有値と固有ベクトル、2つの配列を返します。

サンプルコード

早速使い方をみていきましょう。
linalgモジュールはLAとしてimportするのが慣例のようなので、今回もそれに倣います。

使い方自体は複雑ではないのですぐに覚えられると思います。

In [1]: import numpy as np

In [2]: import numpy.linalg as LA # linalgモジュールはLAとしてimportするのが慣例。

In [3]: a = np.array([[1, 0],[0, 2]]) # まずはわかりやすい対角行列から。

In [4]: a
Out[4]:
array([[1, 0],
       [0, 2]])

In [5]: LA.eig(a)
Out[5]:
(array([ 1.,  2.]), array([[ 1.,  0.],
        [ 0.,  1.]]))

In [6]: b = np.array([[2, 5],[3, -8]]) # 今度はこの行列の固有値、固有ベクトルを求めてみる

In [7]: b
Out[7]:
array([[ 2,  5],
       [ 3, -8]])

In [8]: LA.eig(b)
Out[8]:
(array([ 3.32455532, -9.32455532]), array([[ 0.96665615, -0.40390206],
        [ 0.25607791,  0.91480224]]))

次は3×3の行列でやってみましょう。

In [14]: c = np.random.randint(-10, 10, size=(3,3)) # 3×3の行列で試す。

In [15]: w,v = LA.eig(c) # この場合ではwが固有値、vが固有ベクトルに相当する。

In [17]: w
Out[17]: array([-8.0602555+8.60578754j, -8.0602555-8.60578754j,  9.1205110+0.j        ])

In [18]: v
Out[18]:
array([[-0.03461219-0.64256553j, -0.03461219+0.64256553j, -0.35214563+0.j        ],
       [-0.09795961+0.0259147j , -0.09795961-0.0259147j ,  0.84471803+0.j        ],
       [ 0.75871198+0.j        ,  0.75871198-0.j        ,  0.40304454+0.j        ]])

最後に3次元の配列でやってみます。3×3×3の3次元でやったので、3つの3×3の行列について各々の固有値と固有ベクトルを 求めてくれます。

In [9]: c = np.random.randint(-10, 10, size=(3,3,3)) # 3×3の行列で試す。

In [10]: c
Out[10]:
array([[[ -9,   8,   3],
        [  5,  -7,  -5],
        [ -2,  -5, -10]],

       [[ -4,   1,   3],
        [  4,   4,  -7],
        [  6, -10,   8]],

       [[ -2, -10,   9],
        [-10,  -5,   6],
        [ -1,  -7,   6]]])

In [11]: w,v = LA.eig(c)

In [12]: w
Out[12]:
array([[ -0.2673092 ,  -9.96437556, -15.76831524],
       [ -7.77546211,   0.99173271,  14.78372941],
       [ -9.38894407,   8.64759105,  -0.25864697]])

In [13]: v
Out[13]:
array([[[-0.50024276, -0.75779025, -0.7838022 ],
        [-0.72410553,  0.30721753,  0.5773647 ],
        [ 0.47479297, -0.57564862,  0.22870093]],

       [[-0.60434906,  0.47362558,  0.10874716],
        [ 0.54869006,  0.67807261, -0.5125509 ],
        [ 0.57766897,  0.56204657,  0.8517427 ]],

       [[-0.5518307 , -0.76856194,  0.14126629],
        [-0.74501578,  0.31945109,  0.64855228],
        [-0.37474574, -0.55431359,  0.74794637]]])

*参考
numpy.linalg.eig — NumPy v1.13 Manual
固有値、固有ベクトルの定義と具体的な計算方法 –高校数学の美しい物語–
【数学】固有値・固有ベクトルとは何かを可視化してみる - Qiita