5
5

More than 5 years have passed since last update.

単語ベクトルのコサイン類似度行列を簡単に求める

Last updated at Posted at 2018-11-07

はじめに

word2vecfasttextなどで得られた単語ベクトルから類似度の高い単語をランキングする際に,コサイン類似度の行列があれば楽そうなので勉強がてら実装してみた.

参考

コサイン類似度とは

2つのベクトルのなす角θのコサインの値を求めている.

\cos{(\vec{p},\vec{q})}= \frac{\vec{p} \vec{q}}{|\vec{p}| |\vec{q}|} = \frac{|\vec{p}| |\vec{q}|}{|\vec{p}| |\vec{q}|} \cos\theta = \cos\theta

コード

単語ベクトルのコサイン類似度の行列を計算する関数.単位ベクトルに正規化した後に,全ての単語の組み合わせの内積を計算してコサイン類似度を計算している..

import numpy as np
def cosine_similarity_matrix (vectors):
    unit_vectors = vectors / np.linalg.norm(vectors, axis=1, keepdims=True)
    return np.matmul(unit_vectors, unit_vectors.T)

実行例

コサイン類似度が高い順に単語を出力する例.

import numpy as np
import pandas as pd

# 10,000語の単語とベクトル(256次元)
words = ['word_{}'.format(i) for i in range(10000)]
vectors = np.random.rand(10000, 256)

# コサイン類似度行列を計算
matrix = cosine_similarity_matrix(vectors)
df = pd.DataFrame(matrix, index=words, columns=words)

# word_1と類似度が高い順に単語を出力
result = df['word_1'].sort_values(ascending=False).drop(index='word_1')
print(result)

# word_6049    0.809170
# word_7033    0.808725
# word_8884    0.805947
# word_6607    0.805759
# word_8257    0.805468
# word_1865    0.805220
# word_5849    0.805014
# word_4910    0.804502
# word_4079    0.804210
# word_6249    0.803592
# ...

さいごに

コサイン類似度は2つのベクトルの成す角のみを考慮しているが,ベクトルの大きさは関係ないのだろうか?と疑問に思った.今後時間があるときに実際に単語ベクトルを求めて適用してみようと思う.

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5