MacPortsでword2vec:マルチスレッド改善のC実装+Python3対応のgensim

深層学習手法で用いられる単語のベクトル表現を求めて、構文的もしくは内容的な意味の演算が高い精度でできるword2vecは、実装が公開されて様々なテキストに対して手軽に試せることもあって大変注目を集めています。公開されているコードはLinux用ですが、少しバッチをあてることでMacでもビルドできます。さらに、マルチスレッドで効率的に学習するためのパッチも公開されています:
Word2vecの並列実行時の学習速度の改善

word2vecはMacPortsになっているので、インストールしてサンプルを試すことができます:

$ sudo port selfupdate
$ sudo port install word2vec
$ /opt/local/libexec/word2vec/demo-word.sh 
Enter word or sentence (EXIT to break): japan

Word: japan  Position in vocabulary: 582

                                              Word       Cosine distance
------------------------------------------------------------------------
                                             china		0.672656
                                             korea		0.595309
                                            taiwan		0.591563
                                           paekche		0.549183
                                          japanese		0.534286
                                          cambodia		0.529780
                                         singapore		0.527291
                                             india		0.524282
                                          thailand		0.521931
                                          malaysia		0.499453
                                           germany		0.490402
                                            russia		0.485997
                                            canada		0.482687
                                               prc		0.480759
                                          mongolia		0.476699
                                            taipei		0.476232
                                             tokyo		0.475686
                                          mainland		0.470766
                                           chinese		0.468477
                                         indonesia		0.466051
                                             nepal		0.465414
                                         australia		0.459817
                                       philippines		0.459496
                                        kazakhstan		0.459167
                                            brazil		0.454301
                                               jpy		0.453095
                                               eas		0.451895
                                            baekje		0.451650
                                              laos		0.451343
                                           grenada		0.434702
                                             burma		0.434447
                                          pakistan		0.432753
                                        kyrgyzstan		0.432098
                                         manchuria		0.430930
                                            france		0.430890
                                           jamaica		0.429333
                                              kong		0.427525
                                             macau		0.426827
                                              hong		0.426736
                                             asian		0.426563
Enter word or sentence (EXIT to break): 

実行ファイルやデモスクリプトは、/opt/local/libexec/word2vec/にインストールされます。

また、Pythonで実装されたgensimパッケージでword2vecを使うこともできます。gensimのバージョン0.10.0からはPython2だけではなくPython3にも対応しています。このときCythonもインストールしておくと学習処理が格段に高速化されます:

$ sudo port install py34-gensim py34-cython

Mavericksに対応したJubatus 0.6.1のMacPorts

オンライン機械学習の分散処理フレームワークJubatusの最新バージョン0.6.1は、Mavericksのclangでビルドが可能になっていて、homebrewのFormulaが公開されています。このFormulaを参考にMacPortsのjubatusポートを更新してみました。MacPortsのポートを最新版に更新してjubatusをインストールすると、通常はバイナリがダウンロードされるので作業は比較的短時間で完了します。また、PythonのクライアントもMacPortsでインストールして利用できます。

$ sudo port selfupdate
$ sudo port install jubatus
$ sudo port install py27-jubatus-client

あとは、こちらのチュートリアルにしたがって試してみることができるでしょう。

brown-clusterをMavericksで動かす

brown-clusterは、単語をテキスト中に出現する傾向に基づいて機械的に分類するBrownらが提案したクラスタリングアルゴリズムC++実装です。Brownの単語クラスタリングの結果を機械学習の素性として利用すると、固有表現抽出や単語分割などのタスクで効果があることが知られています:

単語や文書をクラスタリングする際に広く用いられる LSA (Latent Semantic Analysis) や LDA (Latent Dirichlet Allocation) は、内容やトピックに基づく分類になりますが、Brownのクラスタリングは構文的に近い単語が集まります。Brownのアルゴリズムは階層的クラスタリングになっていて、すべての単語がそれぞれ一つのクラスタになっている状態から、テキスト中で隣り合わせにある単語に割り当てられたクラスタ相互情報量が最も大きくなるようにクラスタをまとめあげていきます。具体的な例を使ってアルゴリズムを分かりやすく解説しているCourseraのビデオがYouTubeにあります:
YouTube
YouTube
YouTube

