コサイン類似度と内積の関係を新人エンジニアにわかりやすく解説
こんにちは。ゆうせいです。
今日は「コサイン類似度と内積の関係」についてお話しします。機械学習やデータ分析を勉強すると必ず出てくる概念ですが、公式だけ見るとピンとこない人も多いんですよね。そこで、イメージを重視して解説していきます!
コサイン類似度とは?
コサイン類似度(Cosine Similarity)は、2つのベクトルがどれくらい同じ方向を向いているかを表す指標です。値は -1 から 1 の範囲に収まります。
- 1 → 完全に同じ方向
- 0 → 直角で全く関係がない
- -1 → 完全に逆方向
方向だけに注目するので、長さ(大きさ)は関係ありません。たとえば、(1,1) と (100,100) は大きさが全然違いますが、向きが同じなのでコサイン類似度は1になります。
内積との関係
ここで登場するのが「内積」です。
実は、コサイン類似度は内積を使って表現できます。
公式はこうです。
cos類似度(a, b) = (a・b) / (|a||b|)
ここで
- a・b は内積
- |a|, |b| はそれぞれのベクトルの大きさ
つまり「内積をベクトルの長さで割ったもの」がコサイン類似度です。
内積は「2つのベクトルがどれくらい同じ方向を向いているか」を表す数値です。なす角 θ との関係式をふまえると、向きによって計算結果にはっきりしたパターンが現れます。
※この記事ではベクトルを太字(a, b)で表します。
a ・ b = |a| |b| cos θ
長さは必ず0以上なので、内積の符号を決めているのは cos θ、つまり「向き」だけです。
190°を向いている場合(直交)
2つのベクトルが直角(90°)をなすとき、内積は必ず 0 になります。これは「相手と同じ方向に向かう成分がゼロ」であることを意味します。
具体例
a = (2, 1)、b = (−2, 4) の場合:
a・b = 2 × (−2) + 1 × 4
= −4 + 4
= 0
理由cos 90° = 0 だからです。どんなに長いベクトル同士でも、直角なら結果は0になります。
ポイント物理で例えると、「横に動いている物体を真上から押しても、進行方向への仕事(エネルギー移動)はゼロ」という状態と同じです。
2反対方向を向いている場合
① 完全に真反対(180°)を向いている場合
ベクトルが正反対を向いているとき、内積は「マイナスの最大値」になります。長さの積にそのままマイナスがついた値です。
具体例
a = (1, 2)、b = (−2, −4) の場合(b は a の完全な逆向きで2倍の長さ):
a・b = 1 × (−2) + 2 × (−4)
= −2 − 8
= −10
検算|a| = √5、|b| = √20 = 2√5 なので、|a||b| = 2 × 5 = 10。これに cos 180° = −1 を掛けて −10。定義式の結果と一致します。
② やや反対向き(90°〜180°の鈍角)の場合
完全な真反対でなくても、角度が90°より開いていれば内積は必ずマイナスになります。
具体例
a = (1, 2)、b = (−3, 1) の場合:
a・b = 1 × (−3) + 2 × 1
= −3 + 2
= −1
角度の確認|a| = √5、|b| = √10 なので cos θ = −1 ÷ √50 ≒ −0.14。つまり θ ≒ 98°で、たしかに鈍角です。値が0に近いのは「ほぼ直角だが、わずかに逆向き」だからです。
イメージ「前進しようとする車に、斜め後ろからの引っ張り(抵抗)が働いている」ような状態です。
3まとめ:内積の符号と向きの関係
| なす角 θ | cos θ の値 | 内積の符号 | 意味 |
|---|---|---|---|
| 鋭角(0° ≦ θ < 90°) | プラス(> 0) | プラス(> 0) | 同じような方向を向いている |
| 直角(θ = 90°) | ゼロ(= 0) | ゼロ(= 0) | お互いに干渉しない(垂直) |
| 鈍角(90° < θ ≦ 180°) | マイナス(< 0) | マイナス(< 0) | 逆の方向を向いている |
内積の値そのものを覚える必要はありません。符号を見れば向きが分かる——プラスなら味方、ゼロなら無関係、マイナスなら逆向き。この対応さえ押さえておけば、ベクトルの計算結果から状況をイメージできるようになります。
分母の |a| は「ベクトルの長さ」= L2ノルム
分母にある |a| は、ベクトル a の大きさ(長さ)を表します。これを機械学習の文脈では L2ノルム と呼び、‖a‖2 と書くこともあります。定義は次のとおりです。
|a| = √( a12 + a22 + … + an2 )
「各成分を2乗して、全部足して、ルートを取る」。それだけです。
名前の由来L2の「2」は、成分を2乗して足すことに由来します。同じ発想で、絶対値を足すだけの L1ノルム(|a1|+|a2|+…)もあります。正則化のLasso(L1)/Ridge(L2)の呼び分けもここから来ています。
2次元なら、それは三平方の定理そのもの
成分が2つ、つまり a = (a1, a2) の場合、上の定義はこうなります。
|a| = √( a12 + a22 )
見覚えがあるはずです。直角三角形の斜辺を求める式、そのままですね。原点からベクトルの終点まで矢印を引くと、横方向の成分 a1 を底辺、縦方向の成分 a2 を高さとする直角三角形ができます。そしてベクトルの長さは、その斜辺にあたります。 O (3, 4) 3 4 |a| = 5 ベクトルの長さ(L2ノルム)は、成分が作る直角三角形の斜辺
具体例
a = (3, 4) の長さを求めてみます。
|a| = √( 32 + 42 )
= √( 9 + 16 ) = √25
= 5
ポイントおなじみの「3・4・5の直角三角形」です。L2ノルムという新しい計算を覚えたわけではなく、三平方の定理に別名がついているだけだと理解しておくと、この先ずっと楽になります。
3次元以上も、考え方は同じ
3次元 (a1, a2, a3) では、まず底面で三平方の定理を使って底面の対角線 √(a12+a22) を求め、それを底辺・高さ a3 としてもう一度三平方の定理を使います。すると結局 √(a12+a22+a32)。次元が増えても「2乗して足してルート」という形は変わりません。だからこそ、300次元の単語ベクトルのように絵に描けない世界でも、同じ式で長さが測れるのです。
なぜ長さで割るのか:向きだけを取り出すため
内積 a・b は、ベクトルが長いほど大きな値になってしまいます。「向きの近さ」を知りたいのに、長さの影響が混ざっているわけです。そこでそれぞれの長さで割って、長さの影響を打ち消す。残るのが cos θ、すなわち向きだけの指標です。値は必ず −1 〜 1 の範囲に収まります。
具体例:向きは同じで長さが違うペア
a = (1, 2)、b = (2, 4)(b は a の2倍の長さ、向きは同じ):
a・b = 1×2 + 2×4 = 10
|a| = √(1+4) = √5
|b| = √(4+16) = √20 = 2√5
分母 = √5 × 2√5 = 10
cos θ = 10 ÷ 10 = 1 (θ = 0°)
意味内積そのものは10という中途半端な値ですが、長さで割るとぴったり1。「長さは倍でも向きは完全に同じ」という事実だけが取り出せました。
具体例:前回の鈍角のペア
a = (1, 2)、b = (−3, 1):
a・b = −3 + 2 = −1
分母 = √5 × √10 = √50 ≒ 7.07
cos θ = −1 ÷ 7.07 ≒ −0.14 (θ ≒ 98°)
4まとめ:3つの用語は同じものを指している
| 呼び方 | 使われる場面 | 2次元での式 |
|---|---|---|
| 斜辺の長さ | 中学数学(三平方の定理) | √(x2+y2) |
| ベクトルの大きさ |a| | 高校数学(ベクトル) | √(a12+a22) |
| L2ノルム ‖a‖2 | 機械学習・G検定 | √(a12+a22) |
コサイン類似度の分母は、2つのベクトルのL2ノルムの積。そのL2ノルムの中身は三平方の定理で斜辺を求める計算です。分子の内積が「どれだけ同じ方向を向いているか」を測り、分母がその値から長さの影響を取り除く——この役割分担が分かれば、文書やベクトルの類似度計算はもう怖くありません。
例で確認
a = (1, 0)、b = (0, 1) の場合
- 内積:a・b = 1×0 + 0×1 = 0
- |a| = 1, |b| = 1
- cos類似度 = 0 / (1×1) = 0
つまり直角なので似ていないと判断されます。
次に a = (1, 1)、b = (2, 2) の場合
- 内積:a・b = 1×2 + 1×2 = 4
- |a| = √(1²+1²) = √2
- |b| = √(2²+2²) = √8 = 2√2
- cos類似度 = 4 / (√2 × 2√2) = 1
大きさは違うけれど方向が同じなので、類似度は1となります。
cos類似度は三角関数で計算できないのか?
「cos類似度は三角関数で計算できないのか?」という疑問は、コサイン類似度を初めて学ぶ人が必ず一度は抱くものなんです。
結論
理論的には「三角関数の cos を使って求める」ことは可能です。ただし、実際には三角関数を直接計算することはほとんどありません。なぜなら、三角関数を使わずに内積を利用した式の方が計算がはるかに簡単だからです。
cos類似度の定義
コサイン類似度は角度 θ を使って定義すると、
cos類似度(a, b) = cosθ
ここで θ は2つのベクトル a, b のなす角です。
つまり「角度がわかれば三角関数で計算できる」ことになります。
角度を求める難しさ
でも実際に角度 θ を求めるとなると…?
ベクトル a, b が与えられているとき、θ を出すには三角関数の逆関数(arccos)を使わなければなりません。
θ = arccos( (a・b) / (|a||b|) )
すると最終的に cos類似度 = cosθ に戻すので、結局 a・b / (|a||b|) という内積を使った式にたどり着きます。
まとめると
- 定義としては cos類似度 = cosθ
- でも角度 θ を求めるのに arccos を使うと計算が複雑になる
- だから内積の式 cos類似度 = (a・b) / (|a||b|) を直接使った方が効率的
具体例
a = (1, 0), b = (1, 1)
- 内積を使う方法
a・b = 1×1 + 0×1 = 1
|a| = √(1²+0²) = 1
|b| = √(1²+1²) = √2
cos類似度 = 1 / (1×√2) = 1/√2 ≈ 0.707 - 角度から求める方法
θ = arccos(1/√2) = 45°
cosθ = 0.707
同じ答えですが、内積を使った方が一発で出せます。
エンジニアとしての応用
- 検索エンジン:文章をベクトル化してコサイン類似度で近い文章を探す
- レコメンドシステム:ユーザーの嗜好ベクトルと商品の特徴ベクトルを比較
- クラスタリング:類似度の高いデータをまとめる
このように「ベクトルの大きさは関係なく方向だけで判断する」という性質が、データ解析や機械学習の現場でとても便利なんです。
まとめ
コサイン類似度は「内積をベクトルの長さで割ったもの」で、2つのベクトルがどれだけ同じ方向を向いているかを表します。
内積は方向と大きさを含む情報ですが、そこから「大きさの影響を消して純粋に方向だけを見る」のがコサイン類似度です。
次の学習ステップとしては、ユークリッド距離やマンハッタン距離など、ほかの類似度指標とも比較してみると理解が一層深まりますよ。
さて、あなたが今扱っているデータは「方向(傾向)」を重視すべきでしょうか? それとも「大きさ(量)」を重視すべきでしょうか?
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール



