似た問い合わせをまとめたい
コサイン類似度とは、2つの文章がどれくらい似ているかを、0から1の数で表す方法です。検索や、似た問い合わせをまとめる仕事に使います。
レンタサイクル店には、似た問い合わせが何通も届きます。1通ずつ読み比べる代わりに、文章を数の列にして、数で比べます。
このレッスンのゴール
メモ
2つの文章の似ている度合いを、コサイン類似度で計算することができる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| ベクトル | 数を決まった順に並べた列 | [1, 0, 2] |
| 内積 | 同じ位置の数をかけて、全部足した値 | |
| ベクトルの長さ | 各数を2乗して足し、平方根を取った値 | |
| コサイン類似度 | 向きの近さを、0から1で表した数 | |
| 語彙 | すべての文書に出た、異なる語の一覧 |
学生が入力するセルは、このプレビューでは空白です。
文章は数の列になる
語彙を決めて、その順に各語の回数を並べると、文章はベクトル(数の列)になります。同じ語彙で作れば、どの文章も同じ長さの列です。
列の同じ位置は、いつも同じ語を表します。だから、2つの列を位置ごとに比べられます。
例: 3つの問い合わせのベクトル
| 問い合わせ | 予約 | 雨 | 修理 | 自転車 |
|---|---|---|---|---|
| A「自転車の予約を変える」 | 1 | 0 | 0 | 1 |
| B「雨で自転車の予約を取り消す」 | 1 | 1 | 0 | 1 |
| C「自転車の修理を頼む」 | 0 | 0 | 1 | 1 |
学生が入力するセルは、このプレビューでは空白です。
回数を数えてベクトルにする
vocab = ["予約", "雨", "修理", "自転車"]
doc = ["雨", "自転車", "予約", "自転車"]
vector = []
for word in vocab:
vector.append(doc.count(word))
print(vector)
# doc に "修理" を足して、もう一度実行してください。
内積とベクトルの長さの出し方
内積は、同じ位置の数をかけて、全部足した値です。共通の語が多いほど、大きくなります。
ベクトルの長さは、各数を2乗して足し、その平方根を取った値です。長い文章ほど、長さが大きくなります。
内積と長さを端末で出す
docker exec jupyter python3 -c "print(3 * 4 + 4 * 3, (3 ** 2 + 4 ** 2) ** 0.5)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
例: [3, 4] と [4, 3]
| 出すもの | 計算 | 値 |
|---|---|---|
| 内積 | 3×4 + 4×3 | 24 |
| [3, 4] の長さ | 3×3 + 4×4 = 25 の平方根 | 5 |
| [4, 3] の長さ | 4×4 + 3×3 = 25 の平方根 | 5 |
学生が入力するセルは、このプレビューでは空白です。
コサイン類似度は向きの近さを表す
コサイン類似度は、内積を、2つの長さの積で割った値です。長さで割るので、文章の長さに左右されず、向きだけを比べます。
共通の語がなければ0で、まったく同じ向きなら1です。回数は負にならないので、答えは0から1の間に入ります。
コサイン類似度を端末で出す
docker exec jupyter python3 -c "print(round(24 / (5 * 5), 2))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
例: 3つの問い合わせの類似度
| 組み合わせ | 内積 | 類似度(小数第2位まで) |
|---|---|---|
| AとB | 2 | 0.82 |
| AとC | 1 | 0.5 |
| BとC | 1 | 0.41 |
学生が入力するセルは、このプレビューでは空白です。
コサイン類似度を計算する
import math
a = [3, 4]
b = [4, 3]
dot = 0
for n in range(len(a)):
dot = dot + a[n] * b[n]
length_a = math.sqrt(a[0] ** 2 + a[1] ** 2)
length_b = math.sqrt(b[0] ** 2 + b[1] ** 2)
print("内積:", dot)
print("類似度:", round(dot / (length_a * length_b), 2))
# b を [6, 8] に変えて実行してください。向きは同じです。
よくある間違い
注意
内積が大きいほど似ていると考えがちです。長い文章は数が大きいので、似ていなくても内積が大きくなります。長さで割ったコサイン類似度で比べます。
さらに挑戦: いちばん似た問い合わせ
自分で5つの短い問い合わせを書き、ベクトルにしてください。ほかの4つの中から、最も似た1つを探します。
重みを回数からTF-IDFに変えると、答えは変わりますか。自分の言葉で、なぜ変わったかを説明しましょう。