Open4

NLPを学ぶ-分散表現(Word Embedding)

nabetsunabetsu

Word2Vec

分散表現の作成

学習済みのモデルを利用することもできるが、自分で一からモデルを作成することもできる。
具体的な手順は以下の通り。

1行1文のテキストファイルを分かち書きした結果をファイルに出力

!mecab -Owakati data.txt > wakati.txt

word2vecを使って分散表現を作成。

from gensim.models import word2vec
from gensim.models import Word2Vec

sens = word2vec.LineSentence('wakati.txt')
model = Word2Vec(sens)

後は学習済みモデルを読み込んだ時と同様に使える。

model.similar_by_vector(model['風'])
>>>
[('風', 1.0000001192092896),
 ('、', 0.2056608945131302),
 ('月', 0.17457306385040283),
 ('名称', 0.170188307762146),
 ('宮崎', 0.1565951406955719),
 ('年', 0.15307378768920898),
 ('万', 0.15031349658966064),
 ('。', 0.1447315365076065),
 ('注', 0.13913729786872864),
 ('映画', 0.12678080797195435)]

作成したモデルはsaveメソッド、loadメソッドで保存、読み込みができる

# save
model.save('sample.bin')

# load
model = Word2Vec.load('sample.bin')

既存の分散表現の読み込み

モデルのダウンロード

# Google Driveをマウント
from google.colab import drive 
drive.mount('/content/drive')

# 日本語 Wikipedia エンティティベクトルをダウンロード
!wget -P "/content/drive/My Drive/download" http://www.cl.ecei.tohoku.ac.jp/~m-suzuki/jawiki_vector/data/20170201.tar.bz2

# ダウンロードしたファイルを解凍
!tar -jxvf /content/drive/My Drive/download/20170201.tar.bz2

モデルの利用

解凍して作成された2ファイルの内、binファイルをgensimで読み込む。

読み込みができたら後はgensimのコマンドが通常通り使える。

from gensim.models.keyedvectors import KeyedVectors

model = KeyedVectors.load_word2vec_format(
    'drive/My Drive/download/entity_vector/entity_vector.model.bin',
    binary=True
)

model.most_similar('犬', topn=5)
>>>
[('[犬]', 0.8519492149353027),
 ('[イヌ]', 0.8118769526481628),
 ('[ネコ]', 0.7639949917793274),
 ('[猫]', 0.7535459995269775),
 ('猟犬', 0.7513321042060852)]

nabetsunabetsu

ニューラルネットワーク

Word Embedding

分散表現とは単語をベクトルで表現した際のベクトルのこと。
ベクトルがn次元である場合に、単語をn次元空間のある1点に埋め込むことを意味するため、埋め込み表現(Word Embedding)とも呼ばれる。

とは単語を実数値の特徴ベクトルに変換する手法全般のことを指す。

  • BoWの考え方
    • 文章を語彙数に等しい次元の数のOne-hot Encodingで表現する(対応する単語は1、それ以外は0で表現する)
    • ベクトルとしての特徴は高次元疎で、要素の値が非負であること
    • 単語が増えると次元数が増加する
    • ベクトル間での演算ができない
  • Word Emenedding
    • (設計者が設定した)特定の次元数で全ての次元の値が何らかの実数値となるベクトルを生成する
    • Word Embeddingによって得られたこのベクトルを単語の分散表現(distributed representation)と呼ぶ
    • 単語が増えても次元数は変わらない
    • ベクトル間で演算が可能
# BoW
[0, 0, 0, 1, 0, 1, 1, ..., 0, 1]  

# Word Embedding

[-0.421, 0.121, 0.131, ..., -0.121, 2.532, 0.121]

実装

gensimというライブラリを使用して簡単に試すことができる。

インストールはpipで行える。

pip install gensim

Word Embeddingでは学習済みモデルを利用することが可能であり、ここではgensimの機能を使って学習済みモデルをダウンロードして、それを使ってWord Embeddingに触れてみる。

import gensim.downloader as api

model = api.load('glove-wiki-gigaword-50')

tokyo = model['tokyo']
japan = model['japan']
france = model['france']

# tokyoという単語の意味からjapanを引いて、franceを足す
v = tokyo - japan + france

print('tokyo - japan + france = ',
      model.wv.similar_by_vector(v, topn=1)[0]) # tokyo - japan + france =  ('paris', 0.9174968004226685)

何次元のベクトルで表現するかはモデルにより異なるが、このモデルでは50次元のベクトルとして表現されており、単語名をキーとして指定することで特徴ベクトルにアクセスできる。

model['tokyo']
>>>
array([-0.31168  ,  0.19471  ,  0.19075  ,  0.68413  ,  0.29163  ,
       -0.8988   ,  0.22633  ,  0.17832  , -1.4774   , -0.091882 ,
        0.089789 , -0.94473  , -0.19385  ,  0.58078  ,  0.20208  ,
        0.9924   , -1.0311   ,  0.42467  , -1.142    ,  0.71974  ,
        2.1561   , -0.14197  , -0.92983  , -0.28101  , -0.011046 ,
       -1.6787   ,  0.44449  ,  0.54703  , -0.71357  , -0.67743  ,
        2.3393   ,  0.28577  ,  1.4062   , -0.0078203, -0.15283  ,
       -1.1147   ,  0.2415   , -0.65908  , -0.044945 ,  0.046839 ,
       -1.1396   , -0.44836  ,  0.91807  , -0.74048  ,  1.0508   ,
        0.052699 ,  0.13431  ,  0.62261  ,  0.61384  , -0.097283 ],
      dtype=float32)

最初の例ではtopnを指定することで最も近い単語のみを表示したが、指定しなければ類似度が高い順で10個の単語が表示される。

tokyo = model['tokyo']
print(model.similar_by_vector(tokyo))

[('tokyo', 1.0), ('osaka', 0.8219321966171265), ('seoul', 0.8158921003341675), ('japan', 0.8078721165657043), ('shanghai', 0.7954350113868713), ('japanese', 0.7557870745658875), ('yen', 0.731688916683197), ('singapore', 0.7233644127845764), ('beijing', 0.7195608019828796), ('taipei', 0.7153447270393372)]

Word Embeddingの性質

  • ベクトルの足し算、引き算で意味の足し算、引き算を表現できる
  • 意味が近い単語の分散表現は、ベクトル空間の中で近くに分布する

つまり、word embeddingによって得られる単語の分散表現は単語の意味を表現したベクトルだと言える

Word Embeddingの種類

  • Word2Vec
    • 2013年にGoogleのTomas Mikolovらが発表したもの。
  • GloVe
    • Word2Vecの翌年に発表されたモデル。文章中の連続する数単語に着目するWord2Vecの手法では学習データ全体の統計情報を使うことが出来なかった。GloVeはその課題を解決するため学習データ全体における単語の共起頻度を利用する。
  • fastText
    • Facebook AI Reseearchから発表されたもの。文字n-gramの分散表現を得て、それらを足しあわせて単語の分散表現とする手法。文字n-gramベースなので単語の活用や表記ゆれに強い、未知語に強いなどの特徴がある。

学習済みモデルの利用と日本語対応

Word Embeddingの入口としてはGensimから学習済みモデルを簡単に利用できる。

一方で、日本語対応されたものは提供されていないが、個人やGensim以外の組織から日本語の学習済みモデルが提供されており、利用することができる。

日本語学習済みモデル