NumPyでベクトルの内積と直積を求める
2023.02.18
NumPy でベクトルの内積や直積を簡単に求められます。NumPy は numpy というライブラリをインポートして import numpy as np のように np という名前で使います。
NumPy の内積
ベクトルの内積は inner または dot で計算します。
import numpy as np
a = np.array([3, 5])
b = np.array([2, 1])
m = np.inner(a, b)
n = np.dot(a, b)
print(m) # 11
print(n) # 11
3 次元のベクトルも同じ。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([5, 3, 1])
m = np.inner(a, b)
n = np.dot(a, b)
print(m) # 14
print(n) # 14
次元の異なるベクトルの内積を計算しようとするとエラーになります。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([5, 3])
m = np.inner(a, b)
# ValueError: shapes (3,) and (2,) not aligned: 3 (dim 0) != 2 (dim 0)
ValueError になりました。
1 次元ベクトルの内積も計算できます。
import numpy as np
a = np.array([2])
b = np.array([3])
m = np.inner(a, b)
print(m) # 6
数学では 1 次元ベクトルの内積は実数の乗算と同じです。実数は 1 次元線形空間だからです。
ドットをそのまま使った積
Python における数値のかけ算と同じように、ベクトルをドットでつないだらどうなるでしょうか?
import numpy as np
a = np.array([1, 2])
b = np.array([3, 4])
m = np.inner(a, b)
n = a * b
print(m) # 11
print(n) # [3 8]
print(type(m)) # <class 'numpy.int64'>
print(type(n)) # <class 'numpy.ndarray'>
a * b
はベクトル [3 8]
になりました。これは各次元の積をそのままベクトルにしたもので、内積ではありません。内積はこのベクトルの各次元の総和です。NumPy の sum はベクトルの各要素の総和を計算します。
import numpy as np
a = np.array([1, 2])
b = np.array([3, 4])
m = a * b
s = np.sum(m)
print(m) # [3 8]
print(s) # 11
単に内積を求めるときは inner 関数を使うべきです。
NumPy の直積
直積は outer を使います。まずは 2 次元のベクトルから。
import numpy as np
a = np.array([1, 2])
b = np.array([5, 3])
m = np.outer(a, b)
print(m)
# [[ 5 3]
# [10 6]]
print(type(m))
# <class 'numpy.ndarray'>
2 次元の正方行列が返りました。型は numpy.ndarray です。3 次元ベクトルの直積も同様です。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([9, 8, 7])
m = np.outer(a, b)
print(m)
# [[ 9 8 7]
# [18 16 14]
# [27 24 21]]
2 次元と 3 次元のベクトルの直積。
import numpy as np
a = np.array([1, 2])
b = np.array([9, 8, 7])
m = np.outer(a, b)
print(m)
# [[ 9 8 7]
# [18 16 14]]
直積は次元がそろっていなくても計算できます。