nanoseeingの技術系ブログ

機械学習・競プロなど。アウトプットが目的。

行列の積の種類(行列の積・アダマール積・フロベニウス積)とnumpyでの書き方

単なる行列の積のことを「内積」とか書いてる記事をみつけて混乱したので、まとめてみた。

行列の積

単に、行列の「積」というと、下記のこと。

 \boldsymbol{A} : n * m 行列,  \boldsymbol{B} : m * p 行列
 \boldsymbol{(AB)_{ij}} = \sum_{k=1}^{m} {a}_{ik}{b}_{kj}


これが、一般的に思いつく「積」のはずで、間違っても内積だの外積だのとは言わないはず。左行列の行ベクトルと、右行列の列ベクトルの「内積」を並べた行列とは言える。

numpyだとこう書く。

import numpy as np
A = np.array([[1,2,3],[4,5,6]])
B = np.array([[7,8],[9,10],[11,12]])
AB = np.dot(A, B)
print(AB)
>>
[[ 58  64]
 [139 154]]
AB = A @ B
print(AB)
>>
[[ 58  64]
 [139 154]]

アダマール

アダマール積は、下記で表される。

\boldsymbol{A} : n * m 行列,  \boldsymbol{B} : n * m 行列
\boldsymbol{(A∘B)_{ij}} = {a}_{ij}{b}_{ij}


要するに、「同じ位置の要素同士の積」をとっただけ。当然、同じサイズの行列同士でないと計算できない。

numpyだとこう書く。

A = np.array([[1,2,3],[4,5,6]])
B = np.array([[7,8,9],[10,11,12]])
AB_hadamard = A * B # numpy.matrixでは通常の積になるので注意。
print(AB_hadamard)
>>
[[ 7 16 27]
 [40 55 72]]
AB_hadamard = np.multiply(A, B)
print(AB_hadamard)
>>
[[ 7 16 27]
 [40 55 72]]

フロベニウス内積

フロベニウス内積は、下記で表される。

 \boldsymbol{A} : n * m 行列,  \boldsymbol{B} : n * m 行列
 \boldsymbol{A:B} = \sum_{i,j} {a}_{ij}{b}_{ij}


総和をとっているので、計算結果は「スカラー」になることに注意。「同じ位置の要素同士の積の合計」と覚える。フロベニウス内積はベクトルの「内積」と計算の見た目が同じ。

numpyだとこう書く。

A = np.array([[1,2,3],[4,5,6]])
B = np.array([[7,8,9],[10,11,12]])
AB_frobenius = np.sum(A*B) # アダマール積を計算してからsumをとる
print(AB_frobenius)
>>
217

以上。積ひとつとっても色々概念があって難しい…

参考資料