さて、Mac OS XMavericksだと、XcodeでインストールしたC++コンパイラC++11規格に対応したClangになっています。brown-clusterのソースが参照しているTR1 ( C++ Technical Report 1) のライブラリが参照できないため、そのままではビルドできません。MavericksでのMacPortsの問題はメーリングリストTracに書かれていて、こちらのブログやportのチケットなどが対処するときの参考になります。2013/09/05にコミットされたbrown-cluster v1.3の場合、次のパッチをあてるとビルドできるようになります:

--- basic/std.h.orig	2013-09-05 23:57:03.000000000 +0900
+++ basic/std.h	2013-11-16 12:14:08.000000000 +0900
@@ -15,11 +15,18 @@
 #include <vector>
 #include <string>
 #include <queue>
+#if __cplusplus >= 201103L || defined(_LIBCPP_VERSION)
+#include <unordered_map>
+#include <unordered_set>
+#else
 #include <tr1/unordered_map>
 #include <tr1/unordered_set>
+#endif
 
 using namespace std;
+#if __cplusplus < 201103L && !defined(_LIBCPP_VERSION)
 using namespace std::tr1;
+#endif
 
 ////////////////////////////////////////////////////////////
 

brown-clusterはMacPortsに登録されていて、日本語に対してもMeCabなどを使って単語に分割すればBrownクラスタリングを試すことができます。たとえば前回の記事の内容をsample.txtに保存して、50個のクラスタに分割してみます:

$ sudo port self update
$ sudo port install brown-cluster mecab-utf8
$ mecab -Owakati sample.txt > sample.wakati
$ wcluster --text sample.wakati --c 50
$ cat sample-c50-p1.out/paths | head
000 / 28
0010 R 1
0010 doc 2
0010 examples 2
0010 opt 4
0010 scfg 4
0010 share 4
0010 local 4
0011 短縮 1
0011 GIZA 1

階層的クラスタリングの結果は、0と1のビット列で表現されています。機械学習の素性には途中の何ビットまでかで区切った値が使われるようです。

なお、MavericksBuildbotがいよいよ稼働しました。これからバイナリのパッケージが揃っていくことになります。

統計的機械翻訳ツールキットcicada

機械的にことばの意味を汲み取って別の言語で表現する機械翻訳は、人工知能自然言語処理が目指す究極の目標の一つとされて、古くから研究されてきました。近年では、大量の対訳データに基づいて統計的な言語モデル機械学習アルゴリズムを利用する統計的機械翻訳が主流です。単語や句の単位で二カ国語を対応させる比較的表層的で頑健な方法から、文の構文的な関係が表現された構文解析木や、複数の構文解析木をコンパクトに表現した構文解析森の状態から変換規則を求めるような、文法を利用した高度な方法まで様々提案されています。統計的機械翻訳の手法は、たとえ同じ言語であっても、たとえば話し言葉から書き言葉に変換するといった言い換えの用途にも利用できます。

統計的機械翻訳システムのオープンソースとしてはMosesが有名ですが、cicadaは最新の研究成果が様々盛り込まれていながら、とてもまとまりがあって使い勝手の良い実装です。付属ドキュメントも充実していて、作者のホームページに載っている統計的機械翻訳のチュートリアル資料も大変参考になります。

cicadaはMacPortsからインストールすることができます。ソースコードからビルドすると相当待たされますが、現時点でBiuldbotが用意されているMountain LionまでのOSであれば、バイナリを取ってくるのでインストール時間はかなり短縮できます。近日中にMavericks用のBuildbotも動き出すようなので期待しましょう。

$ sudo port selfupdate
$ sudo port install cicada
$ /opt/local/share/examples/cicada/scfg/sample.sh

最後のコマンドは動作確認用で、あらかじめ用意されているモデルを使って中国語から英語に翻訳するサンプルのテストを実行しています。

京都フリー翻訳タスク (KFTT)には、日英翻訳のデータとMosesをベースとしたシステムが公開されていますが、cicadaの配布物の中にそのデータの一部がサンプルとして同梱されていて、モデルの学習から翻訳の実行と評価まで実際に試すことができます。サンプルのディレクトリをコピーして作業をしてみましょう:

