米googleの研究者が開発したWord2Vecで自然言語処理(独自データ)

  • 544
    いいね
  • 3
    コメント
この記事は最終更新日から1年以上が経過しています。

w2v.png
w2v_logo.png

「Word2Vec」は、米グーグルの研究者であるトマス・ミコロフ氏らが提案した手法であり、いくつかの問題について従来のアルゴリズムよりも飛躍的な精度向上を可能にした自然言語処理の手法。

Word2Vecは、その名前の表す通り、単語をベクトル化して表現するする定量化手法である。例えば日本人が日常的に使う語彙数は数万から数十万といわれるが、Word2Vecでは各単語を200次元くらいの空間内におけるベクトルとして表現する。

その結果、今まで分からなかったり精度を向上するのが難しかった単語同士の類似度や、単語間での加算・減算などができるようになり、単語の「意味」を捉えられるようになった。

というわけで、かなり興味深いないようなので、早速実践してみることにします。

1.環境構築

subversionを使ってWord2Vecのソースコードをcheckoutする。

mkdir ~/word2vec_test
cd ~/word2vec_test
svn checkout http://word2vec.googlecode.com/svn/trunk/
cd trunk
make
#word2vecのインストールが完了

2.とりあえずテストデータで試してみる

cd trunc
./demo-word.sh

を実行すると、テストデータでのトレーニングを開始します。

2-1.トレーニングが終わったら、使ってみる

トレーニングが終わると入力画面になるので、「cat」とか「dog」などの単語を入力してみてください。

実際に「cat」と入力した時の出力結果は以下。

cats        0.603425
feline      0.583455
kitten      0.569622
meow        0.565481
purebred    0.558347
dog         0.545779

3.独自の数十万人のfacebook投稿データで試してみる(こっからが本番!)

facebookの投稿データをcsvに書き出す。(fb_post_for_word2vec.csv)
投稿時のメッセージを1列目、リンクタイトル2列目に挿入してファイルを生成する。

生成したファイルをMeCabで解析して単語のテキストファイル(fb_word_for_word2vec.txt)を作る。
※MeCabの辞書データはデフォルトの辞書に、はてブ、wikipediaの名詞の単語を事前に登録しておく。
参照:http://qiita.com/ysk_1031/items/2ebdfefbca7c01d19ac0

3-1.MeCabを使ってデータを生成する

# -*- coding: utf-8 -*-
import csv
import MeCab
import re
tagger = MeCab.Tagger('-Owakati')
fo = file('fb_word_for_word2vec.txt','w')
for line in csv.reader(open("fb_post_for_word2vec.csv","rU")):
  if len(line) == 2:
    line = line[0] + line[1]
  elif len(line) == 1:
    line = line[0]
  else:
    continue
  line = re.sub('http?://.*','', line)
  fo.write(tagger.parse(line))
fo.close()

3-2.生成したtxtファイルを読み込んでトレーニングさせる

#terminal
time ./word2vec -train fb_post_for_word2vec.txt -output fb_post.bin -cbow 0 -size 200 -window 5 -negative 0 -hs 1 -sample 1e-3 -binary 1

3-3.トレーニングが終わったら使ってみる

#terminal
#単語との類似度が高い順に単語を取得したいとき
./distance fb_post.bin

#とある方程式に単語ベクトルを代入して結果を取得したいとき
./word-analogy fb_post.bin

と実行すると、入力画面になります。

3-3-1.ある単語に似た単語と度合いを抽出(distanceの方)

ある単語を入力すると、似ている単語を上位から出してくれる。

ruby
⇒
rails       0.726545
js          0.719732
rbenv       0.715303
javascript  0.685051
gem         0.684497
python      0.677852
scala       0.672012
#見事にrailsがトップで、その後オブジェクト指向言語やgemなどがランクインしてます。

docker
⇒
apache      0.672672
jenkins     0.668232
ruby        0.661645
redis       0.653154
Vagrant     0.645885
rbenv       0.643476
#ちゃんとインフラとか開発環境系が増えてますね。

半沢
⇒
大和田常務     0.794253
折り合い       0.655206
挟ま          0.634274
半沢直樹       0.632742
野々村        0.630198
激情          0.604290
パロディ       0.490672
県議          0.472910

3-3-2.単語の加算・減算をして遊んでみる(ここ、面白いよ:word-analogyの方)

単語を3つ「A B C」と入力すると、A⇒Bならば、C⇒?という出力を返してくれる。
ベクトルなので、A-B+Cという計算をしているみたいですね。

実際にやってみると面白いw

イチロー - 野球 + 本田
⇒
サッカー        0.612238
初戦           0.588327
バスケ          0.562973
ラグビー        0.543752
大学野球        0.537109
横浜高校        0.536245
練習試合        0.535091

日本 - 東京 + フランス
⇒
札幌          0.569258
パリ          0.566437
ミラノ        0.560036
ロンドン       0.552840
大阪          0.541102
ヴェネツィア    0.540721

ご飯 - 卵 + そば
⇒
鶏        0.686967
ネギ      0.670782
塩        0.663107
味噌      0.654149
魚粉      0.648807
海老      0.648329

4.その他にもできること

  • 単語だけでなくフレーズ間の類似度を算出
  • 単語のクラスタリング

まとめ

単語をベクトルで表現できるということは、あらゆるものの関係性を表すことが可能になるということに近い意味を持ちます。

人と人、画像と画像、地域と地域、モノとモノ、人とモノなど言葉で説明できるものはほぼすべて、200次元の空間上にプロットができるようになるということ。

精度を高めていく努力は必要ですが、活用方法を考えて価値あることに活かせそうなにおいがプンプンしますね!