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

![w2v.png](https://qiita-image-store.s3.amazonaws.com/0/1418/f12c359b-c5bd-6aac-8a72-1c011d362650.png)
![w2v_logo.png](https://qiita-image-store.s3.amazonaws.com/0/1418/9a57d061-720d-8e0f-7e3a-c3e0eac96d49.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の方)

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

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

    イチロー - 野球 + 本田
    ⇒
	サッカー		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次元の空間上にプロットができるようになるということ。

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