行列の計算(線形代数)は、NumPyのような配列計算用のライブラリの中でも特に重要な機能の一つだ。

まずは、行列の内積を求めるdot関数を元に、NumPyでおこなう行列計算の基本的な例を見ていこう。

行列の内積を求めるdot関数の使用例

import numpy as np

x = np.array([[1, 2, 3], [4, 5, 6]])
# [[1 2 3]
#  [4 5 6]]

y = np.array([[7, 8], [9, 10], [11, 12]])
# [[ 7  8]
#  [ 9 10]
#  [11 12]]

x.dot(y)
# array([[ 58,  64],
#        [139, 154]])

内積の計算は、今回の例で言うと下記のとおり計算が行われている。

[
    [(1*7)+(2*9)+(3*11), (1*8)+(2*10)+(3*12)],
    [(4*7)+(5*9)+(6*11), (4*8)+(5*10)+(6*12)]
]

また、dot関数は以下のように書くこともでき、先ほどの例と同じ結果を得ることができる。

np.dot(x, y)

次の例は、二次元配列(行列)と、一次元配列の積を求める例だ。
こちらの結果は一次元の配列となる。

import numpy as np

x = np.array([[1, 2, 3], [4, 5, 6]])

y = np.array([1, 2, 3])

np.dot(x, y)
# array([14, 32])

numpy.linalgモジュールを使用した例

numpy.linalgモジュールでは行列の様々な計算を行う関数が多く用意されている。

下記はほんの一例だが、モジュールからinv関数をインポートし、逆行列を計算している。

from numpy.linalg import inv

X = np.random.randn(3, 3)
# [[-1.2952325   0.69556977  0.15416176]
#  [-0.86662175  0.99757584 -0.0237844 ]
#  [ 1.23513841  0.95040347 -1.09385383]]

T = X.T
# [[-1.2952325  -0.86662175  1.23513841]
#  [ 0.69556977  0.99757584  0.95040347]
#  [ 0.15416176 -0.0237844  -1.09385383]]

mat = np.dot(X, T)
# [[ 2.18521039  1.81269361 -1.10734992]
#  [ 1.81269361  1.74675651 -0.09628161]
#  [-1.10734992 -0.09628161  3.62534984]]

inv_arr = inv(mat)
# [[ 42.14336607 -43.08774458  11.72821865]
#  [-43.08774458  44.62661431 -11.97580652]
#  [ 11.72821865 -11.97580652   3.54012513]]

なお、変数Tに代入しているX.Tは、以前の記事で紹介した行列を転置する方法だ。

まとめ

行列の計算、線形代数は、機械学習でも使用される、Pythonでも重要な計算の一つなので、プログラミングでの扱いだけでなく、高校数学もしっかり学ぶ必要がある。