概要
VRにbot,OS,形態素解析にディープラーニングまで!JavaScriptの限界を超えた鉄人達の変態的所業まとめを読み、RからJavascriptが呼べたらもっと変態なのかなと思ったのでやってみました。
調べてみると{V8}というパッケージがあったので、JavaScriptで書かれた形態素解析器Rakuten MAが使えるか試してみました。
{V8}とRakuten MAについては下記をご参考ください。
- V8: Embedded JavaScript Engine for R
- GitHub - jeroenooms/V8
- Rakuten MA - morphological analyzer (word segue
n- tor + PoS Tagger) for Chinese and Japanese written purely in JavaScript - RakutenMAによる形態素解析入門
事前準備
必要なNode.jsのパッケージをインストールし、RakutenMAを参照するrequireメソッドを含む.jsをbrowserifyでコンパイルしておく。
$ npm install rakutenma
$ npm install js-beautify
# パッケージがインストールされたパスを確認
# 自分のMac環境ではホーム直下のnode_modules以下にインストールされている
$ npm config get prefix
# {V8}のVignetteにある通りにする(var RakutenMAにするとR実行部で" ReferenceError: RakutenMA is not defined")
$ echo "global.RakutenMA = require('$HOME/node_modules/rakutenma/');" > in.js
$ browserify in.js -o RakutenMAbundle.js
# モデルファイルの切り替えられるようにモデルファイルの.jsを分けて作っておく
$ echo "global.model = require('$HOME/node_modules/rakutenma/model_ja.json');" > in.js
browserify in.js -o Modelbundle.js
$ browserify in.js -o Modelbundle.js
R実行部
browserifyで作成した.jsファイルをV8::source
で読み込む。
library(stringr)
library(V8)
ct <- V8::v8()
ct$source(file = stringr::str_c(Sys.getenv("HOME"), "RakutenMAbundle.js", sep = "/"))
ct$source(file = stringr::str_c(Sys.getenv("HOME"), "Modelbundle.js", sep = "/"))
# グローバル環境を確認
> ct$get(V8::JS('Object.keys(global)'))
[1] "console" "print" "global" "ArrayBuffer" "Int8Array" "Uint8Array"
[7] "Int16Array" "Uint16Array" "Int32Array" "Uint32Array" "Float32Array" "Float64Array"
[13] "DataView" "RakutenMA" "model"
RakutenMAのdemo.jsにある通りに実行していく。
# 事前学習されたモデルを読み込んで、RakutenMAインスタンスを生成
ct$eval(src = V8::JS('var rma = new RakutenMA(model, 1024, 0.007812);'))
# 素性については下記を参考
# https://github.com/rakuten-nlp/rakutenma#supported-feature-templates
> ct$eval(src = V8::JS('rma.featset = RakutenMA.default_featset_ja;'))
[1] "c0,w0,w1,w9,w2,w8,b1,b9,b2,b8,c1,c9,c2,c8,c3,c7,d1,d9,d2,d8"
# Set the feature hash function (15bit)
ct$eval(src = V8::JS('rma.hash_func = RakutenMA.create_hash_func(15);'))
# 例文を形態素解析
ct$eval(src = V8::JS('var rs = rma.tokenize("うらにわにはにわにわとりがいる")'))
> ct$get(name = "rs")
[,1] [,2]
[1,] "うらにわ" "N-nc"
[2,] "に" "P-k"
[3,] "は" "P-rj"
[4,] "にわにわとり" "N-nc"
[5,] "が" "P-k"
[6,] "いる" "V-dp"
- POSタグリストより抜粋
タグ | 対応する BCCWJ 品詞名 |
---|---|
N-n | 名詞-名詞的 |
N-nc | 名詞-普通名詞 |
P-k | 助詞-格助詞 |
P-rj | 助詞-係助詞 |
V-c | 動詞-一般 |
V-dp | 動詞-非自立可能 |
そのままのモデルだとうまくいっていないので、モデルを再学習させる。
ct$eval(src = V8::JS(
'res = rma.train_one(
[
["うらにわ","N-nc"],
["に","P-k"],
["は","P-rj"],
["にわ","N-n"],
["にわとり","N-nc"],
["が","P-k"],
["いる","V-c"]
]
);')
)
# 形態素解析の再実行
ct$eval(src = V8::JS('var rs = rma.tokenize("うらにわにはにわにわとりがいる")'))
> ct$get(name = "rs")
[,1] [,2]
[1,] "うらにわ" "N-nc"
[2,] "に" "P-k"
[3,] "は" "P-rj"
[4,] "にわ" "N-n"
[5,] "にわとり" "N-nc"
[6,] "が" "P-k"
[7,] "いる" "V-dp"
学習した結果が反映されています。
まとめ
{V8}パッケージを用いてJavaScriptで書かれた形態素解析器Rakuten MAをRから呼び出せるか確認したところ、デモと同じ結果が出てきており、見たところ動作はしているようです。とはいえ、もっと適したJavaScriptの書き方があるでしょうから、折を見て学習していこうと思います。
{V8}の活用により、JavaScriptの可視化以外のパッケージもRから有効利用できるようになりました。これで{Rcpp}でMeCabとKyTeaが呼び出せて、{rJava}でkuromojiが呼び出せて、{PythonInR}でChainer/scikit-learnなどが使えます。とても変態ですね。
続けてJuman/KNPもいきたいところですが、なかなかどうして難しいものです。Juman++に期待したいですが、こちらもなかなかどうして難しいものですね。
進捗、がんばります。
参考
- Using NPM packages in V8
- Browserify
- Browserify: それはrequire()を使うための魔法の杖
- JUMAN++ (a Japanese Morphological Analyzer)
- RNNLMベースの形態素解析器 JUMAN++ をhomebrewでインストールできるようにした
実行環境
> devtools::session_info()
Session info ----------------------------------------------------------------------------------------
setting value
version R version 3.3.1 (2016-06-21)
system x86_64, darwin13.4.0
ui RStudio (0.99.903)
language (EN)
collate ja_JP.UTF-8
tz Asia/Tokyo
date 2016-10-20
Packages --------------------------------------------------------------------------------------------
package * version date source
assertthat 0.1 2013-12-06 CRAN (R 3.3.1)
curl 1.2 2016-08-13 cran (@1.2)
DBI 0.5 2016-08-11 cran (@0.5)
devtools 1.12.0 2016-06-24 CRAN (R 3.3.0)
digest 0.6.9 2016-01-08 CRAN (R 3.3.0)
dplyr 0.5.0 2016-06-24 CRAN (R 3.3.1)
jsonlite 1.0 2016-07-01 CRAN (R 3.3.0)
magrittr 1.5 2014-11-22 CRAN (R 3.3.1)
memoise 1.0.0 2016-01-29 CRAN (R 3.3.0)
R6 2.1.3 2016-08-19 cran (@2.1.3)
Rcpp 0.12.7 2016-09-05 cran (@0.12.7)
rsconnect 0.4.3 2016-08-13 Github (rstudio/rsconnect@1665cb8)
stringi 1.1.1 2016-05-27 CRAN (R 3.3.1)
stringr * 1.1.0 2016-08-19 cran (@1.1.0)
tibble 1.2 2016-08-26 cran (@1.2)
V8 * 1.0.3 2016-06-28 CRAN (R 3.3.0)
withr 1.0.2 2016-06-20 CRAN (R 3.3.0)