クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

ドット積とコサイン類似度

このレッスンのあとで: ドット積を使って、2つのベクトルがどれだけ同じ向きかを言うことができる。

55分のレッスンコマンド2件JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

ドット積は向きの一致を測る

ドット積とは、2つのベクトルの同じ位置の成分を掛けて、全部足した数です。この1つの数から、2つのベクトルがどれだけ同じ向きを向いているかが分かります。

映画の好みを点数のベクトルにすると、好みの似た人を探せます。おすすめの機能は、この考え方を使います。

このレッスンのゴール

メモ

ドット積を使って、2つのベクトルがどれだけ同じ向きかを言うことができる。

キーワード

ことばいみ
ドット積同じ位置の成分を掛けて、全部足した数。内積ともいう
向きベクトルが指している方向。長さとは別
直交2つのベクトルが直角で、ドット積が 0 になること
コサイン類似度向きの近さを、-1 から 1 の数で表したもの

学生が入力するセルは、このプレビューでは空白です。

ドット積は掛けて足すだけ

2つのベクトルの同じ位置の成分を掛け、その合計を取ります。結果は、ベクトルではなく、ふつうの1つの数です。

同じ向きを向くと大きなプラスの数になり、直角だと 0、反対向きだとマイナスの数になります。

例: 3組のドット積

ab計算ドット積
[2, 3][4, 1]2 × 4 + 3 × 111
[1, 0][0, 1]1 × 0 + 0 × 10
[2, 2][2, -2]2 × 2 + 2 × (-2)0
[1, 2][-1, -2]1 × (-1) + 2 × (-2)-5

学生が入力するセルは、このプレビューでは空白です。

ドット積を計算する

コード: python
# 3つのジャンルで、2人が付けた点数です。
hina = [5, 1, 0]
ren = [4, 2, 0]

total = 0
for i in range(len(hina)):
    total = total + hina[i] * ren[i]

print("ドット積:", total)
# ren の最後を 0 から 5 に変えて、ドット積を予想してから実行してください。

NumPy でドット積を求める

コマンド
docker exec jupyter python3 -c "import numpy as np; a = np.array([2, 3]); b = np.array([4, 1]); print(np.dot(a, b), a @ b)"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コサイン類似度は向きだけを比べる

ドット積は、ベクトルが長いほど大きくなります。向きだけを比べたいので、2つの長さの積で割ります。これがコサイン類似度です。

同じ向きなら 1、直角なら 0、反対向きなら -1 になります。長さが違っても、向きが同じなら 1 です。

例: コサイン類似度の値

abドット積 ÷ 長さの積結果
[3, 4][4, 3]24 ÷ (5 × 5)0.96
[1, 2][2, 4]10 ÷ (√5 × √20)1
[1, 0][0, 1]0 ÷ (1 × 1)0
[1, 0][-1, 0]-1 ÷ (1 × 1)-1

学生が入力するセルは、このプレビューでは空白です。

よくある間違い

注意

多くの人は、ドット積が大きいほど、2つが似ていると考えます。長いベクトルは、向きが違っても大きくなります。向きの近さは、長さで割ったコサイン類似度で比べます。

好みの近い人を探す

3人が、アクション、コメディ、恋愛の3つに0から5の点数を付けました。ひなたは [5, 1, 0]、蓮は [4, 2, 0]、葵は [0, 1, 5] です。

ひなたと蓮のコサイン類似度は約 0.96、ひなたと葵は約 0.04 です。ひなたには、蓮の好みが近いと分かります。

コサイン類似度を計算する

コード: python
# ドット積を、2つの長さの積で割ると、向きの近さになります。
a = [3, 4]
b = [4, 3]

dot = a[0] * b[0] + a[1] * b[1]
length_a = (a[0] ** 2 + a[1] ** 2) ** 0.5
length_b = (b[0] ** 2 + b[1] ** 2) ** 0.5

print("ドット積:", dot)
print("コサイン類似度:", dot / (length_a * length_b))
# b を [6, 8] に変えて、結果が変わるかどうか予想してください。

3人の好みの近さを求める

コマンド
docker exec jupyter python3 -c "import numpy as np; hina = np.array([5, 1, 0]); ren = np.array([4, 2, 0]); aoi = np.array([0, 1, 5]); n = np.linalg.norm; print(round(hina @ ren / (n(hina) * n(ren)), 2), round(hina @ aoi / (n(hina) * n(aoi)), 2))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

さらに挑戦: 単位をそろえる

前回の1日のベクトル [気温, 雨量, 貸出台数] は、台数の数字が大きすぎました。それぞれの列を、その列の最大の値で割ると、どの成分も 0 から 1 になります。

こうして単位をそろえてから、ドット積で、よく似た2日を探してみましょう。

このラボとソースについて: JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。