[JavaScript] kuromoji.js の辞書に単語を追加する

2022-07-22

kuromoji

https://www.atilika.com/ja/kuromoji/

Javaで開発されたオープンソース日本語形態素解析エンジンです。
日本語のテキストを形態素と呼ばれる単語に分割できます。
分割したデータは名詞、動詞、形容詞のような品詞や、活用形など、多くの情報がわかるようになっています。

Apache LuceneやApache Solr、Elasticsearchにも使われています。

また、このぐらいのコードでお手軽に実行できます。

package com.atilika.kuromoji.example;

import com.atilika.kuromoji.ipadic.Token;
import com.atilika.kuromoji.ipadic.Tokenizer;
import java.util.List;

public class KuromojiExample {
    public static void main(String[] args) {
        Tokenizer tokenizer = new Tokenizer() ;
        List<Token> tokens = tokenizer.tokenize("お寿司が食べたい。");
        for (Token token : tokens) {
            System.out.println(token.getSurface() + "\t" + token.getAllFeatures());
        }
    }
}

kuromoji.js

JavaScript implementation of Japanese morphological analyzer. This is a pure JavaScript porting of Kuromoji.

超訳)JavaScriptで動作する kuromoji です。

https://github.com/takuyaa/kuromoji.js/

こちらも、このぐらいのコードでお手軽に実行できます。

const kuromoji = require('kuromoji');
const builder = kuromoji.builder({
  dicPath: './node_modules/kuromoji/dict',
})
builder.build((err, tokenizer) => {
    var path = tokenizer.tokenize("すもももももももものうち");
    console.log(path);
});

今回は、こちらの辞書に単語を追加していく方法の紹介です。

準備

① kuromoji.js を clone

git clone https://github.com/takuyaa/kuromoji.js.git

② npm install

cd kuromoji.js
npm i

単語の追加

まずは辞書が作れるか確認する。

npm run build-dict

完成すると、 .\dict に辞書が作られます。

作れない場合は、後述のトラブルシュートで解決するかもしれません。

では、 今回は「所謂」(いわゆる)という単語を追加したいと思います。
単語を追加していない場合は、こうなりました。

kuromoji.js の公式な デモページ で確認

ひらがなはOKですが、漢字だと トコロイイ(謎)になります。

① 辞書の定義ファイルを作成

まずは、.\node_modules\mecab-ipadic-seed\lib\dictに csvファイルを作ります。
(名前は何にしても大丈夫です。build-dict したときにこんな形で全部の csvファイルを読んでくれます。)

    function IPADic() {
        _classCallCheck(this, IPADic);

        this.costMatrixDefinition = new _DictionaryReader2.default('matrix.def');
        this.characterDefinition = new _DictionaryReader2.default('char.def');
        this.unknownWordDefinition = new _DictionaryReader2.default('unk.def');

        var readers = fs.readdirSync(__dirname + '/dict/').filter(function (filename) {
            return (/\.csv$/.test(filename)
            );
        }).map(function (filename) {
            return new _DictionaryReader2.default(filename);
        });
        this.tokenInfoDictionaries = new _SequentialDictionariesReader2.default(readers);
    }

「所謂」(いわゆる)という単語を追加するときは、csvファイルの中身は以下になります。

所謂,,,,連体詞,*,*,*,*,*,いわゆる,イワユル,イワユル

文字コードはUTF-8にします。
(もし、周囲がeucならeucに。周囲のcsvファイルと合わせるのが正解!)

csvファイルのフォーマットは次になります。

表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音

詳細は こちら に載っています。
活用形がある場合には、自分で展開が必要になります。
周囲のcsvファイルから、もとになる単語を検索して流用するとスムーズです(*’ω’*)

② build

こちらは簡単です。

npm run build-dict

成功すると、 .\dict に辞書が作られます。

あとは、kuromoji.jsを使っているプロジェクトに辞書ファイルをコピーするなりして、dicPathを設定すれば終わり (/・ω・)/

const builder = kuromoji.builder({
  dicPath: 'ここを辞書があるフォルダにする',
})

トラブルシュート

npm run build-dict でエラー

> kuromoji@0.1.2 build-dict
> gulp build-dict

gulp[16036]: c:\ws\src\node_contextify.cc:704: Assertion `args[1]->IsString()' failed.
 1: 00007FF70455FDCF v8::internal::CodeObjectRegistry::~CodeObjectRegistry+112495
 2: 00007FF7044EEF86 DSA_meth_get_flags+65526
 3: 00007FF7044EF341 DSA_meth_get_flags+66481
 4: 00007FF7044FCA2B node::OnFatalError+52507
 5: 00007FF704DDC046 v8::internal::Builtins::code_handle+172694
 6: 00007FF704DDB8BE v8::internal::Builtins::code_handle+170766
 7: 00007FF704DDBEE7 v8::internal::Builtins::code_handle+172343
 8: 00007FF704DDBD60 v8::internal::Builtins::code_handle+171952
 9: 00007FF704EAF171 v8::internal::SetupIsolateDelegate::SetupHeap+494673
10: 00007FF704E3EC06 v8::internal::SetupIsolateDelegate::SetupHeap+34534
11: 00007FF704F3EBD6 v8::internal::SetupIsolateDelegate::SetupHeap+1083062
12: 00007FF704E4161E v8::internal::SetupIsolateDelegate::SetupHeap+45310
13: 00007FF704E4161E v8::internal::SetupIsolateDelegate::SetupHeap+45310
14: 00007FF704E4161E v8::internal::SetupIsolateDelegate::SetupHeap+45310
15: 00007FF704E4161E v8::internal::SetupIsolateDelegate::SetupHeap+45310
16: 00000250E6E9E663

nodeのバージョンが新しいときに起きます。
kuromoji.js では glup 3 を使っているので、node 12 以降では正常に動作しないようです。

やってみたこと

node_modules フォルダを削除
package-lock.json を削除

npm i

⇒動かず。

glup を最新にアップデート

⇒動かず。

npm outdated

でアップデートが必要なモジュールを探して、すべて最新にアップデート

⇒動かず。

仕方ないので、古いバージョンの node にしました。

nvm use 10.16.3

⇒ 動いた! (/・ω・)/

// たまたま入っていたバージョンです。おそらく node 11 でも大丈夫です。