【Node.js】kuromoji.js + mecab-ipadic-neologdで形態素解析して遊ぶ

スクレイピングした文章を**形態素解析**したい！

`node`では`java`用に書かれた`kuromoji`を移植した`kuromoji.js`を使用するのが簡単っぽい。（自分調べ）

しかしWeb上の文字は日々変化し、思ったように解析できない場合も多い。
そこでWeb上の資源を解析して作られている新語・固有表現に強い`mecab-ipadic-NEologd`という辞書も導入する。
（＋ベースは`ipadic`辞書）

- [MeCab: Yet Another Part\-of\-Speech and Morphological Analyzer](https://taku910.github.io/mecab/)
- [kuromoji \- japanese morphological analyzer](https://www.atilika.org/)
- [mecab\-ipadic\-neologd/README\.ja\.md at master · neologd/mecab\-ipadic\-neologd](https://github.com/neologd/mecab-ipadic-neologd/blob/master/README.ja.md)
- [日本語形態素解析エンジンKuromojiについて調べた \- motacaplaのめう](https://tikeda-meu.hatenablog.com/entry/2018/09/22/150740) <-概念が分かりやすい👏

## 環境

- **Windows 10**, git-bash, MINGW64（素直にlinux使ったほうが簡単です）
- busybox（UNIXコマンド群、後で導入）
- node v12.18.3
- npm v6.14.7
- kuromoji.js v0.1.2



## kuromoji.js の導入

`kuromoji.js`にはデフォルトで辞書が入っているため、使うだけなら非常に簡単。
サンプルの`dicPath`を、`node_module`内の辞書を参照するように変更する。

- [takuyaa/kuromoji\.js: JavaScript implementation of Japanese morphological analyzer](https://github.com/takuyaa/kuromoji.js/)

```bash
$ npm install kuromoji
```

```javascript:sample.js
var kuromoji = require("kuromoji");

kuromoji.builder({ dicPath: "node_modules/kuromoji/dict" }).build(function (err, tokenizer) {
  // tokenizer is ready
  var path = tokenizer.tokenize("すもももももももものうち");
  console.log(path);
});
```

実行すると形態素解析した結果が出力されるはず。





## kuromoji\-js\-dictionary の導入

`kuromoji.js`に新しい辞書を追加するには、その辞書を`kuromoji`用に変換する必要がある。
これを支援してくれるスクリプトがあったので使用させてもらう。

- [sable\-virt/kuromoji\-js\-dictionary: kuromoji\.js dictionary generator](https://github.com/sable-virt/kuromoji-js-dictionary)

```bash
$ git clone https://github.com/sable-virt/kuromoji-js-dictionary.git

$ cd kuromoji-js-dictionaly
$ npm install
```

**`windows`環境**では一部動かないので手作業で修正...

```json:package.json
{
  "scripts": {
+   "euc": "find ./neologd-seed -name '*.csv' -exec sh -c 'nkf -e --overwrite {}' ';'",
+   "tar": "find ./neologd-seed -name '*.csv' -exec sh -c 'tar -cvzf ./dict/neologd/$(basename {}).tar.gz {}' ';'",
-   "tar": "find ./neologd-seed -name '*.csv' -exec sh -c 'tar -cvzf ./dict/neologd/$(basename '{}').tar.gz {}' \\;",
  }
}
```

`euc`はgitのログを見る限り必要無くなったようだが、`npm run convert`から消し忘れている様子...。
必要ないか断定できないのでログからリバートした。
また`-exec`コマンドは`windows`では`;`で終わらせる必要があるらしいので修正。

- [WindowsでGnuWin32のfindを使う際の \-exec の指定方法 \- Qiita](https://qiita.com/shinsa82/items/e50f121a3b2d61fc000c)


ビルドするために他に`xz`と`nkf`が必要なので、無い場合は適当に用意しておく。
`linux`環境なら`brew`などで適当に取ってこれるが`windows`だとこれまた厄介。

`xz`は`busybox`を使用し、`nkf`は`victor`から適当なものを用意した。
それぞれ`--help`コマンドが通れば追加完了。
その他足りないコマンドは各自で。

- [【IT初心者向け】Windowsでbusyboxを利用できるようにする \- Qiita](https://qiita.com/tamcchi103/items/ef2315ce9ab872e7a746)
- [nkf\.exe nkf32\.dll Windows用の詳細情報 : Vector ソフトを探す！](https://www.vector.co.jp/soft/win95/util/se295331.html)





## 辞書のコンバート

ここからはレドメ通りなのだが一応記録しておく。

`./neologd-seed`のディレクトリに使用したい辞書（`****.csv.xz`）を置いておく。
初めから以下のの辞書が置いてあるので、とりあえずそれを使用する。

> - ../dict/mecab-ipadic-2.7.0-20070801.tar.gz (ベースの辞書)
> - mecab-user-dict-seed.20180322.csv.xz
> - neologd-adjective-verb-dict-seed.20160324.csv.xz
> - neologd-common-noun-ortho-variant-dict-seed.20170228.csv.xz
> - neologd-noun-sahen-conn-ortho-variant-dict-seed.20160323.csv.xz

```bash
# ./dict/neologd に変換した辞書を出力
$ npm run convert

# ./dist に kuromoji.js 用の辞書を出力
$ ./bin/run
```

`All done!!`って言われたら完成！
`./dict`ディレクトリを自分のプロジェクトに持ってきて、`dicPath`を変更すれば完成。

`TypeError: Cannot read property 'lookup' of null`は辞書が見つからないエラー。
おま環か分からないが、`package.json`からの相対パスで記載すればOKだった。





## 新しい辞書の追加（mecab-ipadic-NEologd）

- [neologd/mecab\-ipadic\-neologd: Neologism dictionary based on the language resources on the Web for mecab\-ipadic](https://github.com/neologd/mecab-ipadic-neologd)

上記では予め用意された辞書を使用したが、`NEologd`はビルドすることで最新の辞書を作成することができる。（週2更新？）
ただそれはまた大変なので、リポジトリに定期的に保存？されているビルドされた辞書を使用する。
上記URLの [./seed](https://github.com/neologd/mecab-ipadic-neologd/tree/master/seed) からビルドされた辞書を取得できる。

試しに`mecab-user-dict-seed.****.csv.xz`という辞書を追加する場合...
この辞書をダウンロードして、`./neologd-seed`に放り込む。
前回のビルドの残骸（`***.csv`）が残っている場合、消しておいてもよい。
その後、上記の「辞書のコンバート」の章と同じことをやれば完成だ。

他の辞書もこれと同様の手法で導入できる（はず）。




## NEologdの効能

`NEologd`を今試しているサンプルに適用してみた。
これはある動画のチャット欄から単語として有用な名詞、動詞、形容詞を抽出し、出現数をカウントしたものである。
（ちなみにあんかけパスタを食べているシーンのチャット200件を対象としている）

未適用の状態と比較すると「名古屋めし」や「あんかけパスタ」といういかにもな単語が、ちゃんと1ワードになっていることが確認できた。
2018年版と2020年版は特異な単語が無かったせいか大きな変化は無かった。
よって、Webの情報を処理する際には、`NEologd`を使用したほうが効果的であろう。

![neologd_test_diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105139/44dddce5-3575-418a-b6bd-e0f0064e0f2e.png)




## 結論
`kuromoji`と`NEologd`を使ってどんどん形態素解析してこ！

##### あとがき：
nodeでゴリゴリ書けるのは非常に助かる。
やろうと思えばブラウザでも実行できるのは強い。
`Sudachi`ってのも試してみたいね。

ぶっっっちゃけスクリプトをnodeで書き直せばこんなに引っかからないよねぇ。
けど、元ソースを読み解くのも面倒なので、環境側を合わせる方針にした。

...WSLを使うのも手か？（まだ触ってないから未知の世界）