python(numpy)でL2ノルムが1になるようにする
コサイン類似度は以下で求まる.
\( cos(\vec{a}, \vec{b}) = \frac{\vec{a} \cdot \vec{b}}{ \sqrt{\sum^{n}a_i} \sqrt{\sum^{n}b_i}} \)
ここでコサイン類似度を求めるのに、毎度ベクトルのノルム(\( \sqrt{\sum^{n}a_i} \sqrt{\sum^{n}b_i}\) )を求めるのは効率が悪い. そこで予めこれが1になるようにする(→内積=コサイン類似度になる)
ベクトルのリスト
\(
X = (\vec{x_1}, \vec{x_2}, ..., \vec{x_n})
\)
について,各々のベクトルを正規化する.numpyのlinalg.norm
を利用するとベクトルの長さ(ノルム)を求めることができるので、それを利用する.
import numpy as np norm = np.linalg.norm(X, ord=2, axis=1) X = X / norm[:np.newaxis]
np.linalg.norm
について、キーワード引数ord
でノルムの次元数を指定、axis
でどの次元方向に和を取るかを指定できる.
Xをnorm[:np.newaxis]
で割って終了.
なおここでnorm
(横ベクトル)を縦ベクトルに転置している.
元の配列の大きさを維持する次元には":"を指定し,新たに大きさが 1 の次元を追加するところには np.newaxis
を指定している.