$ mkdir samples
$ cd samples
$ cp -R /opt/local/share/examples/cicada/kftt.30k .
$ cd kftt.30k

実行する手順は /opt/local/share/doc/cicada/training.rst に書いてありますが、コマンドを実行するスクリプトがサンプルディレクトリにちゃんと置かれていて、そのまま使うことができます。ただし、重い処理になるので、搭載メモリの少ない非力なマシンでは辛くなるので実行しない方が良いでしょう…。

まず、(1) 単語を対応付けて、(2) 翻訳の文法モデルを作り、(3) 文字列ベースの言語モデルを求めます。そして、(4) モデルを組み合わせて良い結果を出すためにパラメータのチューニングを行います。あとは、(5) 翻訳を実行して、(6) 一般的な評価尺度のBLEUスコアで翻訳結果を評価します:

$ cd alignment && ./alignment.sh ...(1)
$ cd ../scfg/model && ./extract.sh && ./index.sh ...(2)
$ cd ../../ngram && ./expgram.sh ...(3)
$ cd ../scfg/tune && ./config.sh && cd ../../data && ./preprocess.sh && cd ../scfg/tune && tune.sh ...(4)
$ cd ../test && ./test.sh ...(5) (6)

構文解析を利用したモデルを学習する手順は /opt/local/share/doc/cicada/training-stsg.rst に書かれています。日本語に対してはCaboCha (cabocha) とMeCab (mecab-utf8)、英語にはStanford Parser (stanford-parser) を利用します。実行する前にMacPortsでこれらの解析器をインストールしておきます:

$ sudo port install cabocha stanford-parser

なお、MacPortsには、バージョンはやや古いですがMoses (mosesdecoder) や、GIZA++ (giza-pp)、IRSTLM (irstlm)、lader (lader)、MGIZA++ (mgizapp)、pialign (pialign) などの統計的機械学習に関連するportが登録されています。

高速実装CRFSuiteとベンチマーク

テキストから人名や地名など内容を特定するような箇所を取り出す固有表現抽出や、名詞句や動詞句などのようにかたまった単語の列を求めるチャンキング、単語の品詞を特定する形態素解析など、自然言語処理の様々なタスクでCRF(Conditional Random Fields)の機械学習アルゴリズムが利用されています。

CRFSuiteはCRFの学習とテスト実行を高速に行うオープンソースの実装で、CRF++と並んで広く利用されています。メモリ使用量を抑えるよりも処理を高速に行う実装を目指していて、効率的なオンライン学習のアルゴリズムであるAveraged PerceptronやPassive Aggressive、AROW (Adaptive Regularization Of Weight Vector)なども利用することができます。他のオープンソースと比較したベンチマークテストの結果を見ると、訓練時間が極端に短いことに驚かされます:

CRFSuiteの配布ソースコードにはこのベンチマークを実行するスクリプトが含まれています。比較対象はWapitisgdCRF++MALLETとCRFSuiteの旧バージョン(v0.11)です。先ほどのベンチマークの結果は2011年の時点でのものですが、他のソフトもそれぞれバージョンが更新されています。現時点で比較してみると結果はどうなるでしょうか?

MacPortsにはCRFSuiteの旧版を除いて上のソフトがすべてパッケージ化されています。CRFSuiteのベンチマークスクリプトもパス名などがパッケージに合わせて修正してあります。手元のマシンで実行してみましょう。まずは必要なパッケージをインストールして、解析対象のチャンキング用データをダウンロードします:

$ sudo port selfupdate
$ sudo port install crfsuite wapiti sgd crfpp mallet
$ mkdir bench
$ cd bench
$ curl -O http://www.cnts.ua.ac.be/conll2000/chunking/train.txt.gz
$ curl -O http://www.cnts.ua.ac.be/conll2000/chunking/test.txt.gz
$ gunzip train.txt.gz test.txt.gz
$ /opt/local/share/examples/crfsuite/bench/collect.py

