関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
<< テキストアノテーションツール brat がすごい件 | main | Solrを使って専門用語抽出 >>
word2vec for Lucene ご紹介

Luceneインデックスをコーパスとみなして動作する word2vec for Lucene を開発したのでその使い方を紹介しよう。word2vec は Tomas Mikolov らによって提案/開発された単語をベクトルに変換するOSSツールである。オリジナルの word2vec は自然言語で書かれたテキストファイルを読み込み、単語ベクトルを出力するようになっている。

word2vec for Lucene はテキストファイルの代わりにLuceneインデックスを入力コーパスとして用いる。オリジナルの word2vec が扱うテキストファイルは単語単位で分かち書きされている必要がある。この点は英語テキストなどでは問題ないが、単語で分かち書きされていない日本語などではあらかじめMeCabなどの形態素解析器や分かち書きツールを用いて単語で分かち書きされたテキストファイルを用意しておかなければならない。また英語であっても大文字→小文字変換や単語テキストの直後に続くピリオド/カンマの削除など、事前の正規化作業が必要になってくる。word2vec for Lucene では Luceneインデックスを入力コーパスとして用いるため、事前の正規化作業が不要である。

以下では簡単に試していただけるよう、word2vec for Lucene のデモを実行する手順を説明する。大まかな手順は:

1.word2vec for Lucene のダウンロード
2.デモデータの準備
3.Lucene/Solrインデックスの準備(デモデータの登録)
4.単語ベクトルの作成
5.単語ベクトルで遊ぶ

という感じである。すでにLuceneインデックスを持っている方は手順2〜3の代わりに手持ちのLuceneインデックスを手順4で指定することにしてもよい。word2vec for LuceneはLucene 4.10.2ベースで作成したが、(試していないが)たいていのLucene 4.x インデックスで動作するものと思われる。したがって、Solr 4.x はもちろんのこと、Elasticsearch(バージョンはよく知らないが1.x系以降)で作成したインデックスも指定できる。

手順5で楽しい結果を得るためにはそれなりに大きなコーパスが必要である。数百万文書など大きなLuceneインデックスを持っている方はぜひ word2vec for Lucene を試していただきたい。

以下手順を示すが、簡単のために /Users/koji/work ディレクトリ以下に Solr 環境と word2vec for Lucene 環境をインストールする想定で話を進める。

手順1.word2vec for Lucene のダウンロード
$ pwd
/Users/koji/work
$ git clone https://github.com/kojisekig/word2vec-lucene.git
手順2.デモデータの準備
$ pwd
/Users/koji/work
$ cd word2vec-lucene
# オリジナルの word2vec でも使用されている英語コーパス text8 をダウンロードして Solr 形式に変換
$ ant t8-solr
$ ls -l text8*
-rw-r--r--  1 koji  staff  100000000  6  9  2006 text8
-rw-r--r--  1 koji  staff  100017005 12  3 13:44 text8.txt
-rw-r--r--  1 koji  staff  100017078 12  3 13:44 text8.xml
-rw-r--r--  1 koji  staff   31344016 12  3 13:40 text8.zip
手順3.Lucene/Solrインデックスの準備(デモデータの登録)

コンソールを2つ用意して最初のコンソールでSolrを起動する。

$ pwd
/Users/koji/work

# Solrのダウンロード
$ wget http://ftp.meisei-u.ac.jp/mirror/apache/dist/lucene/solr/4.10.2/solr-4.10.2.tgz
$ tar xvzf solr-4.10.2.tgz

# Solrの起動
$ cd solr-4.10.2/example
$ java -Dsolr.solr.home=/Users/koji/work/word2vec-lucene/solrhome -Dsolr.dir=/Users/koji/word/solr-4.10.2 -jar start.jar

2つめのコンソールではtext8コーパスをSolrに登録する。

$ pwd
/Users/koji/work
$ cd word2vec-lucene
# Solr形式に変換した英語コーパスをSolrに登録
$ ./post.sh collection1 text8.xml
手順4.単語ベクトルの作成

demo-word2vec.sh スクリプトにSolrコア名を指定してword2vecを実行する。実行結果はvectors.txtというファイルに出力される。

$ pwd
/Users/koji/work
$ cd word2vec-lucene
$ ./demo-word2vec.sh collection1
$ ls -l vectors.txt 
-rw-r--r--  1 koji  staff  136053041 12  3 15:31 vectors.txt
手順5.単語ベクトルで遊ぶ

