顔が似ている。好みが似ている。声が似ている。
自分たちは日常で「似ている」をかなり自然に使っています。 でも、それを機械にやらせるには、どこかで数にしないといけません。
「似ている」を数で測るとは、何を測ることなのでしょうか。 距離が近いことなのか、それとも別の何かなのか。 このラボノートでは、好みを二つの数にして、その違いを見ていきます。
「似てる」って、どう決めているのか
人の顔なら、輪郭や目鼻の配置を見ています。 声なら、高さやリズムや話し方を聞いています。 好みなら、「甘いものが好き」「辛いものも好き」といった傾向を比べています。
ここで共通しているのは、対象をいくつかの特徴に分けていることです。 特徴に分けられれば、それぞれを数にできます。 数にできれば、機械にも比べられます。
ただし、数にした瞬間に問題が出ます。 何を同じと見なし、何を違うと見るのかを、こちらが決めなければならないからです。
好みを数の並びにする
たとえば、好みを二つの軸で表してみます。 横軸を「甘いもの好き度」、縦軸を「辛いもの好き度」とします。
人Aの好みを $A=(4,2)$、人Bの好みを $B=(8,4)$、人Cの好みを $C=(2,6)$ と置きます。 $(4,2)$ は、甘いもの好き度が $4$、辛いもの好き度が $2$ という意味です。
こういう数の並びをベクトルと呼びます。 ベクトルは、数を順番に並べたものです。 二つの数なら平面上の一点として描けますし、原点からその点へ矢印を引けば、「どちらへ伸びているか」も見えます。

図で見ると、AとBは同じ直線上にあります。 BはAの2倍なので、矢印の長さは違いますが、向きは同じです。 一方でCは、甘いものより辛いものの方向へ強く伸びています。
この時点で、AとBはかなり似ているように見えます。 どちらも「甘いものの方が、辛いものより好き」という傾きが同じだからです。
距離で測るとつまずく
素朴には、近いほど似ていると考えたくなります。 平面に点を置いたのだから、点と点の距離を測ればよさそうです。
でもAとBでそれをやると、少し変なことが起きます。 BはAの2倍なので、好みの傾向は同じです。 それでも点としては離れています。
距離を計算すると、
$$ |A-B|=\sqrt{(8-4)^2+(4-2)^2}=\sqrt{20}\approx4.47 $$
です。 距離だけを見ると、AとBはゼロではない違いを持つ別の点です。 でも、好みの傾きは同じままです。
しかし、この違いの中身は「何を好むか」ではありません。 Bが全体に強く答えているだけです。 甘いものも辛いものも、Aの2倍の強さで表現している。 傾きは変わっていません。
距離は、こういう表現の強さに引きずられます。 何でも強めに「大好き」と答える人と、控えめに点をつける人がいると、同じ傾向でも離れて見えてしまいます。
内積とコサインで向きを測る
二つのベクトル $a$ と $b$ の内積は、次の形で書けます。
$$ a\cdot b=\sum_i a_i b_i $$
二次元なら、
$$ a\cdot b=a_1b_1+a_2b_2 $$
です。 成分どうしを掛けて足す。 これは、二つの矢印がどれだけ同じ方向へ一緒に伸びているかを数にする操作です。
ただし内積も、矢印が長いほど大きくなります。 AとBの内積は、
$$ A\cdot B=4\cdot8+2\cdot4=40 $$
です。 Bが長いぶん、重なりの量も大きく出ます。 そこで、長さで割ります。
$$ \cos\theta=\frac{a\cdot b}{|a|\,|b|} $$
分子の $a\cdot b$ は、二つの矢印の重なりです。 分母の $|a|\,|b|$ は、それぞれの矢印の長さを掛けたものです。 重なりを長さで割ると、強さの効果が消えて、角度だけが残ります。
AとBで確かめると、
$$ |A|=\sqrt{20}=2\sqrt5,\quad |B|=\sqrt{80}=4\sqrt5 $$
なので、
$$ \frac{A\cdot B}{|A|\,|B|}=\frac{40}{40}=1 $$
になります。 距離は $\sqrt{20}$ だけ離れているのに、向きは完全に一致しています。 コサイン類似度では、AとBは同じ方向を向いていると読めます。
Cとも比べます。
$$ A\cdot C=4\cdot2+2\cdot6=20 $$
また、
$$ |C|=\sqrt{40}=2\sqrt{10} $$
なので、
$$ \frac{A\cdot C}{|A|\,|C|}=\frac{20}{20\sqrt2}=\frac{1}{\sqrt2}\approx0.71 $$
です。 AとCは、まったく無関係ではありません。 どちらも甘いものと辛いものをある程度好きです。 でも向きは45度ずれていて、AとBほどはそろっていません。
今回は好み度をすべて $0$ 以上で置いています。 すると二つの矢印が反対を向くことはなく、コサイン類似度は $0$ から $1$ の間に収まります。 $1$ に近いほど傾向がそろっていて、$0$ に近いほど食い違っている、という「似てる度合い」として読めます。 一般のベクトルでは、逆向きの成分があれば負になり、コサイン類似度は $-1$ から $1$ まで動きます。
この「掛けて足す」=内積は、行列のかけ算の一つ一つの中身でもあります。GPU がその計算を速くこなせる理由は、別の記事で書きました。
距離と角度を分けて見る
AとBの食い違いを図にすると、距離と角度が別の量だと分かります。 点としてのAとBは離れています。 でも原点から見た矢印の向きは同じです。

右側の図では、矢印の長さをすべて1にそろえています。 これを正規化と呼びます。 正規化は、長さをいったん捨てて、向きだけを残す操作です。
長さをそろえると、BはAにぴったり重なります。 Cだけが別の場所に残ります。 この見え方が、コサイン類似度の気持ちです。
距離で見ると、AとBは離れています。 コサインで見ると、AとBは同じ向きです。 どちらが正しいかではなく、何を比べたいかが違います。 量の差を見たいなら距離が効きます。 傾向の一致を見たいなら、長さを割って向きを見る方が合います。
長さを捨てる、が本質
コサイン類似度がやっていることは、かなりはっきりしています。 どれだけ強く好きかという量をいったん捨てて、何を相対的に好むかという傾きだけを残しています。
だから、熱量の大きい人と控えめな人を比べられます。 文章なら、長い文章と短い文章を比べられます。 文章をどんな単語が何回出たかという頻度のベクトルにすれば、長さの違いに引きずられずに話題の近さを測れます。 評価なら、点を甘くつける人と厳しくつける人を、傾向だけで比べられます。
「似ている」を測るとは、いつも距離を縮めることではありません。 少なくともコサイン類似度では、長さを捨てて、向きがそろっているかを見ることです。
似ているの正体は、近さではなく向きでした。 次はこの「向きで測る」が、AIが文章を読むときにどう効いてくるのか、その入り口から書きたいと思います。
あわせて読みたい関連記事。



