コサイン類似度とは
Cosine Similarity
2つのベクトルがなす角度の近さから、意味的な類似度を測る指標
ひとことで言うと
2つの意味ベクトルの「向き」がどれだけ近いかで、意味の近さを測るものさし。
概要
コサイン類似度は、2つのベクトルの内積をそれぞれのベクトルの大きさ(ノルム)の積で割った指標。 2つのベクトルがなす角度の余弦(コサイン)に相当し、ベクトルの向きがどれだけ近いかを-1から1の範囲で表す。 値が1に近いほど2つのベクトルはほぼ同じ向き(意味的に近い)であることを示し、0に近いほど無関係、-1に近いほど反対の向きであることを示す。 ベクトルの大きさではなく向きだけに着目するため、埋め込みベクトルの大きさが文の長さなどによって変動しても意味の近さを一定の基準で比較でき、セマンティック検索や文書間の類似度計算で標準的に使われている。 ベクトルをあらかじめ大きさ1に正規化しておけば、コサイン類似度の計算は単純な内積の計算と等価になる。ベクトル検索エンジンの多くはこの性質を前提に実装している。
背景
埋め込みベクトル同士の類似度を測る際、単純なユークリッド距離はベクトルの大きさの違いに影響されやすく、文の長さなどが異なる文書同士の比較には不向きな場合がある。 コサイン類似度は、ベクトルの向きだけに着目することでこの影響を受けにくくし、意味的な近さをより安定して比較できる指標として広く使われるようになった。
歴史
1970年代: Gerard Saltonらが情報検索のベクトル空間モデル(Vector Space Model)を提唱し、文書とクエリの類似度を測る指標としてコサイン類似度を採用。 2010年代以降: word2vecやBERTなど分散表現・埋め込みモデルの普及に伴い、意味的な近さを測る標準的な指標としてコサイン類似度が広く使われるようになる。
アーキテクチャ
2つのベクトル a と b に対し、コサイン類似度は内積 a・b を、それぞれのノルム|a|と|b|の積で割った値として計算される。 この値は、2つのベクトルがなす角度θの余弦cosθと数学的に一致し、角度が0度(同じ向き)のとき1、90度(直交)のとき0、180度(反対向き)のとき-1をとる。
ワークフロー
比較したい2つのベクトルを用意する(埋め込みモデルの出力など)。 それぞれのベクトルの内積と、各ベクトルのノルム(大きさ)を計算する。 内積をノルムの積で割り、-1から1の範囲のコサイン類似度を得る。 ベクトルをあらかじめL2正規化しておけば、ノルムが常に1になるためこの割り算が不要になり、内積の計算だけで類似度を求められる。 検索用途では、この計算をクエリと全候補ベクトルの組に対して行い、類似度が高い順に候補をランキングする。
コード例
scikit-learnでのコサイン類似度計算
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
a = np.array([[1, 2, 3]])
b = np.array([[4, 5, 6]])
similarity = cosine_similarity(a, b)
print(similarity) # [[0.9746318]]利点
- ベクトルの大きさに影響されず、向きの近さだけで意味的な類似度を比較できる
- 計算がシンプルで、正規化済みベクトルであれば内積の計算だけで済む
- 埋め込みベクトルを使う様々な検索・比較タスクで標準的に使われ、実装例やライブラリのサポートが豊富
欠点
- ベクトルの大きさの情報を無視するため、大きさ自体に意味がある用途には向かない
- 埋め込み空間の学習のされ方によっては、コサイン類似度が必ずしも人間の感じる意味的な近さと一致しないことがある
- 非常に高次元な空間では、ランダムなベクトル同士でも類似度が特定の値へ偏りやすいという性質がある
比較
関連用語
よくある質問
コサイン類似度とユークリッド距離の違いは?
ユークリッド距離はベクトル間の直線的な距離を測るのに対し、コサイン類似度はベクトルの向きの近さだけを測る。ベクトルの大きさが意味を持たない埋め込み同士の比較では、コサイン類似度がよく使われる。
コサイン類似度の値はどう解釈する?
1に近いほど意味的に近く、0に近いほど無関係、負の値に近いほど反対の意味合いを持つ傾向がある。実務では0.7〜0.8以上を類似と判断する閾値に使うことが多いが、最適な閾値は埋め込みモデルごとに異なる。
参考文献
- Documentationsklearn.metrics.pairwise.cosine_similarity