配列 ベクトル 行列 統計

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]]

直積は次元がそろっていなくても計算できます。