AI

コサイン類似度とは?計算式・仕組みと類似検索での実装を実装目線で解説

コサイン類似度とは、2つのベクトルがなす角のコサイン値を使って、両者がどれだけ似た向きを向いているかを測る指標です。値は-1から1の範囲を取り、1に近いほど向きがそろって似ており、0なら無関係、-1なら正反対を意味する。文章や画像を数値ベクトル(埋め込み)に変換したうえで意味的な近さを比べる場面で広く使われ、ベクトル検索やRAGの中核をなす計算です。本記事では、コサイン類似度の計算式と-1〜1の解釈、内積やユークリッド距離との違い、Pythonでの実装、そしてベクトル検索・RAGでの使われ方までを、実装の現場で判断できる粒度で整理します。

目次

まとめ:コサイン類似度はベクトルの向きの近さを-1〜1で測る指標

コサイン類似度は「2つのベクトルが同じ方向を向いているか」を数値化します。計算式は2ベクトルの内積を、それぞれの大きさ(ノルム)の積で割るだけです。大きさで割ることで、ベクトルの長さの違いを打ち消し、純粋に向きだけを比べられる。ここが距離ベースの指標と決定的に異なる点です。

先に結論を置きます。テキストの埋め込みのように「値の大小より方向が意味を持つ」データでは、コサイン類似度が第一候補になる。文書の長さや単語の出現回数が違っても向きが近ければ高い値を返すため、長短の異なる文章同士でも公平に比べられます。以降の章で、計算式の中身、他指標との違い、numpyやベクトルデータベースでの実装、採用と見送りの判断基準を順に示します。

コサイン類似度の計算式と-1から1が示す意味を数式目線で整理

まず定義と数式、そして値の範囲が何を表すかを押さえます。埋め込みを扱う実装では、この-1〜1の解釈が閾値設計の土台になる。

コサイン類似度の計算式と内積をノルムで割る操作が意味すること

2つのベクトル a と b のコサイン類似度は、両者の内積を、それぞれの大きさ(L2ノルム)の積で割った値です。数式では cos(a, b) = (a・b) ÷ (‖a‖ × ‖b‖) と書き、成分で展開すると Σ(aᵢ × bᵢ) ÷ (√Σaᵢ² × √Σbᵢ²) になります。分子の内積は2ベクトルがどれだけ同じ方向に伸びているかを表し、分母のノルムの積が各ベクトルの長さを打ち消す役割を担う。結果として、長さに左右されない「向きの一致度」だけが残ります。

コサイン類似度が1・0・-1になるときのベクトルの向きの関係

コサイン類似度は角度θのコサインそのものなので、値と角度が一対一で対応します。1は角度0度で完全に同じ向き、0は角度90度で直交(無関係)、-1は角度180度で正反対の向きを表す。数値と幾何的な意味の対応を整理します。

コサイン類似度の値 2ベクトルの角度 向きの関係 類似の解釈
1 0度 完全に同じ向き 非常に似ている
0.5前後 60度前後 やや近い向き ある程度似ている
0 90度 直交 無関係
-1 180度 正反対の向き 正反対の意味

テキスト埋め込みで実際に取りうるコサイン類似度の値と閾値の勘所

理論上は-1〜1ですが、実務で扱うテキスト埋め込みは負の値が出にくく、多くのモデルで0.0〜1.0付近に分布します。同じモデルで作ったベクトル同士では、無関係な文でも0.1〜0.3程度、意味が近い文で0.7以上、といった具合に山ができる。ここで押さえるべきは、閾値の絶対値はモデル依存だという点です。あるモデルで0.8が「ほぼ同義」でも、別モデルでは0.6が同水準ということが起こる。閾値は使うモデルの実データで分布を見てから決めるのが実装の勘所になります。

コサイン類似度と内積・ユークリッド距離を比べる指標選びの違い

類似度の指標はコサイン類似度だけではありません。内積やユークリッド距離との違いを押さえると、ベクトルデータベースで距離関数を選ぶときに迷わなくなる。

コサイン類似度と内積の違い・正規化したときに両者が一致する理由