demo-distance.sh を実行するとvectors.txtファイルを読み込んで入力待ちになる。そこで単語を入力すると、その単語に最も近い(コサインを計算)ベクトルを持つ単語上位40個を表示する。

$ ./demo-distance.sh
cat
Word: cat
Position in vocabulary: 2601

                                              Word      Cosine distance
------------------------------------------------------------------------
                                              cats		0.511078
                                               dog		0.471308
                                              dogs		0.469539
                                        sighthound		0.452233
                                           bobtail		0.436424
                                             tapir		0.424105

demo-analogy.sh を実行するとvectors.txtファイルを読み込んで入力待ちになるので、3つの単語をスペース区切りで入力する。以下ではman king womanと入力しているが、「manに対するkingの関係を、womanに適用するとどうなるか」という意味である。するとqueenが期待値になるが、実行結果もそのようになる。

$ ./demo-analogy.sh
man king woman
日本語で試す場合

以上の手順はオリジナルの word2vec でも使用している text8 という英語の正規化済みのコーパスを使った手順であるが、以下では日本語の(正規化済みでない)コーパスを使った手順も紹介しよう。デモデータは livedoor ニュースコーパスを用いる。ロンウイットのサイトから Solr ネイティブ形式に加工した livedoor ニュースコーパスをダウンロードする。

$ pwd
/Users/koji/work
$ cd word2vec-lucene
$ mkdir work
$ cd work
$ pwd
/Users/koji/work/word2vec-lucene/work
$ wget http://www.rondhuit.com/download/livedoor-news-data.tar.gz
$ tar xvzf livedoor-news-data.tar.gz
$ cd ..

ダウンロードした livedoorニュースコーパスをSolrに登録し、word2vecを実行する。コア名にはldccを指定する。また、-aオプションでLuceneのAnalyzerクラスを指定する。また以下では-fオプションで出力先ベクトルファイル名を指定している(指定しないとデフォルトのvectors.txtとなってしまい、先ほど作成した英語の単語ベクトルファイルを上書きしてしまう)。

$ ./post.sh ldcc work/*.xml
$ ./demo-word2vec.sh ldcc -a org.apache.lucene.analysis.ja.JapaneseAnalyzer -f vectors-ldcc.txt
$ ./demo-distance.sh -f vectors-ldcc.txt
結婚
野球
デモデータ以外のLuceneインデックスで試す場合の注意点

word2vec for Lucene で配布しているデモ実行スクリプト demo-word2vec.sh を見てもらうとわかるように、いくつかのパラメータがハードコーディングで指定されている。以下はLuceneに関連するパラメータである。これを手持ちのLuceneインデックスに合うように適宜指定しなおせばLucene 4.x インデックスのデータでword2vecが動くはずである。

オプション説明
-indexLuceneインデックスのディレクトリを指定する。
-fieldword2vec を実行するLuceneインデックスのフィールド名を指定する。このフィールドはindexedでかつstoredでなければならない。
-analyzer-fieldオプションで指定されたフィールドのstoredデータをここで指定されたLuceneのAnalyzerクラスでanalyzeする。

-analyzer オプションについては、storedデータではなくTermVectorでもよかったのだが、TermVectorを保存しているLuceneインデックスは少なく、処理速度的にも疑問だったため、storedデータをここで指定するLuceneのAnalyzerクラスでanalyze する方針をとった。ではなぜindexedでなければいけないかというと、(オリジナル実装でも)word2vecではコーパスを2度読んでいて、1回目の読み込みで単語表を作成しているが、indexedであればそこは一瞬で完了し、なんといってもLuceneっぽいからである。また、word2vecで解析したくなるようなLuceneフィールドはたいていindexedでかつstoredと考えられるので、多くのLuceneインデックスオーナーにはこの条件は受け入れられるはずである。

相当数の文書が入っているLuceneインデックスを持っている方は、デモデータで動作を確認したあと、ぜひword2vec for Luceneを手持ちのLuceneインデックス上で試していただき、どんな結果になったか教えていただければありがたい。

| 関口宏司 | NLP | 09:00 | comments(0) | trackbacks(0) |









http://lucene.jugem.jp/trackback/479
+ Solrによるブログ内検索
+ PROFILE
   1234
567891011
12131415161718
19202122232425
262728    
<< February 2017 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Apache Solr入門 ―オープンソース全文検索エンジン
Apache Solr入門 ―オープンソース全文検索エンジン (JUGEMレビュー »)
関口 宏司,三部 靖夫,武田 光平,中野 猛,大谷 純
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ SPONSORED LINKS