word-vector-web-api : Implementation in order to operate a web API of word vector models which are generated by Word2Vec, GloVe or e.t.c.
word2vec や GloVe などで構築済みな単語ベクトルのモデルを使った結果を HTTP 経由で JSON/JSONP 形式で取得することができる Web API です。
word-vector-web-api を利用することで、様々なライブラリや資源を組み合わせて同様の Web API を構築するために必要な作業コストを軽減できます。
- Web API なので、どのようなプログラミング言語からでも結果を取得可能
- リクエスト時に callback パラメタを指定すれば、フロントエンドから JSONP でレスポンスを取得・可視化も可能
- HTTP サーバに nginx を使っており、処理結果がキャッシュされる
- 割と高速、割と省メモリ
- モデルの読み込みと検索は C++ な MessagePack RPC サーバでおこなっている
- Dockerfile が用意されている
- アプリケーションごとに ENDPOINT に使うスクリプトを改変して image を作り直せばよい
- まだメソッドが充実しきっていない。
- 自分のアプリケーションに利用するためには、結局のところサンプルを眺めて理解したり、 word-vector-web-api の各コードを読む必要がある
更新は GitHub 経由で行います。
初回は以下のコマンドでgit cloneしてください。
$ git clone --depth 1 https://github.com/overlast/word-vector-web-api.git
または
$ git clone --depth 1 git@github.com:overlast/word-vector-web-api.git
もしも、リポジトリの全変更履歴を入手したい方は「--depth 1」を消してcloneして下さい。
以下では日本語 Wikipedia を使って作ったサンプルモデルを使ってデータを取得してみます。
環境構築の際の不具合をできるだけ減らすために Docker を使います。
Dockerfile からイメージを作り、起動したコンテナ内でプロセスを立ち上げて、結果を取得するまでの手順を示します。
-
(登録していない場合) epel リポジトリ
$ sudo yum -y clean all
$ sudo yum -y install epel-release
$ sudo yum -y update
-
docker
$ sudo yum --enablerepo=epel -y install docker-io
-
Docker に関する知識
- docker コマンドで CentOS の docker image を pull して run できる程度に
-
Google のアカウント
- Google Drive からサンプルモデルをダウンロードするために必要です
-
- パッケージをインストールして、 以下の3コマンドを実行しておいて下さい
- $ boot2docker init
- $ boot2docker start
- $ eval "$(boot2docker shellinit)"
- shellinit すると docker コマンドが使えるようになります
- パッケージをインストールして、 以下の3コマンドを実行しておいて下さい
-
Docker と boot2docker に関する知識
- boot2docker を使って CentOS の docker image を pull して run できる程度に
-
Google のアカウント
- Google Drive からサンプルモデルをダウンロードするために必要です
はじめに以下のコマンドを実行してサンプルモデル(約 800 MByte)を Google Drive からダウンロードします。
$ ./libexec/download-sample-jawiki-model.sh
上記で実行したスクリプトは、golang で実装された drive コマンドのコンパイルと、それを使った Google Drive に対するリクエストを行います。
たとえば以下の様な出力が表示されます。
$./libexec/download-sample-jawiki-model.sh
[sample-model-downloader] : Start..
[sample-model-downloader] : Linux is supported
[sample-model-downloader] : Install go and hg
読み込んだプラグイン:fastestmirror, priorities, security
インストール処理の設定をしています
Loading mirror speeds from cached hostfile
* base: www.ftp.ne.jp
* epel: ftp.kddilabs.jp
* extras: www.ftp.ne.jp
* rpmforge: ftp.kddilabs.jp
* updates: www.ftp.ne.jp
169 packages excluded due to repository priority protections
パッケージ golang-1.4.2-2.el6.x86_64 はインストール済みか最新バージョンです
パッケージ mercurial-1.4-3.el6.x86_64 はインストール済みか最新バージョンです
何もしません
[sample-model-downloader] : go get github.com/prasmussen/gdrive/cli
[sample-model-downloader] : go get github.com/voxelbrain/goptions
[sample-model-downloader] : go get code.google.com/p/goauth2/oauth
[sample-model-downloader] : git clone https://github.com/prasmussen/gdrive.git
[sample-model-downloader] : cd /home/overlast/git/word-vector-web-api/libexec/../tmp/gdrive
Already up-to-date.
[sample-model-downloader] : Compile drive.go to create Google Drive CLI application
command-line-arguments
[sample-model-downloader] : cd /home/overlast/git/word-vector-web-api/libexec/../model/
うまくいくと、初めてdrive コマンドでモデルをダウンロードする場合には、 Google Drive からのダウンロードに必要な確認作業のための URL が表示されます。過去に drive コマンドを認証した情報が保持されているなら同意が不要なのでURLは表示されません。
[sample-model-downloader] : Download sample model data file from Google Drive using drive command
Go to the following link in your browser:
https://accounts.google.com/o/oauth2/auth?client_id=367116221053-7n0vf5akeru7on6o2fjinrecpdoe99eg.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&state=state
Enter verification code:
この URL にブラウザでアクセスして、同意画面で同意して、確認用の token を得たら、以下のようにコピペします。
Enter verification code: 4/m62RCGf0d81HV5sooL*********************
確認が成功すると、xz 圧縮されたサンプルモデルが model ディレクトリにダウンロードされて、さらに unxz コマンドで解凍されます。
[sample-model-downloader] : Decompress sample model data file using unxz command
Downloaded 'jawiki.20150602.neologd.bin.xz' at 32.7 MB/s, total 849.3 MB
[sample-model-downloader] : Finish..
解凍されたサンプルモデルは以下の位置にあります。
$ ls -al model/jawiki.20150602.neologd.bin
-rw-rw-r-- 1 overlast overlast 917846510 7月 2 20:57 2015 model/jawiki.20150602.neologd.bin
このモデルについて簡単なコメントを書いておきます。
- jawiki.20150602.neologd.bin.xz (810MByte)
- 日本語 Wikipedia の 2015-06-02 の dump データ(jawiki-latest-pages-articles.xml.bz2)から作成
- jawiki-latest-pages-articles.xml.bz2 から plain text を抽出する際に New Version の WikiExtractor.py を使用
- 分かち書きに MeCab と mecab-ipadic-NEologd を使用
- Word2Vec のパラメタは"-cbow 0 -size 300 -window 5 -negative 0 -hs 1 -sample 1e-5"
次に docker/sample_s1/Dockerfile を使って、起動すると 1.5 GByte 程度のメモリを使う Docker image を build します。
Docker の build には以下のコマンドを使います。
$ ./libexec/create-docker-image-sample-word-vector-web-api-s1.sh
もしも最後まで処理がうまくいった場合は、以下の様なメッセージが表示されます。
...
Step 57 : ENTRYPOINT /root/git/word-vector-web-api/libexec/boot-word-vector-web-api-sample-1-slave.sh
---> Running in bbec3c1833d9
---> 76493a06b018
Removing intermediate container bbec3c1833d9
Successfully built 76493a06b018
[create-docker-image-sample-word-vector-web-api-s1] : Finish..
表示されていない場合、何かの原因で build が失敗しています。
ネットワーク環境に若干左右されるみたいなので、何度か時間を変えて実行してみてください。または以下のようにして一回作成中の image を消してリトライして下さい。
$ docker rmi -f sample-word-vector-web-api-s1:0.0.1
$ ./libexec/create-docker-image-sample-word-vector-web-api-s1.sh
できあがった image は以下のコマンドで確認できます。
$ docker images
$docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
sample-word-vector-web-api-s1 0.0.1 a6aaf2fcdc1a 44 seconds ago 698.6 MB
centos centos6 a005304e4e74 13 days ago 203.1 MB
サーバプロセスが 3 つ立ち上がる Docker image を build したいときは以下のコマンドを使います。
$ libexec/create-docker-image-sample-word-vector-web-api-s3.sh
起動すると 4 GByte 程度のメモリを使うけど、単位時間あたりに同時に処理できるリクエスト数が増えます。
Step2 で作った Docker image を使ってコンテナを起動します。
起動には以下のコマンドを使います。
$ ./libexec/run-docker-container-of-sample-word-vector-web-api-s1.sh
このコマンドでコンテナを起動すると word-vector-web-api に 22670 番ポートからアクセスできるようになります。
もしも localhost の 22670 番ポートをすでに使っている場合は、-p オプションで空いているポートを指定して下さい。
$ ./libexec/run-docker-container-of-sample-word-vector-web-api-s1.sh
[run-docker-container-of-sample-word-vector-web-api-s1] : Start..
[run-docker-container-of-sample-word-vector-web-api-s1] : OSX is supported
[run-docker-container-of-sample-word-vector-web-api-s1] : Run docker container of sample
543a30bc4737c9c287953a8f8b1b9d5af52b55fa14a1a3737278908896a182cf
Error response from daemon: Cannot start container 543a30bc4737c9c287953a8f8b1b9d5af52b55fa14a1a3737278908896a182cf: Bind for 0.0.0.0:22670 failed: port is already allocated
$
$ ./libexec/run-docker-container-of-sample-word-vector-web-api-s1.sh -p 23670
おそらく以下の様な表示が出ます。
$./libexec/run-docker-container-of-sample-word-vector-web-api-s1.sh --port 23670
[run-docker-container-of-sample-word-vector-web-api-s1] : OSX is supported
[run-docker-container-of-sample-word-vector-web-api-s1] : Run docker container of sample
0077aef0e71a9858342e3f7f780bd5dbac0184253cbef917e278a17d27b7a5ff
[run-docker-container-of-sample-word-vector-web-api-s1] : Finish..
コンテナの起動に成功した場合、以下のコマンドで起動したコンテナの状態を確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0077aef0e71a sample-word-vector-web-api-s1:0.0.1 "/bin/sh -c /root/gi 58 seconds ago Up 42 seconds 22671-22680/tcp, 0.0.0.0:23670->22670/tcp stoic_turing
Step2 でサーバプロセスが 3 つ立ち上がる Docker image を作った場合、そのイメージを使ったコンテナは以下のコマンドで起動できます。
$ ./libexec/run-docker-container-of-sample-word-vector-web-api-s3.sh -p 22670
Step3 でコンテナの起動に成功している場合、curl や ブラウザで結果を確認できます。
まず distance で 'タモリ'さんと Cosine 距離が近い単語を見てみましょう。ポート番号は自分で調整して下さい。
-
Linux の場合
$ curl "http://0.0.0.0:22670/distance?a1=タモリ"
-
OSX の場合
$ curl "http://$(boot2docker ip):22670/distance?a1=タモリ"
その結果、以下の様な結果が得られました。
{"format": "json", "items": [
{"term": "明石家さんま", "score": 0.81528389453887939}, {"term": "さんま", "score": 0.80035871267318726},
{"term": "ビートたけし", "score": 0.79251360893249512}, {"term": "所ジョージ", "score": 0.76938104629516602},
{"term": "とんねるず", "score": 0.7473946213722229}, {"term": "爆笑問題", "score": 0.73406845331192017},
{"term": "司会", "score": 0.72929728031158447}, {"term": "森田一義", "score": 0.72818166017532349},
{"term": "島田紳助", "score": 0.72627973556518555}, {"term": "中居正広", "score": 0.72301918268203735},
{"term": "山田邦子", "score": 0.71929085254669189}, {"term": "笑福亭鶴瓶", "score": 0.71266698837280273},
{"term": "ボキャブラ天国", "score": 0.70373982191085815}, {"term": "笑っていいとも!", "score": 0.70154005289077759},
{"term": "関根勤", "score": 0.70032232999801636}, {"term": "明石家マンション物語", "score": 0.70010024309158325},
{"term": "冠番組", "score": 0.69675129652023315}, {"term": "いいとも", "score": 0.69370967149734497},
{"term": "石橋貴明", "score": 0.68870562314987183}, {"term": "オレたちひょうきん族", "score": 0.68832921981811523},
{"term": "ものまね", "score": 0.68563121557235718}, {"term": "松村邦洋", "score": 0.68541419506072998},
{"term": "ボキャ天", "score": 0.68538647890090942}, {"term": "ウッチャンナンチャン", "score": 0.68278044462203979},
{"term": "テレフォンショッキング", "score": 0.68264764547348022}, {"term": "コーナー司会", "score": 0.68219667673110962},
{"term": "浅草キッド", "score": 0.68129265308380127}, {"term": "今夜は最高!", "score": 0.67805778980255127},
{"term": "今田耕司", "score": 0.67686200141906738}, {"term": "萩本欽一", "score": 0.67244911193847656},
{"term": "みのもんた", "score": 0.67096501588821411}, {"term": "北野ファンクラブ", "score": 0.66866558790206909},
{"term": "中居", "score": 0.66742992401123047}, {"term": "鶴瓶", "score": 0.66699719429016113},
{"term": "志村けん", "score": 0.66617244482040405}, {"term": "大橋巨泉", "score": 0.66485863924026489},
{"term": "上岡龍太郎", "score": 0.66450983285903931}, {"term": "ナインティナイン", "score": 0.66341793537139893},
{"term": "松本人志", "score": 0.66267943382263184}, {"term": "和田アキ子", "score": 0.66127783060073853}
], "query": "タモリ", "method": "distance", "sort": "cosine similarity", "status": "OK", "total_count": 40}
正解データがあるわけではないので、なるほど、って感じですね。
次に analogy で 「東京と東京タワー」との関係に近い「大阪」に対する東京タワー的なものが何かを見てみましょう。
-
Linux の場合
-
OSX の場合
$ curl "http://$(boot2docker ip):22670/analogy?a1=東京&a2=東京タワー&a3=大阪"
その結果、以下の様な結果が得られました。
{"format": "json", "items": [
{"term": "電波塔", "score": 0.60608410835266113}, {"term": "東京スカイツリー", "score": 0.58792692422866821},
{"term": "あべのハルカス", "score": 0.52693915367126465}, {"term": "生駒山", "score": 0.52557224035263062},
{"term": "対馬オメガ局", "score": 0.52209371328353882}, {"term": "通天閣", "score": 0.51043027639389038},
{"term": "東山タワー", "score": 0.49114975333213806}, {"term": "名古屋テレビ塔", "score": 0.48477703332901001},
{"term": "鉄塔", "score": 0.47564679384231567}, {"term": "テレビ塔", "score": 0.45989611744880676},
{"term": "フットタウン", "score": 0.45694351196289062}, {"term": "瀬戸デジタルタワー", "score": 0.44819486141204834},
{"term": "神戸ポートタワー", "score": 0.4481755793094635}, {"term": "送信所", "score": 0.44717010855674744},
{"term": "新梅田シティ", "score": 0.44428074359893799}, {"term": "大阪マルビル", "score": 0.44200178980827332},
{"term": "大平山送信所", "score": 0.43856528401374817}, {"term": "イーグレひめじ", "score": 0.43271398544311523},
{"term": "大阪ビジネスパーク", "score": 0.43267670273780823}, {"term": "生駒山テレビ・FM送信所", "score": 0.43197193741798401},
{"term": "福岡タワー", "score": 0.42966717481613159}, {"term": "京都タワー", "score": 0.42821276187896729},
{"term": "阪急グランドビル", "score": 0.42394104599952698}, {"term": "天保山ハーバービレッジ", "score": 0.42309394478797913},
{"term": "御堂筋", "score": 0.4201604425907135}, {"term": "OBP", "score": 0.41969111561775208},
{"term": "扇町公園", "score": 0.41857218742370605}, {"term": "アンテナ", "score": 0.41681712865829468},
{"term": "ランドマークタワー", "score": 0.41671887040138245}, {"term": "大阪城公園", "score": 0.41529473662376404},
{"term": "日本電波塔", "score": 0.41485264897346497}, {"term": "在阪テレビジョン放送局", "score": 0.41319084167480469},
{"term": "大阪タワー", "score": 0.41302743554115295}, {"term": "エフエムゆめウェーブ", "score": 0.41291263699531555},
{"term": "阪急三番街", "score": 0.41132032871246338}, {"term": "大阪市内", "score": 0.40921291708946228},
{"term": "梅田スカイビル", "score": 0.40839734673500061}, {"term": "夢洲", "score": 0.4076114296913147},
{"term": "コスモタワー", "score": 0.40697681903839111}, {"term": "スカイツリー", "score": 0.4069637656211853}
], "query": "東京 東京タワー 大阪", "method": "analogy", "sort": "cosine similarity", "status": "OK", "total_count": 40}
これも正解データがあるわけではないので、なるほど、って感じですね。人間だとどれが正解でどれが不正解か分かりますね。
実用するときは、モデルデータを改良して distance の結果を人手でフィルタリングして使うのがオススメです。
API 自体の詳しい説明は以降の「word-vector-web-api の使い方」の節に書きます。
試し終わった後の Docker コンテナの停止は docker stop を使います。
最初にコンテナのIDを調べます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0077aef0e71a sample-word-vector-web-api-s1:0.0.1 "/bin/sh -c /root/gi 58 seconds ago Up 42 seconds 22671-22680/tcp, 0.0.0.0:23670->22670/tcp stoic_turing
ID が分かったら docker stop [CONTAINER ID] と指定します。
$ docker stop 0077aef0e71a
これでコンテナは停止し破棄されます。
個人的にはこの使い方がオススメです。
Dockerfile を参考に環境構築をしてみて下さい。
今後、Linux と OSX に対応した環境構築用のスクリプトと手順も公開します。
インストール時に以下のライブラリが必要に応じて順にインストールされます。
- nginx-1.8.0 (独自のディレクトリにインストールされます)
- nginx-msgpack-rpc-module
- word2vec-msgpack-rpc-server
- Word2Vec (word-vector-web-api ディレクトリ内にインストールされます)
動作に必要なものは、上記ライブラリのインストール時に必要としている資源やライブラリです。
word-vector-web-api を使いたいときは、自分の作成したいアプリケーションごとに conf ファイルをコピーして設定を調整して使うのが良いです。
以下に API の仕様や、カスタマイズ時に必要な作業についても書きます。
a という 1 単語のクエリを投げると、ベクトル空間上でベクトル a に最も近いベクトル b を探して答えます。
具体的には「タモリ = ?」の ? に何が入りそうかを考える様なものです。
答えがどうなって欲しいかも考えてみましょう。
サンプルモデルは Wikipedia から作りました。ベクトルを構築する手法の性質から、タモリさんと同年代に同じ職種だった人の名前は同じような文脈で出現することが多そうで、距離が近くなりそうです。
お笑いビッグ 3 みたいな概念がありますし、明石家さんまさんやビートたけしさんは近いかもしれませんね。。(それがうまくいくかはモデル作成に使ったコーパス次第です)
http://[host_name or ip_address]:[port_number]/distance?a1=[query_string]
API は callback パラメタが指定されれ場合はレスポンスを JSONP 形式で返し、それ以外の場合は JSON 形式で返す。
parameter name | type | description |
---|---|---|
a1(required) | string | Word2Vec の distance のクエリ文字列 |
callback | string | コールバック関数名 |
"http://0.0.0.0:22670/distance?a1=タモリ"
"http://0.0.0.0:22670/distance?a1=タモリ&callback=sample"
field name | description |
---|---|
format | json のみ |
method | まさに distance メソッド |
sort | items の score の値の算出方法。今は cosine 距離のみ |
status | OK=結果が得られている, NG=何か不具合がある |
query | a1 パラメタで与えられた文字列 |
items | 検索結果の内容。term と score の組の配列。 |
term | score フィールドのスコアを持つ文字列 |
score | sort フィールドの手法で算出されたスコアの実数値 |
total_count | items フィールドに含まれる term と score の組数 |
以下は a1 パラメタに'タモリ'を指定した場合のレスポンスです
{"format": "json", "items": [
{"term": "明石家さんま", "score": 0.81528389453887939}, {"term": "さんま", "score": 0.80035871267318726},
{"term": "ビートたけし", "score": 0.79251360893249512}, {"term": "所ジョージ", "score": 0.76938104629516602},
{"term": "とんねるず", "score": 0.7473946213722229}, {"term": "爆笑問題", "score": 0.73406845331192017},
(略)
{"term": "上岡龍太郎", "score": 0.66450983285903931}, {"term": "ナインティナイン", "score": 0.66341793537139893},
{"term": "松本人志", "score": 0.66267943382263184}, {"term": "和田アキ子", "score": 0.66127783060073853}
], "query": "タモリ", "method": "distance", "sort": "cosine similarity", "status": "OK", "total_count": 40}
所ジョージさんですか。なるほど。
a、b と c の 3 単語のクエリを投げると、a - b = c - d という状態に一番近い d を見つけるために、ベクトル空間上でベクトル b - a + c に最も近いベクトル d を探して答える。
具体的には「東京 - 東京タワー = 大阪 - ?」の ? に何が入りそうかを考える様なものです。
答えがどうなって欲しいかも考えてみましょう。
東京から東京的な要素とタワー的な要素をひいたものを大阪から作るには、大阪から大阪的要素とタワー的要素をひくために、通天閣とかをひくとどうでしょうか。。(それがうまくいくかはモデル作成に使ったコーパス次第です)
http://[host_name or ip_address]:[port_number]/analogy?a1=[query_string]&a2=[query_string]&a3=[query_string]
API は callback パラメタが指定されれ場合はレスポンスを JSONP 形式で返し、それ以外の場合は JSON 形式で返す。
parameter name | type | description |
---|---|---|
a1(required) | string | Word2Vec の analogy のクエリ文字列a |
a2(required) | string | Word2Vec の analogy のクエリ文字列b |
a3(required) | string | Word2Vec の analogy のクエリ文字列c |
callback | string | コールバック関数名 |
"http://0.0.0.0:22670/analogy?a1=東京&a2=東京タワー&a3=大阪"
"http://0.0.0.0:22670/analogy?a1=東京&a2=東京タワー&a3=大阪&callback=sample"
field name | description |
---|---|
format | json のみ |
method | まさに analogy メソッド |
sort | items の score の値の算出方法。今は cosine 距離のみ |
status | OK=結果が得られている, NG=何か不具合がある |
query | a1、a2、a3 パラメタで与えられた文字列を半角スペースで結合した文字列 |
items | 検索結果の内容。term と score の組の配列。 |
term | score フィールドのスコアを持つ文字列 |
score | sort フィールドの手法で算出されたスコアの実数値 |
total_count | items フィールドに含まれる term と score の組数 |
以下は a1 パラメタに'東京'、a2 パラメタに'東京タワー'、そして a3 パラメタに'大阪'を指定した場合のレスポンスです。
{"format": "json", "items": [
{"term": "電波塔", "score": 0.60608410835266113}, {"term": "東京スカイツリー", "score": 0.58792692422866821},
{"term": "あべのハルカス", "score": 0.52693915367126465}, {"term": "生駒山", "score": 0.52557224035263062},
{"term": "対馬オメガ局", "score": 0.52209371328353882}, {"term": "通天閣", "score": 0.51043027639389038},
(略)
{"term": "梅田スカイビル", "score": 0.40839734673500061}, {"term": "夢洲", "score": 0.4076114296913147},
{"term": "コスモタワー", "score": 0.40697681903839111}, {"term": "スカイツリー", "score": 0.4069637656211853}
], "query": "東京 東京タワー 大阪", "method": "analogy", "sort": "cosine similarity", "status": "OK", "total_count": 40}
電波塔ですか。そうですか。
ちなみに overlast が普段使っているモデルでは上位 3 つは以下の通りでした。さっぽろテレビ塔・・・。
{term: "通天閣",score: 0.6666724681854248},
{term: "さっぽろテレビ塔", score: 0.6369253993034363},
{term: "ライトアップ",score: 0.6251795291900635},
word2vec-message-pack-server のプロセス数に関わらず、nginx(master) が全てのリクエストをさばいて、結果を 24 時間キャッシュします。
process name | port number | request to | return to | cache of response | protocol |
---|---|---|---|---|---|
nginx(master) | 22670 | nginx(slave) | user | on | HTTP |
nginx(slave) | 22671 | word2vec-message-pack-server | nginx(master) | - | HTTP & MessagePack-RPC |
word2vec-message-pack-server | 22676 | - | nginx(slave) | - | MessagePack-RPC |
process name | port number | request to | return to | cache of response | protocol |
---|---|---|---|---|---|
nginx(master) | 22670 | nginx(slave 1、2と3 に均等に) | user | on | HTTP |
nginx(slave 1) | 22671 | word2vec-message-pack-server 1 | nginx(master) | - | HTTP & MessagePack-RPC |
nginx(slave 2) | 22672 | word2vec-message-pack-server 2 | nginx(master) | - | HTTP & MessagePack-RPC |
nginx(slave 3) | 22673 | word2vec-message-pack-server 3 | nginx(master) | - | HTTP & MessagePack-RPC |
word2vec-message-pack-server 1 | 22676 | - | nginx(slave 1) | - | MessagePack-RPC |
word2vec-message-pack-server 2 | 22677 | - | nginx(slave 2) | - | MessagePack-RPC |
word2vec-message-pack-server 3 | 22678 | - | nginx(slave 3) | - | MessagePack-RPC |
いま書いてます。
研究的な実装を C/C++ で実装して word2vec-msgpack-rpc-server と同様に msgpack-rpc-server 化すれば、LL 言語で下手な実装をするより省メモリで高速な実装を各言語の MessagePack-RPC モジュール経由で利用できる。
MessagePack-RPC は依存ライブラリが少なく、他のプロトコルに無い柔軟性があるので、最初は雑に作りたい研究的なものづくりに向いている。
また、選択したプログラミング言語によるメモリの無駄が少ないことは、発明された新しい技術を実応用に近づけたり、結果を精緻化するうえでとても重要である。
さらに、その実装を Web API 化する場合、nginx-msgpack-rpc-module を利用すれば nginx の設定ファイルを書き換えるだけで msgpack-rpc-client と HTTP Server の用意が終わる。
新しい RPC server を書いた際に必要になる RPC client の実装工数がとても少なくなることは個人的にとても重要である。
そして研究的な実装を一般のエンジニアに試してもらうには、Web API にリクエストして結果の JSON を見てもらうことが、個人的な経験上では一番早いのでオススメである。
何か有益なものを実装するときは、Python ではなく C/C++ で実装し、更に Web API 化することで、最終的により広い範囲の研究者やエンジニアがユーザになるだろう。
word-vector-web-api を実用する際には、単語ベクトルのモデルを作る際の日本語文の単語分割の結果が形態素解析辞書によって変わり、その変化が性能に大きく影響するので、mecab-ipadic と mecab-ipadic-NEologdを併用するのが望ましい。
以上です。
継続して開発しますので、気になるところはどんどん改善されます。
ユーザの8割が気になる部分を優先して改善します。
まずは gensim の models.word2vec で使える method のうち、よく使いそうなものを順に実装していく予定です。
もしも word-vector-web-api を論文から参照して下さる場合は、以下の bibtex をご利用ください。
@misc{sato2015wordvectorwebapi,
title = {Word Vector Web API},
author = {Toshinori, Sato},
url = {https://github.com/overlast/word-vector-web-api},
year = {2015}
}
Copyright (c) 2015 Toshinori Sato (@overlast) All rights reserved.
ライセンスは Apache License, Version 2.0 です。下記をご参照下さい。