内積(ドット積)はベクトルの向きと大きさの両方を反映する値で、大きさで割らない分だけ長いベクトルほど値が大きくなります。一方コサイン類似度は大きさを打ち消すため、向きだけを見る。両者には明快な関係があり、あらかじめ各ベクトルを長さ1に正規化しておけば、内積とコサイン類似度は完全に一致します。この性質は実装上の高速化に直結する。埋め込みを保存する時点で正規化しておけば、検索時はノルム計算を省いて内積だけで済み、計算量を減らせます。

コサイン類似度とユークリッド距離のそれぞれが向くデータの違い

ユークリッド距離は2点間の直線距離で、値が小さいほど近い(似ている)ことを表します。コサイン類似度が「向き」を見るのに対し、ユークリッド距離は「位置」を見る点が本質的な違いです。単語の出現回数や特徴量の絶対的な大きさそのものが意味を持つデータでは、距離のほうが実態に合う。逆に、文書の長さで頻度がふくらんでも意味は同じ、というテキスト系では、長さの影響を受けないコサイン類似度が向きます。正規化したベクトルではユークリッド距離とコサイン類似度が単調な対応関係になるため、正規化済みのデータではどちらを使っても順位は変わりません。

コサイン類似度とコサイン距離の関係と距離へ変換するときの注意

ベクトルデータベースの多くは「距離」で扱うため、コサイン距離という指標が登場します。コサイン距離は 1 − コサイン類似度 と定義され、値が小さいほど似ている、という距離の約束に合わせた形です。PostgreSQLの拡張pgvectorでは <=> 演算子がコサイン距離を返すため、類似度に直したいときは1から引く。実装では「類似度が高い=距離が小さい」の向きの反転を取り違えないことが、並べ替えのバグを防ぐ勘所になります。

コサイン類似度をPythonとベクトル検索で実装する具体的な手順

ここからは実装です。numpyでの素朴な計算から、ベクトルデータベースでの近傍探索までを追います。埋め込みベクトルを大量に扱う検索の全体像は、ベクトル検索とリランキングの違いを扱った記事で前提を押さえると流れがつかめます。

numpyでコサイン類似度を計算する最小コードと実装の注意点

2ベクトルのコサイン類似度は、numpyなら内積とノルムの3つの関数で書けます。import numpy as np のうえで、np.dot(a, b)np.linalg.norm(a) * np.linalg.norm(b) で割った値が定義そのままの実装です。多数のベクトルとの類似度をまとめて求めるなら、scikit-learnの cosine_similarity が行列単位で計算してくれる。実装時の注意はゼロベクトルの扱いです。ノルムが0のベクトルは分母が0になり計算が破綻するため、空文字列や全ゼロの埋め込みが混ざらないよう、事前に長さをチェックしておきます。

ベクトルデータベースの近傍探索でコサイン類似度を使う処理の流れ

文章や画像を埋め込みモデルでベクトルに変換し、ベクトルデータベースに格納したうえで、クエリのベクトルとコサイン類似度が高い順に取り出すのが類似検索の基本形です。件数が増えると全件との総当たりは重くなるため、近似最近傍探索(ANN)のインデックスで候補を絞る。pglite+pgvectorを使った具体的な類似度検索の組み立ては、pgvectorで文章の類似度検索を実装した記事で演算子レベルの書き方まで確認できます。埋め込みを正規化して保存し、内積で距離を取る構成にすれば、コサイン類似度と同じ順位を保ったまま計算を軽くできます。

RAGの検索フェーズでコサイン類似度が果たす役割と精度への影響

RAG(検索拡張生成)は、質問に関連する社内文書をベクトル検索で引き当て、その内容をLLMへ渡して回答させる仕組みです。この「関連文書を引き当てる」部分でコサイン類似度が働く。質問文の埋め込みと、あらかじめベクトル化した文書チャンクの埋め込みを比べ、類似度上位を文脈として渡します。RAG全体の設計思想はRAGの仕組みと導入例を解説した記事で確認できる。検索精度が回答品質を左右するため、埋め込みモデルの選定・チャンク分割・閾値設計を実データで詰める必要があり、この一連の実装は社内文書を対象としたRAG構築支援のように、埋め込み設計から検索チューニングまでを外部と分担する進め方もあります。

