はじめに
以前、ベイジアンフィルタを実装して自然言語処理に興味を持ち始めたので、とりあえず「king - man + woman = queen」で有名になった「Word2Vec」を動かしてみたいと思った次第です。
yaju3d.hatenablog.jp
Word2Vecとは
Word2Vecは米グーグルの研究者であるトマス・ミコロフ氏らが提案した機械学習の分野で使われる、ニューラルネットというモデルを使ったツール/ライブラリです。名前の通り、word(単語)をvector(ベクトル)に変換します。
この技術をベースに、「単語」だけではなく「文書」にも意味を持たせてベクトルとして捉えて利用できる技術「Doc2Vec」も作成されました。
ベクトルは1行m列やn行1列のこと、または「大きさと向き」を持つ量のことです。単語を文字列としているだけでは分類することは出来ないので何かしら意味のある数値にするわけです。こうすることでベクトル同士の足し算・引き算・コサイン類似度などを計算できるようになり、有名になった「king(王様) - man(男) + woman(女性) = queen(女王)」ということが可能になるわけです。
他にも「東京 - 日本 + フランス = パリ」となるという例もあり、これは「首都」であるという関連情報が上位にあるからです。
単語をベクトル表現する方法は「word2vec」以前にもあったのですが、類似度の特徴を満たしていたものの足したり引いたりといった操作までは出来ませんでした。なので、「word2vec」が発表された時は一般には衝撃的だったのです。
ベクトル空間モデル
word2vec以外で基本的なベクトル空間モデルを2点を列挙します。
BoW(Bag of Words)モデル
テキストデータを単語ごとの出現回数だけで表す方法です。ちなみに、bagは多重集合(multiset)の別名とのこと。
単語の出現順は考慮しないため。「彼女と僕」と「僕と彼女」は同じベクトルになる。
N-gramモデル
テキストデータをN文字単位で文字列を分解して表す方法です。
「彼女と僕」→ 彼女、彼女と、と僕、僕
「僕と彼女」→ 僕、僕と、と彼女、彼女
N-gramモデルでは、隣り合った文字列または単語の組み合わせを「共起関係」と呼びます。
また、「共起関係」がどの程度現れるかを集計した結果を「共起頻度」と呼びます。
実装環境
Pythonは、Docker上のTensorFlowで構築した環境を使用しています。
参照:WindowsユーザーがTensorFlowをインストールしてみた(Docker版) - デジタル・デザイン・ラボラトリーな日々
環境
- Docker
- Jupyter
- Python 2.7
- Word2Vec 0.9.1
- CPython 0.25.1
Word2Vecのインストール
Word2Vecをインストールしたら「ImportError: No module named Cython.Build」とエラーになりましたので、先に「Cython」をインストールします。
※Word2Vecは、Pythonから扱える自然言語処理ライブラリ(Gensim)に含まれているのですが、今回はGensimを使わない方法にしました。
※pipはアップグレードしておいただけです。
# pip install --upgrade pip ︙ Successfully installed pip-9.0.1 # pip install Cython ︙ Successfully installed Cython-0.25.1 # pip install word2vec ︙ Successfully installed word2vec-0.9.1
Word2Vecを試す
下記のword2vecのexamplesサイトを試しに動かしてみます。 http://nbviewer.jupyter.org/github/danielfrg/word2vec/blob/master/examples/word2vec.ipynb
text8.zipのダウンロードと解凍
Word2Vecのデモ用としてtext8という100MB程のコーパスのデータが用意されていますので、ダウンロードして解凍します。
wgetコマンドが無かったので、curlコマンドを使用します。
# curl http://mattmahoney.net/dc/text8.zip > text8.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 29.8M 100 29.8M 0 0 497k 0 0:01:01 0:01:01 --:--:-- 396k # gzip -d text8.gz -f
Jupyter Notebook
Inの番号が飛んでいるのはミスしたからで意味はありません。 examplesサイトではtext8の格納フォルダ「/Users/drodriguez/Downloads/」になっていますが、自分はカレントフォルダに格納したのでフォルダは付けていません。
「king - man + woman」の部分
indexes, metrics = model.analogy(pos=['king', 'woman'], neg=['man'], n=10) indexes, metrics model.generate_response(indexes, metrics).tolist()
結果として、「queen」が先頭になっています。
[(u'queen', 0.2905402467729655), (u'empress', 0.2734506828577926), (u'prince', 0.2709167973829251), (u'wife', 0.2679356346054478), (u'monarch', 0.26728773557223445), (u'son', 0.2666904115522106), (u'throne', 0.2657155461401751), (u'regent', 0.26416170868397304), (u'pope', 0.2637096213206423), (u'pharaoh', 0.2619265026976325)]
最後に
Word2Vecをインストールして英語用のデモを試して雰囲気を楽しんだだけでしたが、次回は日本語を使っていろいろ試してみたいと思います。
今回初めて、GitHub Gistを使ってブログにJupyter Notebookを表示してみました。これ結構いけますね。
参照
- Gensimを使わないで、Pythonでword2vecを使う
- 畳み込みニューラルネットワークによるテキスト分類を TensorFlow で実装する
- Word2Vecの進化形Doc2Vecで文章と文章の類似度を算出する
- Ubuntu マシンで、Python 2.7 をつかって word2vec 解析をやってみた
- Word2VecをPythonでやってみる
- 青空文庫のデータを使って、遅ればせながらword2vecと戯れてみた
- Gensimを使ったWord2vec
- Word2Vecを試す (3)|日販コンピュータテクノロジイ株式会社(NCT)
- 義理といえば?クックパッドのレシピをword2vecで料理してみた
- GitHub Gistを使ってブログにJupyter(IPython) Notebookを表示する方法