こんにちは!インストラクターのフクロウです!
この記事では、行列の対角要素を取り出したり、対角行列を作ったりできるnp.diag関数を紹介しますよ!
- 対角要素って何?
- 対角行列って何?
- np.diag関数ってどうやって使うの?
って思った方は必見です!この記事を読めば
- 対角要素とは
- 対角行列とは
- np.diagの使い方
- 機械学習ではどう使われるのか
などがわかりますよ!
使い方は簡単!この機会に覚えちゃいましょう!
対角要素を取り出す方法
そもそも対角要素って何?
行列の対角要素って何?って思った方!
例えば1~16の要素が入った4×4行列aを想像してください。
このaの主対角要素は、下の図の緑色の要素のことです!
np.diagで対角要素を得る
そしてこれをNumPyの関数で計算するには、以下のように「np.diag」を使います!
※これ以降、IPythonを使ってプログラムを実行していきますよ!
Python 3.7.0 (default, Jun 28 2018, 13:15:42) Type 'copyright', 'credits' or 'license' for more information IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: import numpy as np In [2]: a = np.arange(1,17).reshape((4,4)) In [3]: a Out[3]: array([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15, 16]]) In [4]: np.diag(a) Out[4]: array([ 1, 6, 11, 16]) In [5]: np.diag(a, k=0) # = np.diag(a) Out[5]: array([ 1, 6, 11, 16])
ここで、k=0というパラメータがありますね。
これは主対角要素を指定しています。
kパラメータを操作するとどうなる?
np.diag関数のkの値を変えると、正の値ならば右上、負の値ならば左下の対角要素を取り出します。
In [6]: np.diag(a, k=1) Out[6]: array([ 2, 7, 12]) In [7]: np.diag(a, k=2) Out[7]: array([3, 8]) In [8]: np.diag(a, k=3) Out[8]: array([4]) In [9]: np.diag(a, k=-1) Out[9]: array([ 5, 10, 15]) In [10]: np.diag(a, k=-2) Out[10]: array([ 9, 14]) In [11]: np.diag(a, k=-3) Out[11]: array([13])
ちなみにこの関数は、メソッドとしても提供されています。
In [12]: a.diagonal() Out[12]: array([ 1, 6, 11, 16])
対角行列を作る方法
対角行列って何?
対角行列とは、対角要素以外は0で埋められた行列です。
これにまつわるもっと深い話が知りたい場合は、以下の解説記事が読みやすいですよ。
np.diagを使った対角行列の作り方
np.diagにベクトルを渡すと対角行列を作ってくれます。
試してみましょう!
In [13]: b = np.array([1,2,3,4]) In [14]: np.diag(b) Out[14]: array([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]])
[1,2,3,4]というベクトルの要素数に合わせた対角行列ができていますね!
kパラメータを操作するとどうなる?
対角行列を作るときも、kパラメータを操作することで、与えたベクトルがどこの対角要素なのかを指定できますよ!
In [15]: np.diag(b, k=0) Out[15]: array([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]]) In [16]: np.diag(b, k=1) Out[16]: array([[0, 1, 0, 0, 0], [0, 0, 2, 0, 0], [0, 0, 0, 3, 0], [0, 0, 0, 0, 4], [0, 0, 0, 0, 0]]) In [17]: np.diag(b, k=2) Out[17]: array([[0, 0, 1, 0, 0, 0], [0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 4], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]) In [18]: np.diag(b, k=3) Out[18]: array([[0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 4], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]) In [19]: np.diag(b, k=-1) Out[19]: array([[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 0, 3, 0, 0], [0, 0, 0, 4, 0]]) In [20]: np.diag(b, k=-2) Out[20]: array([[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0], [0, 2, 0, 0, 0, 0], [0, 0, 3, 0, 0, 0], [0, 0, 0, 4, 0, 0]]) In [21]: np.diag(b, k=-3) Out[21]: array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0], [0, 2, 0, 0, 0, 0, 0], [0, 0, 3, 0, 0, 0, 0], [0, 0, 0, 4, 0, 0, 0]])
機械学習ではどこで使うの?
対角行列や対角要素という言葉は線形代数の言葉です。
scikit-learnなどでPCA(主成分分析)をやったことがある人なら、対角化という言葉を聞いたことがあるかもしれません。
PCAなどの次元圧縮手法で近い操作が頻出するので、np.diagに限らず行列を操作する関数は覚えておくと機械学習の理論を学ぶときに役立ちますよ!
まとめ
この記事では、行列の対角要素を取り出したり、対角行列を作ったりできる関数「np.diag」を紹介しました。
線形代数的な操作は機械学習を学ぶ上で避けては通れない基本技術です。
このような基本的な操作から学んでいって、ただ機械学習ライブラリを使うだけじゃないしっかりとした理解ができるようになりましょうね!