コサイン類似度を実務で採用してよい場面と見送るべき場面の基準

ここは独自の判断章です。コサイン類似度を選ぶか、別の指標にするかを、条件付きで言い切ります。

コサイン類似度が適する条件と向きが意味を持つデータの見分け方

次の条件に当てはまるデータでは、コサイン類似度が第一候補になります。ベクトルの大きさより「向き」が意味を持つこと、比べる対象の長さ(文書量や特徴量のスケール)にばらつきがあること、そして負の相関まで区別したいわけではないことです。テキスト埋め込みによる意味検索、文書レコメンド、FAQマッチングはこの条件にそろって当てはまる。文章が長くても短くても、述べている内容が近ければ高い類似度を返してほしい、という要件にコサイン類似度がかみ合います。

コサイン類似度を見送るべき場面と別の指標が向くケースの見極め

逆に、コサイン類似度が向かない場面を明示します。第一に、ベクトルの大きさ自体が情報を持つデータです。購入回数や金額のように、値の絶対量が重みを持つ特徴量では、大きさを捨てるコサイン類似度は情報を落とす。この場合はユークリッド距離や、大きさを残した内積が向きます。第二に、すべてのベクトルを正規化済みで扱う設計なら、内積のほうが計算が軽く同じ順位を得られるため、あえてノルム計算を挟むコサイン類似度を選ぶ理由は薄い。第三に、類似度の絶対値をそのまま「◯%一致」と外部に見せたい要件では、値がモデル依存でスケールが安定しない点が扱いにくく、順位づけの内部指標にとどめる判断が無難です。データの性質とスケールの扱いを実測してから、指標を決めます。

コサイン類似度の計算と実装・使い分けに関するよくある質問と回答

実装・設計の現場で挙がりやすい疑問を、5つに絞って答えます。

コサイン類似度はどのくらいの値なら「似ている」と判断できますか?

一律の基準はなく、使う埋め込みモデルによって変わります。多くのテキスト埋め込みでは、無関係な文で0.1〜0.3、意味が近い文で0.7以上に分布する傾向がありますが、これはモデル依存です。実運用では、正解ペアと不正解ペアの類似度分布を実データで測り、両者が分かれる境目を閾値に置くのが確実な決め方になります。

コサイン類似度と内積はどう使い分けますか?

ベクトルを長さ1に正規化しているなら、内積とコサイン類似度は同じ値になり、内積のほうがノルム計算を省ける分だけ速く求まります。正規化していない生のベクトルで向きだけを比べたいならコサイン類似度、大きさも含めて比べたいなら内積です。ベクトルデータベースでは保存時に正規化して内積で検索する構成が広く採られます。

コサイン類似度は負の値になりますか?

定義上は-1から1の範囲で負にもなり得ますが、テキスト埋め込みでは負の値が出にくく、実際には0付近から1の範囲に収まることが多いです。負の値は2ベクトルが正反対の向きを指す場合に現れます。埋め込みの成分が非負に寄るモデルでは、直交(0)より下にはあまり下がりません。

コサイン類似度とコサイン距離は何が違いますか?

コサイン距離は 1 − コサイン類似度 で定義される値で、類似度とは大小の向きが逆になります。類似度は高いほど似ている、距離は小さいほど似ている、という約束の違いです。pgvectorの <=> 演算子はコサイン距離を返すため、類似度が必要なときは1から引いて変換します。

コサイン類似度はPythonでどう計算しますか?

numpyなら np.dot(a, b)np.linalg.norm(a) * np.linalg.norm(b) で割るのが定義そのままの実装です。多数のベクトルとまとめて比べるなら、scikit-learnの cosine_similarity が行列単位で計算します。分母が0になるゼロベクトルだけは事前に除外しておきます。

関連記事

資料請求

RELATED POSTS 関連記事