68
35

More than 3 years have passed since last update.

結局、Embeddingって何者?

Posted at

はじめに

深層学習を用いた自然言語処理に触れると、
Embeddingとかいう耳慣れないヤツに遭遇します。

日本語に直訳すると 埋め込み です。
time_cupsule_kids_30.png

まるで意味が解らんぞ
よくわからないので調べました。

どんな操作?

自然言語を計算が可能な形に変換することをEmbeddingと呼ぶようです。
多くの場合、単語や文章等をベクトル表現に変換する操作のことを指しています。

なんのため?

大きく分けると二つ理由があります。

1. コンピュータが処理できるようにするため

基本的に現在の機械学習アルゴリズムは、文字列型を処理できるように作られていません。
そのため、計算可能な形に変換する必要があります。

2. 変換方法次第で精度の向上が見込めるため

また、単に計算可能な形にするだけでなく、ベクトルの表現方法を工夫することで
単語や文章の特徴をベクトルに表現できるようになります。

たとえば、近い意味の単語同士を近いベクトルとなるように変換することで、
ベクトルの距離や類似度で、単語の意味(っぽいもの)を表せるようになるようになります。

とりあえず動かしてみる

それっぽく書いてみましたが、動かさないと実感がわかないのでコードを書いてみます。

使用技術

実装が簡単な、gensimというライブラリのWord2Vecで埋め込んでみます。
以下の事前学習済みモデルをそのまま利用させていただきました。

※2017年2月1日版 日本語 Wikipedia エンティティベクトル©Masatoshi Suzuki
http://www.cl.ecei.tohoku.ac.jp/~m-suzuki/jawiki_vector/

いろいろ埋め込んでみる

とりあえず、"おはよう"、"こんばんは"を埋め込んでみます。
※諸々の処理はコードを確認してください。

print(model["おはよう"])

# [ 0.36222297 -0.5308175   0.97112703 -0.50114137 -0.41576928  1.7538059
#  -0.17550747 -0.95748925 -0.9604152  -0.0804095  -1.160322    0.22136442
# ...

print(model["こんばんは"])

# [-0.13505702 -0.11360763  0.00522657 -0.01382224  0.03126004  0.14911242
#   0.02867801 -0.02347831 -0.06687803 -0.13018233 -0.01413341  0.07728481
# ...

文字列がベクトルに変換されていることが確認できます。

。。。だから何だ、と言われた気がしたので意味を表現できているのか確認してみます。

類似度を確認してみる

文書の類似度を計算するときによく使われるコサイン類似度を見てみます。
ちなみにコサイン類似度は0から1の間で表現され、1に近いほど類似します。

まずは、先ほどの"おはよう"と"こんばんは"の類似度を見てみます。

print(cos_similarity(model["おはよう"],model["こんばんは"]))
# 0.8513177

スコアが0.85...と出てきました。
まあまあ近いように思えます。

今度は単語の意味が遠いものとの類似度を見てみます。


print(cos_similarity(model["おはよう"],model["ひじき"]))
# 0.17866151

スコアが0.17...でした。
"おはよう"と"ひじき"は遠いと言えそうです。

体感的にも、ベクトルに意味を持たせられていそうです。

おわりに

Embeddingについてイメージくらいは掴めた様な気になりました。
少し前にバズったBERTのEmbeddingがすごくいいと聞いたので、試してみようと思います。

コード

import numpy as np
import gensim

# モデルの読み込み
model_path = "entity_vector/entity_vector.model.bin"
model = gensim.models.KeyedVectors.load_word2vec_format(model_path, binary=True)

# コサイン類似度
def cos_similarity(a,b):
    return np.dot(a,b) / ((np.sqrt(np.dot(a,a))) * (np.sqrt(np.dot(b,b))))

print(model["おはよう"])
print(model["こんばんは"])

print(cos_similarity(model["おはよう"],model["こんばんは"]))
print(cos_similarity(model["おはよう"],model["ひじき"]))

68
35
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
68
35