Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

内積

kk次元のベクトルa=(a1,a2,,ak), b=(b1,b2,,bk)\boldsymbol{a} = (a_1, a_2, \dots, a_k)^\top, \ \boldsymbol{b} = (b_1, b_2, \dots, b_k)^\topがあるとき、

i=1kaibi\sum^k_{i=1} a_i b_i

という演算を内積(inner product)といい、ab\boldsymbol{a}^\top \boldsymbol{b}ab\boldsymbol{a} \cdot \boldsymbol{b}(a,b)(\boldsymbol{a}, \boldsymbol{b})a,b\langle\boldsymbol{a}, \boldsymbol{b} \rangleと表す

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import japanize_matplotlib

a = np.array([1, 1, 1])
b = np.array([2, 2, 2])
a.T @ b
6

ノルム

ベクトルa\boldsymbol{a}に対してab\sqrt{\boldsymbol{a}^\top \boldsymbol{b}}をベクトルa\boldsymbol{a}長さ または ノルム(norm) といい、a\|\boldsymbol{a}\|で表す。すなわち

a=ab,a2=ab\|\boldsymbol{a}\| = \sqrt{\boldsymbol{a}^\top \boldsymbol{b}}, \quad \|\boldsymbol{a}\|^2= \boldsymbol{a}^\top \boldsymbol{b}

である。

内積と類似度

コサイン類似度

aTb=a bcos(a,b)    cos(a,b)=aTba b\newcommand{\b}[1]{\boldsymbol{#1}} \boldsymbol{a}^T \boldsymbol{b} = ||\boldsymbol{a}|| \ ||\boldsymbol{b}|| \cos(\boldsymbol{a}, \boldsymbol{b}) \\ \implies \cos(\boldsymbol{a}, \boldsymbol{b}) = \frac{ \boldsymbol{a}^T \boldsymbol{b} }{ ||\boldsymbol{a}|| \ ||\boldsymbol{b}|| }

コサイン類似度はベクトルを矢印で表現したときに同じ方向を向いているほど1に近く、真逆の方向ほど-1に近くなる

def cos(a, b):
    return (a.T @ b) / (np.linalg.norm(a) * np.linalg.norm(b))

cos(a, b)
1.0000000000000002
Source
o = np.array([0, 0])
buffer = 0.1
lim = np.array([-1, 1]) * (1 + buffer)
ticks = [-1, 0, 1]

datasets = [
    [np.array([1, 0]), np.array([0, 1])],
    [np.array([1.1, 0.9]), np.array([0.9, 1.1])],
    [np.array([1, 1]), np.array([-1, -1])],
]
m = len(datasets)
fig, axes = plt.subplots(ncols=m, figsize=[m*3, 2.5])
for i in range(m):
    a, b = datasets[i]
    axes[i].arrow(*o, *a, width=0.02, color="black", length_includes_head=True, alpha=0.7)
    axes[i].arrow(*o, *b, width=0.02, color="black", length_includes_head=True, alpha=0.7)
    axes[i].grid(True, alpha=0.3)
    axes[i].set(title=f"cos(a, b) = {cos(a, b):.2f}", xticks=ticks, yticks=ticks, xlim=lim, ylim=lim)

fig.show()
<Figure size 900x250 with 3 Axes>

直交

コーシー・シュワルツの不等式

コサイン類似度が [1,1][-1, 1] の範囲に正規化される理由

平方根をとれば

abab| \boldsymbol{a}^\top \boldsymbol{b} | \leq \| \boldsymbol{a} \| \cdot \| \boldsymbol{b} \|

となり、それを変形すると

ababab- \| \boldsymbol{a} \| \cdot \| \boldsymbol{b} \| \leq \boldsymbol{a}^\top \boldsymbol{b} \leq \| \boldsymbol{a} \| \cdot \| \boldsymbol{b} \|

なので両辺をab\| \boldsymbol{a} \| \cdot \| \boldsymbol{b} \|で割れば

1abab1- 1 \leq \frac{ \boldsymbol{a}^\top \boldsymbol{b} }{ \| \boldsymbol{a} \| \cdot \| \boldsymbol{b} \| } \leq 1