アダマール積
同じサイズの行列 $A,\ B$ に対して、成分ごとの積をとる演算を アダマール積 (Hadamard product) または シューア積 (Schur product) とよび、$A\circ B$ で表します。たとえば、3×3サイズの行列同士のアダマール積は次のように表されます。
\[\begin{bmatrix}a_{11}&a_{12} &a_{13}\\a_{21}&a_{22}&a_{23}\\a_{31}&a_{32}&a_{33}\end{bmatrix}\begin{bmatrix}b_{11}&b_{12}&b_{13}\\b_{21}&b_{22}&b_{23}\\b_{31}&b_{32}&b_{33}\end{bmatrix}=\begin{bmatrix}a_{11}b_{11}&a_{12}b_{12}&a_{13}b_{13}\\a_{21}b_{21}&a_{22}b_{22}&a_{23}b_{23}\\a_{31}b_{31}&a_{32}b_{32}&a_{33}b_{33}\end{bmatrix}\tag{1}\]
ほぼ自明のことですが、アダマール積は交換則と分配則
\[\begin{align*}&A\circ B=B\circ A\tag{2}\\[6pt]&A\circ (B\circ C)=(A\circ B)\circ C\tag{3}\\[6pt]&A\circ (B+C)=A\circ B+A\circ C\tag{4}\end{align*}\]
を満たす演算です。(参考文献:フリー百科事典 Wikipedia)
NumPyのアダマール積
NumPy の配列に対して * 演算子を適用すると、成分ごとの積、すなわち アダマール積 を計算します(行列積ではありません)。3×3サイズの配列を用意して、配列積 (アダマール積) を計算させてみましょう。
# NumPy_Hadamard_product
# In[1]
import numpy as np
a = np.array([[3, 1, 7],
[0, 2, 5],
[9, 4, 3]])
b = np.array([[2, 2, 6],
[9, 6, 2],
[8, 1, 4]])
# aとbのアダマール積
print(a*b)
# [[ 6 2 42]
# [ 0 12 10]
# [72 4 12]]
アダマール積を使うと、$a_{ij}b_{ij}$ の総和
\[a_{11}b_{11}+a_{12}b_{12}+\ \cdots+\ a_{nn}b_{nn}\]
を簡潔なコードで実装できます。すなわち行列 $a_{ij}$ と $b_{ij}$ を用意しておいて、アダマール積をとってから、numpy.sum() ですべての成分の和をとります。たとえば、In[1] で定義した行列 a, b の成分ごとの積の和は以下のように計算できます。
# In[2]
# 行列 a, b の成分ごとの積の和
s = np.sum(a*b)
print(s)
# 160
これは機械学習などでも用いられる実践的な手法です。
sympy.matrix_multiply_elementwise()
SymPy では * 演算子は行列積を実行します。
アダマール積は matrix_multiply_elementwise() を使って計算します。
# SymPy_Hadamard_product
# In[1]
from sympy import Symbol, var, init_printing
from sympy.matrices import Matrix
from sympy.matrices import matrix_multiply_elementwise
init_printing()
# 一般表記の行列生成関数
def general_matrix(m, n, s):
Symbol(s)
elements = lambda i,j : var('{}{}{}'.format(s, i+1, j+1))
return Matrix(m, n, elements)
a = general_matrix(3, 3, "a")
b = general_matrix(3, 3, "b")
# aとbのアダマール積を計算
aob = matrix_multiply_elementwise(a, b)
# a,b,aobを表示
display(a, b, aob)
&\left[\begin{matrix}a_{11} & a_{12} & a_{13}\\a_{21} & a_{22} &a_{23}\\a_{31} & a_{32} & a_{33}\end{matrix}\right]\\[6pt]&\left[\begin{matrix}b_{11} & b_{12} & b_{13}\\b_{21} & b_{22} &b_{23}\\b_{31} & b_{32} & b_{33}\end{matrix}\right]\\[6pt]&\left[\begin{matrix}a_{11} b_{11} & a_{12} b_{12} & a_{13} b_{13}\\a_{21} b_{21} & a_{22} b_{22} & a_{23} b_{23}\\a_{31} b_{31} & a_{32} b_{32} & a_{33} b_{33}\end{matrix}\right]\end{align*}
【ChatGPT講義】アダマール積
アダマール積は、行列の要素ごとの積を計算する演算です。他の行列演算とは異なり、対応する要素同士の積を計算し、同じ位置にある要素同士を掛け合わせます。これにより、同じ次元を持つ2つの行列を要素ごとに結合させることができます。アダマール積は、要素ごとの操作が必要な場合に使用されます。例えば、データの要素ごとの相乗平均や要素ごとの比較、フィルタリングなどがアダマール積の応用例です。アダマール積を計算するためには、同じ次元を持つ2つの行列が必要です。行列Aと行列Bのアダマール積は、以下のように表されます:
C = A ⊙ B
ここで、Cは結果の行列であり、AとBの対応する要素の積です。具体的な例を見てみましょう。以下の2つの行列を考えます:
A = [[1, 2], [3, 4]]
B = [[2, 2], [2, 2]]
この場合、AとBのアダマール積は以下のように計算されます:
C = A ⊙ B = [[1*2, 2*2], [3*2, 4*2]] = [[2, 4], [6, 8]]
結果の行列Cは、対応する要素同士の積であり、同じ位置にある要素同士が掛け合わされた結果です。アダマール積は、NumPyなどの数値計算ライブラリを使って簡単に計算することができます。
アダマール積は以下のような場面で使用されます:
・データの要素ごとの変換: アダマール積は行列やベクトルの要素ごとの変換に使用されます。たとえば、行列やベクトルの各要素を別の行列やベクトルの対応する要素と乗算する場合に利用されます。
・データの要素ごとの関連付け: アダマール積は要素ごとの関連付けを表現するために使用されます。たとえば、2つのベクトルがあり、それぞれが同じインデックスの要素に関連付けられている場合、アダマール積を計算することで要素間の関連性を求めることができます。
・データのフィルタリング: アダマール積はデータのフィルタリングにも使用されます。たとえば、あるベクトルを別のベクトルでマスクする際に、アダマール積を使用してフィルタリングを行うことができます。マスクベクトルの要素が0の場合、対応する要素は0になり、フィルタリングされます。
これらはアダマール積の一般的な使用例です。応用はさまざまであり、数学、統計、信号処理、画像処理、機械学習などの分野で幅広く利用されています。