Python 3 エンジニア認定データ分析試験に向けて勉強している中で、内積(ドット積)の仕組みやエラーになるパターンなどが少しややこしく感じたので、整理のためにまとめてみました。
自分用の学習記録として書いていますが、同じように初学者として勉強されている方の参考になればうれしいです。
🔰 内積(ドット積)とは?
「内積(ドット積)」とは、2つのベクトルの対応する要素を掛けて足し合わせる演算です。
数学的には次のように定義されます。
[2, 3]・[4, 5] = 2×4 + 3×5 = 8 + 15 = 23
Python では np.dot()
を使って計算します。
import numpy as np
a = np.array([2, 3])
b = np.array([4, 5])
result = np.dot(a, b)
print(result) # 23
✅ 基本ルール(形の一致)
NumPy の np.dot()
は、以下のようなルールに従います。
左の配列の shape | 右の配列の shape | 結果の shape | 内容 |
---|---|---|---|
(n,) | (n,) | () | ベクトル同士の内積(スカラー) |
(n,) | (n, m) | (m,) | 行ベクトル × 行列 |
(n, m) | (m,) | (n,) | 行列 × 列ベクトル |
(n, k) | (k, m) | (n, m) | 行列 × 行列 |
🧠 中の次元が一致している必要があるとは?
行列積では、次の形状のときだけ掛け算できます。
A.shape = (a, b)
B.shape = (b, c)
→ np.dot(A, B) は OK
→ 結果は shape (a, c)
つまり、「左の列数 = 右の行数」がドット積の条件です。
例:OKなパターン
A = np.array([[1, 2], [3, 4]]) # shape (2, 2)
B = np.array([[5], [6]]) # shape (2, 1)
print(np.dot(A, B)) # shape (2, 1)
例:NGなパターン(中の次元が合わない)
A = np.array([[1, 2], [3, 4]]) # shape (2, 2)
B = np.array([[5], [6], [7]]) # shape (3, 1)
print(np.dot(A, B)) # ❌ エラー
✅ 1次元配列は自動で行・列ベクトルのように扱われる
NumPyでは、1次元配列(shape が (n,)
)は、状況に応じて次のように扱われます。
パターン | 実質的な扱い |
---|---|
左に来た場合(np.dot(1D, 2D)) |
(1, n) の行ベクトル的に扱われる |
右に来た場合(np.dot(2D, 1D)) |
(n, 1) の列ベクトル的に扱われる |
例:左に来る(行ベクトル扱い)
a = np.array([2, 2]) # shape (2,)
b = np.array([[2], [2]]) # shape (2,1)
print(np.dot(a, b)) # [8]
例:右に来る(列ベクトル扱い)
a = np.array([[2, 2]]) # shape (1, 2)
b = np.array([2, 2]) # shape (2,)
print(np.dot(a, b)) # [8]
✅ @
演算子でも同じように動作する
Python では @
を使って行列積を書くこともできます。
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5], [6]])
print(A @ B) # [[17], [39]]
⚠ 注意:np.dot()
はブロードキャストしない
次のような掛け算(要素ごとの積)は *
を使うもので、np.dot()
ではできません。
A = np.array([[1, 2], [3, 4]]) # shape (2,2)
B = np.array([[10], [20]]) # shape (2,1)
print(A * B) # ✅ ブロードキャストされて計算できる
print(np.dot(A, B)) # ✅ 行列積 → OK(形が合っている)
🎯 まとめ
-
np.dot()
は中の次元(左の列数 = 右の行数)が一致していないとエラーになる - 1次元配列
(n,)
は自動的に(1, n)
または(n, 1)
のように扱われる -
np.dot()
はブロードキャストを行わない(形が合ってないとエラー) -
@
演算子はnp.dot()
とほぼ同じ動作をする(Python 3.5以降)