…段々とマシンの反応が鈍くなってきました。ベンチマークページの実験環境を見ると、64GBのメモリを積んだマシンで実行していますね! 手元のMac miniはメモリが4GBなので、とりあえず処理は途中で止めておくことにしましょうか…

CRFSuiteにはサンプルとして、チャンキング、品詞タグ付け、固有表現抽出といったタスク向けにCRFの素性を生成するスクリプトが同梱されています。チュートリアルにしたがって、公開されているタスク用のデータから素性ファイルを作成して、CRFの学習とテスト実行ができるようになっています。

多機能で洗練されたテキストアノテーションツールbrat

brat (brat rapid annotation tool)は固有名・イベント抽出、共参照解析、チャンキング、構文解析などの様々なタスクに利用できるテキストアノテーションを表示・編集するツールです。数多くの機能を備えていて、右の画面のように表示が美しく、操作もマウスを使って直観的に行うことができ、ショートカットのキーボード操作も設定できるようになっているなど大変使いやすくなっています。

bratは共同作業も行えるようにサーバクライアントのシステムになっていて、サーバはPythonで、クライアントはJavaScriptで書かれています。セキュリティ面からApacheサーバなどを通して利用することが推奨されていますが、次のようにして簡単に起動することができます:

$ curl -O http://weaver.nlplab.org/~brat/releases/brat-v1.3_Crunchy_Frog.tar.gz
$ tar xzf brat-v1.3_Crunchy_Frog.tar.gz
$ cd brat-v1.3_Crunchy_Frog
$ ./install.sh -u
(ユーザ名、パスワード、管理者メールアドレスを入力します)
$ python standalone.py

ブラウザで、http://127.0.0.1:8001 にアクセスすると利用できます。アノテーションの情報は、テキストのファイルとは別に拡張子が.annのファイルに記録されます。テキストファイルを選択してログインした状態で、マウスを使ってダブルクリックまたはドラッグして単語を選択すると、固有名を指定するウィンドウが現れます。

また、MeCabを利用した日本語の単語分割にも対応しているようで、tools.confファイルに次のように指定できます:

Tokens tokenizer:mecab

Upgrading to v1.3 (Crunchy Frog) - brat rapid annotation tool

MacPortsを使っているのであれば、MeCabに対応したPythonをインストールしておきます:

$ sudo port install py27-mecab

ただし、サーバサイドでは確かにMeCabの単語分割処理が行われているようなのですが、クライアントの画面上では特に変わりがなく、単語が分かれて表示されてダブルクリックで単語が選択できるようになるとおもいきや、そうなっていないので謎ですが…。

他にもSimStringを使った類似文字列の正規化に対応していたりと、精力的に様々な機能を盛り込んでいます。

自然言語処理ツールなどのMacPorts

Mac OSオープンソースのパッケージを利用するには、XcodeApp Storeからダウンロードしてコマンドラインツールをインストールする必要があります。MacPortsを使ってパッケージをインストールすると、通常の場合、Buildbotであらかじめ作成されたバイナリがダウンロードされるので、ソースからビルドする負荷は減りましたが、Xcodeのインストールは相変わらず必要です。

単にパッケージを利用したいユーザにとって、Xcodeをインストールすること自体が手間ですが、Xcodeは頻繁に更新される上、バージョンの違いによってビルドできないパッケージがあるのも問題です。Xcode 4.6 Release Notesによると、次期バージョンではGCCコンパイラが提供されないようです。

MacPortsでビルドするとデフォルトのClangコンパイラが使われるので、GCCが前提のパッケージは修正が必要になることがあります。MacPortsの開発者メーリングリストでは、Xcodeに依存しない形でシステムを提供できないか、という議論もあります。使いやすいシステムに発展していくといいですね。

日本語向けの自然言語処理ツールをはじめとしてパッケージ化してきたPortを、あまり整理できていませんが、Wikiページにまとめました。これだけのパッケージがあると凄いことができそうです。MacPortsのLivecheckの仕組みを使うと、手軽にバージョン更新情報が確認できるので、Portも定期的に最新版に追随しています。色々と発見もあって、例えば、相当昔から公開されている専門用語自動抽出用PerlモジュールのTermExtractが、今年になって更新されていることも知りました(^^)