#1.概要
本記事は、日本ディープラーニング協会認定講座プログラム『ラビットチャレンジ』での学習の一つである応用数学・線形代数の部分についてレポートを作成する。
具体的には行列を理解し、特異値分解までをできるようにする。また、Pythonで表現できるようになることが目標である。
#2.目次
3.スカラーとベクトルとは?
4.行列とは?
5.行列の演算
6.単位行列
7.逆行列
8.転置行列
9.行列式
10.固有値と固有ベクトル
11.固有値分解
12.特異値分解
13.演習問題
14.各種リンク
#3.スカラーとベクトルとは?
スカラーとベクトルには以下の違いがある。
スカラー・・・大きさのみで表現され、向きを持たない
ベクトル・・・大きさと向きで表現される
####3-1.数式での表現
表現例
スカラー:
a=1
ベクトル:
\vec{a}=\left(
\begin{array}{c}
a_{ 1 } \\
a_{ 2 } \\
\end{array}
\right)
=\left(
\begin{array}{c}
2 \\
3 \\
\end{array}
\right)
####3-2.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入
a=1
b = np.array([2,3])
#スカラーの表現
print("a={}".format(a))
#ベクトルの表現
print("b={}".format(b))
出力結果
a=1
b=[2 3]
#4.行列とは?
行列とは、スカラーを表で表現したものやベクトルを集合させて表現したものである。
横方向を行、縦方向を列と言いい、行がm行、列がn列であるものをm×n行列と呼ぶ。
また、そのうち行が$i$番目$(1≤i≤m)$、列が$j$番目$(1≤j≤n)$のものを(i,j)成分と呼ぶ。
####4-1.数式での表現
表現例
行列:
A=\left(
\begin{array}{c}
a_{ 11 } &a_{ 12 }&a_{ 13 }\\
a_{ 21 } &a_{ 22 }&a_{ 23 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
1&3&2 \\
2&4&1 \\
\end{array}
\right)
####4-2.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
A= np.array([
[1,3,2],
[2,4,1]
])
#行列の表現
print("A=")
print(A)
出力結果
A=
[[1 3 2]
[2 4 1]]
#5.行列の演算
スカラーと同様に行列にも演算が存在するが、スカラーと違い演算する際の制約が多い。
和(A+B)・・・$m×n$行列$A$,$B$の$(i,j)$成分同士を足し算する。
差(A-B)・・・$m×n$行列$A$,$B$について、$A$の$(i,j)$成分から$B$の$(i,j)$成分を引く。
スカラー倍(aA)・・・行列$A$について、各成分を$a$倍する。
積(AB)・・・$l×m$行列$A$,$m×n$行列$B$について、行列$C=AB$は$l×n$行列となり行列$C$の各成分$c_{ij}$は、$\sum_{ k = 1 }^{ m }(a_{im}・b_{mj})$となる。
アダマール積(A⊙B)・・・$m×n$行列$A$,$B$の$(i,j)$成分同士を掛け算する。
####5-1.数式での表現
表現例
\begin{align}
行列:&
A=\left(
\begin{array}{c}
a_{ 11 } &a_{ 12 }\\
a_{ 21 } &a_{ 22 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
1&3 \\
2&4 \\
\end{array}
\right)
,
行列:
B=\left(
\begin{array}{c}
b_{ 11 } &b_{ 12 }\\
b_{ 21 } &b_{ 22 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
-1&1 \\
-2&0 \\
\end{array}
\right),
a=2
とする。\\
&和:
A+B=\left(
\begin{array}{c}
a_{ 11 }+b_{ 11 } &a_{ 12 }+b_{ 12 }\\
a_{ 21 }+b_{ 21 } &a_{ 22 }+b_{ 22 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
1+(-1)&3+1 \\
2+(-2)&4+0 \\
\end{array}
\right)
=\left(
\begin{array}{c}
0&4 \\
0&4 \\
\end{array}
\right)\\
&差:
A-B=\left(
\begin{array}{c}
a_{ 11 }-b_{ 11 } &a_{ 12 }-b_{ 12 }\\
a_{ 21 }-b_{ 21 } &a_{ 22 }-b_{ 22 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
1-(-1)&3-1 \\
2-(-2)&4-0 \\
\end{array}
\right)
=\left(
\begin{array}{c}
2&2 \\
4&4 \\
\end{array}
\right)\\
&スカラー倍:
aA=\left(
\begin{array}{c}
a・a_{ 11 } &a・a_{ 12 }\\
a・a_{ 21 } &a・a_{ 22 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
2・1&2・3 \\
2・2&2・4 \\
\end{array}
\right)
=\left(
\begin{array}{c}
2&6 \\
4&8 \\
\end{array}
\right)\\
&積:
AB=\left(
\begin{array}{c}
a_{ 11 }b_{ 11 } +a_{ 12 }b_{ 21 }&a_{ 11 }b_{ 12 } +a_{ 12 }b_{ 22 }\\
a_{ 21 }b_{ 11 } +a_{ 22 }b_{ 21 } &a_{ 21 }b_{ 12 } +a_{ 22 }b_{ 22 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
1・(-1)+3・(-2)&1・1+3・0 \\
2・(-1)+4・(-2)&2・1+4・0 \\
\end{array}
\right)
=\left(
\begin{array}{c}
-7&1 \\
-10&2 \\
\end{array}
\right)\\
&アダマール積:
A⊙B=\left(
\begin{array}{c}
a_{ 11 }・b_{ 11 } &a_{ 12 }・b_{ 12 }\\
a_{ 21 }・b_{ 21 } &a_{ 22 }・b_{ 22 }\\
\end{array}
\right)
=\left(
\begin{array}{c}
1・(-1)&3・1 \\
2・(-2)&4・0 \\
\end{array}
\right)
=\left(
\begin{array}{c}
-1&3 \\
-4&0 \\
\end{array}
\right)\\
\end{align}
####5-2.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
A= np.array([
[1,3],
[2,4]
])
B= np.array([
[-1,1],
[-2,0]
])
a=2
#行列の演算表現
#和
print("A+B=")
print(A+B)
#差
print("A-B=")
print(A-B)
#スカラー倍
print("aA=")
print(a*A)
#積
print("AB=")
print(A.dot(B))
#アダマール積
print("A⊙B=")
print(A*B)
出力結果
A+B=
[[0 4]
[0 4]]
A-B=
[[2 2]
[4 4]]
aA=
[[2 6]
[4 8]]
AB=
[[ -7 1]
[-10 2]]
A⊙B=
[[-1 3]
[-4 0]]
#6.単位行列
$n×n$行列(一般に$n$次正方行列とも呼ぶ)について、$(1,1)$成分から$(i,j)$成分にかけての対角線上を$1$、それ以外を$0$とする行列を$n$次の単位行列と呼ぶ。
####6-1.数式での表現
表現例
単位行列:
I=\left(
\begin{array}{c}
a_{ 11 } &a_{ 12 }&\cdots&a_{ 1n }\\
a_{ 21 } &a_{ 12 }&&\vdots\\
\vdots &&\ddots&a_{ n-1n }\\
a_{ n1 } &\cdots&a_{ nn-1 }&a_{ nn }\\
\end{array}
\right)
=\left(
\begin{array}{c}
1 &0&\cdots&0\\
0&1&&\vdots\\
\vdots &&\ddots&0\\
0 &\cdots&0&1\\
\end{array}
\right)
####6-2.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 identity(n)でn次の単位行列が設定される。 ※float型で作成される。
I= np.identity(2)
#単位行列の表現
print("I=")
print(I)
出力結果
I=
[[1. 0.]
[0. 1.]]
#7.逆行列
ある行列$A$について、$AB=BA=I$を満たす行列$B$のことを逆行列とよび、$A^{ -1}$と表現する。
(この$-1$はインバースと呼ぶ。)
####7-1.掃き出し法
逆行列の算出方法はいくつかあるが、今回は掃き出し法を紹介する。
掃き出し法による逆行列の算出では以下の操作が可能である。
1.ある行について0でない実数倍をする。
2.ある行について、他の行の実数倍を加える。
3.ある行とある行を入れ替える。
以下の行列$A$について、逆行列$A^{ -1}$を算出する。(今回は$2×2$行列で算出)
行列:
A=\left(
\begin{array}{c}
a &b\\
c &d\\
\end{array}
\right)
もとの行列を左に、単位行列を右に設定した拡大行列を用意する。
拡大行列:
(A|I)=\left(
\begin{array}{cc|cc}
a &b&1&0\\
c &d&0&1\\
\end{array}
\right)
1行目を$1/a$倍する。
($a$が$0$の場合は、1行目と2行目を入れ替える。また、後続でも述べるが$a$,$c$がともに$0$の場合、逆行列は存在しないことにも注意)
\left(
\begin{array}{cc|cc}
1 &\frac{b}{a}&\frac{1}{a}&0\\
c &d&0&1\\
\end{array}
\right)
2行目に1行目の$-c$倍を加える。
\left(
\begin{array}{cc|cc}
1 &\frac{b}{a}&\frac{1}{a}&0\\
0 &d-\frac{bc}{a}&-\frac{c}{a}&1\\
\end{array}
\right)
2行目を$\frac{1}{d-\frac{bc}{a}}=\frac{a}{ad-bc}$倍する。
($ad-bc$が$0$の場合、逆行列は存在しないことに注意)
\left(
\begin{array}{cc|cc}
1 &\frac{b}{a}&\frac{1}{a}&0\\
0 &1&-\frac{c}{ad-bc}&\frac{a}{ad-bc}\\
\end{array}
\right)
1行目に2行目の$-\frac{b}{a}$倍を加える。
\left(
\begin{array}{cc|cc}
1 &0&\frac{d}{ad-bc}&-\frac{b}{ad-bc}\\
0 &1&-\frac{c}{ad-bc}&\frac{a}{ad-bc}\\
\end{array}
\right)=(I|A^{-1})
上記から$2×2$行列の逆行列$A^{-1}$は以下のように表現できる。
(これは$a$=0で、掃き出し法ではじめに1行目と2行目を入れ替えても同じ結果となる。)
A^{-1}=
\frac{1}{ad-bc}
\left(
\begin{array}{cc|cc}
d&-b\\
-c&a\\
\end{array}
\right)
####7-2.数式での表現
表現例
行列:
A=\left(
\begin{array}{c}
1&3 \\
2&4 \\
\end{array}
\right)\\
逆行列:A^{-1}=
\frac{1}{1・4-3・2}
\left(
\begin{array}{c}
4 &-3\\
-2 &1\\
\end{array}
\right)
=\left(
\begin{array}{c}
-2&\frac{3}{2} \\
1&-\frac{1}{2} \\
\end{array}
\right)\\
AA^{-1}=A^{-1}A=
\left(
\begin{array}{c}
1&0 \\
0&1 \\
\end{array}
\right)
=Iを満たしている。
####7-3.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
#行列Aの宣言
A= np.array([
[1,3],
[2,4]
])
#逆行列A^(-1)の宣言 np.linalg.inv(行列)で算出可能 逆行列が存在しない場合エラーとなる。
invA = np.linalg.inv(A)
#行列の表現
print("A=")
print(A)
#逆行列の表現
print("A^(-1)=")
print(invA)
#行列と逆行列の積
print("AA^(-1)=")
print(A.dot(invA))
出力結果
A=
[[1 3]
[2 4]]
A^(-1)=
[[-2. 1.5]
[ 1. -0.5]]
AA^(-1)=
[[1. 0.]
[0. 1.]]
#8.転置行列
転置行列とは、行列の行と列を入れ替えた行列のことである。
####8-1.数式での表現
表現例
行列:
A=\left(
\begin{array}{c}
a_{ 11 } &a_{ 12 }&\cdots&a_{ 1n }\\
a_{ 21 } &a_{ 12 }&&\vdots\\
\vdots &&\ddots&a_{ m-1n }\\
a_{ m1 } &\cdots&a_{ mn-1 }&a_{ mn }\\
\end{array}
\right)\\
転置行列:A^{T}=\left(
\begin{array}{c}
a_{ 11 } &a_{ 21 }&\cdots&a_{ m1 }\\
a_{ 12 }&a_{ 12 }&&\vdots\\
\vdots &&\ddots&a_{ mn-1 }\\
a_{ 1n } &\cdots&a_{ m-1n }&a_{ mn }\\
\end{array}
\right)\\
####8-2.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
#行列Aの宣言
A= np.array([
[1,3],
[2,4]
])
#行列の表現
print("A=")
print(A)
#転置行列の表現
print("A^(T)=")
print(A.T)
出力結果
A=
[[1 3]
[2 4]]
A^(T)=
[[1 2]
[3 4]]
#9.行列式
行列式とは、ある行列が逆行列の有無を判別する指標となる。
2次の正方行列の行列式は以下で求められる。
\begin{vmatrix}
a &b\\
c &d\\
\end{vmatrix}
=ad-bc
####9-1.行列式の特徴
\begin{align}
&\vec{a}_{ i} =\left(
\begin{array}{c}
a_{ i1} &a_{ i2}&\cdots&a_{ in} \\
\end{array}
\right)、
\vec{w}=\left(
\begin{array}{c}
w_{ 1} &w_{ 2}&\cdots&a_{ n} \\
\end{array}
\right)、λはある定数とするとき以下の特徴がある。\\
\\
&1.同じ行ベクトルが含まれていると行列式は0となる。\\
&
\begin{vmatrix}
\vec{a}_{ 1} \\
\vdots \\
\vec{w}\\
\vdots \\
\vec{w} \\
\vdots \\
\vec{a}_{ n}
\end{vmatrix}
=0\\
\\
&2.ある行ベクトルがある定数λ倍となったとき、行列式は元の行列式のλ倍となる。\\
&
\begin{vmatrix}
\vec{a}_{ 1} \\
\vdots \\
λ\vec{a}_{ i} \\
\vdots \\
\vec{a}_{ n}
\end{vmatrix}
=λ\begin{vmatrix}
\vec{a}_{ 1} \\
\vdots \\
\vec{a}_{ i} \\
\vdots \\
\vec{a}_{ n}
\end{vmatrix}\\
&3.ある行ベクトルを二つの行ベクトルの足し合わせに分解したとき、他の行ベクトルの成分はそのままで行列式を分解することが可能である。\\
&
\begin{vmatrix}
\vec{a}_{ 1} \\
\vdots \\
\vec{a}_{ i} + \vec{w} \\
\vdots \\
\vec{a}_{ n}
\end{vmatrix}
=\begin{vmatrix}
\vec{a}_{ 1} \\
\vdots \\
\vec{a}_{ i} \\
\vdots \\
\vec{a}_{ n}
\end{vmatrix}
+
\begin{vmatrix}
\vec{a}_{ 1} \\
\vdots \\
\vec{w} \\
\vdots \\
\vec{a}_{ n}
\end{vmatrix}\\
&4.もとの行列と転置した行列式は一致する。\\
&
\begin{vmatrix}
\vec{a}_{ 1} \\
\vdots \\
\vec{a}_{ i} \\
\vdots \\
\vec{a}_{ n}
\end{vmatrix}
=
\begin{vmatrix}
\vec{a}_{ 1}^{T} &\cdots&\vec{a}_{ i}^{T}&\cdots&\vec{a}_{ n}^{T} \\
\end{vmatrix}\\
\\
\\
\end{align}
####9-2.余因子展開
行列$A$に対し、$i$行$j$列を除いた行列を$A_{ij}$とすると、$(i,j)$余因子は$(-1)^{ij}・\begin{vmatrix}A_{ij}\end{vmatrix}$と表現できる。
余因子展開は、行列$A$のある行(または列)に対し、その成分と余因子を全て足し合わせて表現したものである。
余因子展開を利用することで、3次以上の正方行列の行列式に対しても2次の正方行列の行列式の足し合わせで表現することができ、比較的容易に行列式を算出することができる。
$j$列目について余因子展開した場合
\begin{align}
行列式:
\begin{vmatrix}A\end{vmatrix}&=
\begin{vmatrix}
a_{ 11 } &a_{ 12 }&\cdots&a_{ 1n }\\
a_{ 21 } &a_{ 12 }&&\vdots\\
\vdots &&\ddots&a_{ n-1n }\\
a_{ n1 } &\cdots&a_{ nn-1 }&a_{ nn }\\
\end{vmatrix}
\\
&=\sum_{i=1}^{n}(-1)^{i+j}・a_{ij}・
\begin{vmatrix}
A_{ ij }
\end{vmatrix}
\\
\end{align}
####9-3.数式での表現
表現例
\begin{align}
行列式:
\begin{vmatrix}A\end{vmatrix}
&=\begin{vmatrix}
1&3&2 \\
0&1&1 \\
1&4&1 \\
\end{vmatrix}\\
&=1・\begin{vmatrix}
1&1 \\
4&1 \\
\end{vmatrix}-
0・\begin{vmatrix}
3&2 \\
4&1 \\
\end{vmatrix}+
1・\begin{vmatrix}
3&2 \\
1&1 \\
\end{vmatrix}\\
&=1・(1・1-1・4)+
1・(3・1-2・1)\\
&=-2\\
\end{align}
####9-4.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
#行列Aの宣言
A= np.array([
[1,3,2],
[0,1,1],
[1,4,1]
])
#行列の表現
print("A=")
print(A)
#行列式の表現 np.linalg.det(行列)で算出可能
print("|A|={}".format(np.linalg.det(A)))
出力結果
A=
[[1 3 2]
[0 1 1]
[1 4 1]]
|A|=-2.0
#10.固有値と固有ベクトル
ある行列$A$に対し、スカラー$λ$と0ベクトルでないベクトル$\vec{x}$を用いて$A\vec{x}=λ\vec{x}$と表現できるとき、$λ$を固有値、$\vec{x}$を固有ベクトルと呼ぶ。
####10-1.数式での表現
表現例
\begin{align}
&A=\left(
\begin{array}{c}
1&3 \\
4&2 \\
\end{array}
\right)
の固有値と固有ベクトルを求める。\\
& A\vec{x}=λ\vec{x}\\
& (A-λI)\vec{x}=\vec{0}\\
& \\
&\vec{x}は0ベクトルでないことから\\
& \\
& \begin{vmatrix}A-λI\end{vmatrix}=
\begin{vmatrix}
1-λ&3\\
4&2-λ\\
\end{vmatrix}=0\\
& (1-λ)(2-λ)-3・4=0\\
& λ^{2}-3λ-10=0\\
& (λ-5)(λ+2)=0\\
& λ=-2,5\\
& \\
&λ=-2のとき\vec{x}=\left(
\begin{array}{c}
x_{ 1 } \\
x_{ 2 } \\
\end{array}
\right)は\\
& \left(
\begin{array}{c}
1&3 \\
4&2 \\
\end{array}
\right)
\left(
\begin{array}{c}
x_{ 1 } \\
x_{ 2 } \\
\end{array}
\right)=-2・
\left(
\begin{array}{c}
x_{ 1 } \\
x_{ 2 } \\
\end{array}
\right)\\
& \left(
\begin{array}{c}
3x_{ 1 }+3x_{ 2 } \\
4x_{ 1 }+4x_{ 2 } \\
\end{array}
\right)=
\left(
\begin{array}{c}
0 \\
0 \\
\end{array}
\right)\\
&上記より、x_{ 1 }=-p、x_{ 2 }=p(pは0以外の任意の実数)\\
&今回はベクトルの大きさ(\sqrt {x_{ 1 }^{2}+x_{ 2 }^{2}})が1となるように\\
&(大きさが1のベクトルを単位ベクトルと言う)\\
& \vec{x}=
\left(
\begin{array}{c}
-\frac{1}{\sqrt {2}} \\
\frac{1}{\sqrt {2}} \\
\end{array}
\right)\\
& \\
&λ=5のとき\vec{x}=\left(
\begin{array}{c}
x_{ 1 } \\
x_{ 2 } \\
\end{array}
\right)は\\
& \left(
\begin{array}{c}
1&3 \\
4&2 \\
\end{array}
\right)
\left(
\begin{array}{c}
x_{ 1 } \\
x_{ 2 } \\
\end{array}
\right)=5・
\left(
\begin{array}{c}
x_{ 1 } \\
x_{ 2 } \\
\end{array}
\right)\\
& \left(
\begin{array}{c}
-4x_{ 1 }+3x_{ 2 } \\
4x_{ 1 }-3x_{ 2 } \\
\end{array}
\right)=
\left(
\begin{array}{c}
0 \\
0 \\
\end{array}
\right)\\
&上記より、x_{ 1 }=3p、x_{ 2 }=4p(pは0以外の任意の実数)\\
&単位ベクトルとなるように\\
& \vec{x}=
\left(
\begin{array}{c}
\frac{3}{5} \\
\frac{4}{5} \\
\end{array}
\right)\\
\end{align}
####10-2.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
#行列Aの宣言
A= np.array([
[1,3],
[4,2]
])
#固有値・固有ベクトルの宣言 np.linalg.eig(行列)で[固有値,固有ベクトル]が返ってくる
eig_num , eig_vec= np.linalg.eig(A)
#行列の表現
print("A=")
print(A)
print()
#固有値の表現
print("[λ_1,λ_2]={}".format(eig_num))
print()
#固有ベクトルの表現 各λに対応するベクトルは列ベクトルで生成される。
print("[x_1,x_2]=")
print(eig_vec)
出力結果
A=
[[1 3]
[4 2]]
[λ_1,λ_2]=[-2. 5.]
[x_1,x_2]=
[[-0.70710678 -0.6 ]
[ 0.70710678 -0.8 ]]
※数式での表現とPythonでの表現で固有ベクトルの値が異なるが任意定数$p$の設定の違いである。
#11.固有値分解
ある行列$A$に対し、固有値を対角行列($(1,1)$成分から$(n,n)$成分までの対角成分以外の成分が$0$)で並べた$𝛬$とそれに対応する固有ベクトルを並べた行列$V$を使用し,$A=V𝛬V^{-1}$と表現すること固有値分解と言う。
####11-1.数式での表現
表現例
\left(
\begin{array}{c}
1&3 \\
4&2 \\
\end{array}
\right)=
V𝛬V^{-1}=
\left(
\begin{array}{c}
-\frac{1}{\sqrt {2}}&\frac{3}{5} \\
\frac{1}{\sqrt {2}}&\frac{4}{5} \\
\end{array}
\right)
\left(
\begin{array}{c}
-2&0 \\
0&5 \\
\end{array}
\right)
\left(
\begin{array}{c}
-\frac{4\sqrt {2}}{7}&\frac{3\sqrt {2}}{7} \\
\frac{5}{7}&\frac{5}{7} \\
\end{array}
\right)
####11-2.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
#行列Aの宣言
A= np.array([
[1,3],
[4,2]
])
#固有値・固有ベクトルの宣言 np.linalg.eig(行列)で[固有値,固有ベクトル]が返ってくる
eig_num , eig_vec= np.linalg.eig(A)
#固有ベクトルの逆行列の宣言
invV = np.linalg.inv(eig_vec)
#行列の表現
print("A=")
print(A)
print()
#固有値の対角行列の表現 np.diag(配列)で対角行列化できる。
print("𝛬=")
print(np.diag(eig_num))
print()
#固有ベクトルの表現 各λに対応するベクトルは列ベクトルで生成される。
print("V=")
print(eig_vec)
print()
#固有ベクトルの逆行列
print("V^(-1)=")
print(invV)
print()
#固有値分解と元の行列の関係の確認
print("V𝛬V^(-1)=")
print(eig_vec.dot(np.diag(eig_num).dot(invV)))
出力結果
A=
[[1 3]
[4 2]]
𝛬=
[[-2. 0.]
[ 0. 5.]]
V=
[[-0.70710678 -0.6 ]
[ 0.70710678 -0.8 ]]
V^(-1)=
[[-0.80812204 0.60609153]
[-0.71428571 -0.71428571]]
V𝛬V^(-1)=
[[1. 3.]
[4. 2.]]
※数式での表現とPythonでの表現で固有ベクトルの値が異なるが任意定数$p$の設定の違いである。
#12.特異値分解
固有値分解は正方行列に対し使用できるが、正方行列でない行列に対しては似たようなことがあり特異値分解と呼ばれるものがある。機械学習でしばし用いられる。
10.固有値と固有ベクトルのように以下を満たす$0$以上となるスカラー$σ$とベクトル$\vec{u}$、$\vec{v}$を考える。
このとき、$σ$を特異値、$\vec{u}$、$\vec{v}$をそれぞれ左特異ベクトル、右特異ベクトルと言う。
M\vec{v}=σ\vec{u}\\
M^{T}\vec{u}=σ\vec{v}
このような特殊な単位ベクトルがあるならば特異値分解が可能であり以下のように表現できる。
($m×n$行列$M$の特異値分解に使用する行列$U$、$S$、$V$には様々な表記方法があるが、今回は$U$を$m×m$行列、$S$を$m×n$行列(対角行列のように$(i,j)$成分は$i≠j$のとき$0$)、$V$を$n×n$行列で話を進める。)
M=USV^{-1}
####12-1.特異値の求め方
11.固有値分解のように$M$、$M^{T}$は以下のように表現できる。
M=USV^{-1} M^{T}=VS^{T}U^{-1}
$MM^{T}$と$M^{T}M$のような行列の積を考える。
MM^{T}=USV^{-1}VS^{T}U^{-1}=USS^{T}U^{-1}\\
M^{T}M=VS^{T}U^{-1}USV^{-1}=VS^{T}SV^{-1}
$MM^{T}$は$m×m$行列、$M^{T}M$は$n×n$行列で正方行列となっており、
$SS^{T}$は$m×m$行列、$S^{T}S$は$n×n$行列で特異値の$2$乗が並んだ対角行列となっていることから、
$MM^{T}$と$M^{T}M$を固有値分解することで$U$、$S$、$V$を求めることができる。
($U$、$V$は単位ベクトルからなること、固有値の対角行列は特異値が$2$乗となっていることに注意)
####12-2.数式での表現
表現例
$以下の行列を特異値分解する。$
長方行列M=
\left(
\begin{array}{c}
1&1&2 \\
-1&2&-1 \\
\end{array}
\right)
$MM^{T}について考える。$
MM^{T}=
\left(
\begin{array}{c}
1&1&2 \\
-1&2&-1 \\
\end{array}
\right)
\left(
\begin{array}{c}
1&-1 \\
1&2 \\
2&-1 \\
\end{array}
\right)=
\left(
\begin{array}{c}
6&-1 \\
-1&6 \\
\end{array}
\right)
$上記を固有値分解すると、(実際の計算は省略)$
MM^{T}=
\left(
\begin{array}{c}
6&-1 \\
-1&6 \\
\end{array}
\right)=
\left(
\begin{array}{c}
\frac{1}{\sqrt {2}}&\frac{1}{\sqrt {2}} \\
\frac{1}{\sqrt {2}}&-\frac{1}{\sqrt {2}} \\
\end{array}
\right)
\left(
\begin{array}{c}
5&0 \\
0&7 \\
\end{array}
\right)
\left(
\begin{array}{c}
\frac{1}{\sqrt {2}}&\frac{1}{\sqrt {2}} \\
\frac{1}{\sqrt {2}}&-\frac{1}{\sqrt {2}} \\
\end{array}
\right)=USS^{T}U^{-1}
$次に、M^{T}Mについて考える。$
M^{T}M=
\left(
\begin{array}{c}
1&-1 \\
1&2 \\
2&-1 \\
\end{array}
\right)
\left(
\begin{array}{c}
1&1&2 \\
-1&2&-1 \\
\end{array}
\right)
=
\left(
\begin{array}{c}
2&-1&3 \\
-1&5&0 \\
3&0&5 \\
\end{array}
\right)
$上記を固有値分解すると、(実際の計算は省略)$
M^{T}M=
\left(
\begin{array}{c}
2&-1&3 \\
-1&5&0 \\
3&0&5 \\
\end{array}
\right)=
\left(
\begin{array}{c}
0&\frac{2}{\sqrt {14}}&\frac{5}{\sqrt {35}} \\
\frac{3}{\sqrt {10}}&-\frac{1}{\sqrt {14}}&\frac{1}{\sqrt {35}} \\
\frac{1}{\sqrt {10}}&-\frac{3}{\sqrt {14}}&-\frac{3}{\sqrt {35}} \\
\end{array}
\right)
\left(
\begin{array}{c}
5&0&0 \\
0&7&0 \\
0&0&0 \\
\end{array}
\right)
\left(
\begin{array}{c}
0&\frac{3}{\sqrt {10}}&\frac{1}{\sqrt {10}} \\
\frac{2}{\sqrt {14}}&-\frac{1}{\sqrt {14}}&\frac{3}{\sqrt {14}} \\
\frac{5}{\sqrt {35}}&-\frac{1}{\sqrt {35}}&-\frac{3}{\sqrt {35}} \\
\end{array}
\right)=VS^{T}SV^{-1}
$MM^{T},M^{T}Mの固有値分解より、Mの特異値分解は以下のように表現できる。$
M=
\left(
\begin{array}{c}
1&1&2 \\
-1&2&-1 \\
\end{array}
\right)=
\left(
\begin{array}{c}
\frac{1}{\sqrt {2}}&\frac{1}{\sqrt {2}} \\
\frac{1}{\sqrt {2}}&-\frac{1}{\sqrt {2}} \\
\end{array}
\right)
\left(
\begin{array}{c}
\sqrt {5}&0&0 \\
0&\sqrt {7}&0 \\
\end{array}
\right)
\left(
\begin{array}{c}
0&\frac{3}{\sqrt {10}}&\frac{1}{\sqrt {10}} \\
\frac{2}{\sqrt {14}}&-\frac{1}{\sqrt {14}}&\frac{3}{\sqrt {14}} \\
\frac{5}{\sqrt {35}}&-\frac{1}{\sqrt {35}}&-\frac{3}{\sqrt {35}} \\
\end{array}
\right)
####12-3.Pythonでの表現
プログラム例
#numpyのインポート(行列などを扱うときに使用するライブラリ)
import numpy as np
#scipy.linalgのインポート(行列Sを作成するために必要)
#※実はこちらを使うと一般的な固有値問題を解くことができる。
import scipy.linalg
#変数に値を代入 ※行列を表現するとき、","、"["や"]"の入力漏れに注意!!
#行列Mの宣言
M= np.array([
[1,1,2],
[-1,2,-1]
])
#固有値・固有ベクトルの宣言 np.linalg.sdv(行列)で[左特異ベクトル,特異値,右特異ベクトルの逆行列]が返ってくる
sin_vec_l,sin_num,sin_vec_r = scipy.linalg.svd(M)
#行列の表現
print("M=")
print(M)
print()
#特異値の表現 scipy.linalg.diagsvd(配列,行,列)で特異値を対角に並べられる。
print("S=")
print(scipy.linalg.diagsvd(sin_num,M.shape[0],M.shape[1]))
print()
#左特異ベクトルの表現
print("U=")
print(sin_vec_l)
print()
#右特異ベクトルの逆行列の表現
print("V^(-1)=")
print(sin_vec_r)
print()
#特異値分解と元の行列の関係の確認
print("USV^(-1)=")
print(sin_vec_l.dot(scipy.linalg.diagsvd(sin_num,M.shape[0],M.shape[1]).dot(sin_vec_r)))
出力結果
M=
[[ 1 1 2]
[-1 2 -1]]
S=
[[2.64575131 0. 0. ]
[0. 2.23606798 0. ]]
U=
[[-0.70710678 0.70710678]
[ 0.70710678 0.70710678]]
V^(-1)=
[[-5.34522484e-01 2.67261242e-01 -8.01783726e-01]
[ 1.46210030e-16 9.48683298e-01 3.16227766e-01]
[-8.45154255e-01 -1.69030851e-01 5.07092553e-01]]
USV^(-1)=
[[ 1. 1. 2.]
[-1. 2. -1.]]
※数式での表現とPythonでの表現で特異ベクトルの値が異なるが任意定数$p$の設定の違いである。
※数式での表現とPythonでの表現で特異値の順番は異なるが問題なし。
#13.演習問題
***近々更新予定***
#14.各種リンク
・E資格取得に向けた学習まとめ
https://qiita.com/gen1127/items/413ee03a6fa1a3b4a5ed
・ラビットチャレンジ
https://ai999.careers/rabbit/
・3カ月で現場で潰しが効くディープラーニング講座
http://study-ai.com/jdla/