MATLABでmecab-ipadic-NEologdをシステム辞書として使う

#はじめに
@aoimidori さまの記事「[MATLABでmecab-ipadic-NEologdを使ってテキスト解析](https://qiita.com/aoimidori/items/85aa3a5791ca86a46217)」でNEologd辞書をMATLABのユーザー辞書として使う方法が紹介されているのを読んで，「せっかくだからシステム辞書も組み込んでしまおう」と思いやってみました．ほぼほぼ一本道ですが，いくつか躓いた点もあったので覚え書きがてら紹介しようと思います．

__環境・使用プログラム__
OS: Windows 10 (64bit)
MeCab: Windows用バイナリパッケージ（mecab-0.996.exe）でインストールしたもの．
MATLAB R2020a
Text Analytics Toolbox
7zip (v19.00)
Text Code Converter （v1.4.2) 

__参考にさせていただいた記事__
この記事を書くにあたり，以下の記事を参考にさせていただきました．どうもありがとうございました．
@aoimidori さま [MATLABでmecab-ipadic-NEologdを使ってテキスト解析](https://qiita.com/aoimidori/items/85aa3a5791ca86a46217)
@zincjp さま [WindowsでNEologd辞書を比較的簡単に入れる方法ーユーザー辞書編](https://qiita.com/zincjp/items/c61c441426b9482b5a48)
@zincjp さま [WindowsでNEologd辞書を比較的簡単に入れる方法-システム辞書編](https://qiita.com/zincjp/items/e491f1712a701ad91a4f)

#ポイント
mecab-ipadic-NElongdのダウンロード，MeCab辞書のコンパイル方法（mecab-dict-index.exeの使い方）などすでにご存じの方のために，自分が躓いたところだけまとめておきます．ポイントは次の4つ．

1. コンパイル時は文字コードを合わせてあげないといけない（MeCabのデフォルト辞書をUTF-8に合わせるのがよさげ）．
1. MeCabの辞書フォルダにあるファイル全部をコード変換してはならない．*.csv とunk.def だけ．
1. MeCabのデフォルト辞書の文字コードをUTF-8に変換するときにはBOMを付加してはいけない（辞書はできるけどMATLABで実行するとエラーになる．）
1. 全部入りでコンパイルしようと思うと落ちる（ファイル容量に制限？）．mecab-user-seed.yyyymmdd.csvはユーザー辞書としておくのが無難．

# 事前準備
__新しいシステム辞書を置くフォルダの作成__
MATLABのMeCabでユーザー指定のシステム辞書を使用するには，```mecabOptions``` オブジェクトの```Model```プロパティで__システム辞書そのほか一式が置かれているフォルダ__を指定する必要があります．この辺が，ユーザー辞書の指定と違うところですね．そこで，```C:\newDic```に新しい辞書を作ることにします．以下，このフォルダのことを「新辞書フォルダ」と呼びます．

MATLABでのオプション指定は次のようになります．

```matlab
str = "「ああ」と「あああ」と「ああああ」はどう分かれるか";
mecabOpt = mecabOptions('Model','C:\newDic\');
tkn = tokenizedDocument(str,'TokenizeMethod',mecabOpt);
```

__MeCabのインストール__
Windows用のビルド済みのバイナリパッケージのインストーラ（mecab-0.996.exe）が[MeCab作者のページ](https://taku910.github.io/mecab/#download)からダウンロードできますので，それのファイルをダウンロードして実行します．デフォルトで C:\Program Files (x86)\MeCab にインストールされます．辞書ファイルは，C:\Program Files (x86)\MeCab\dic\ipadic　にあります．

<details><summary>MeCabの辞書フォルダの中身</summary>
![NEologd_install_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541000/de9588ef-33b8-100f-71e0-8397b37932e3.png)
</details>
__mecab-ipadic-NElogdのダウンロードと辞書ファイルの解凍__
[gitHubのレポジトリ](https://github.com/neologd/mecab-ipadic-neologd)から，gitでクローンするかzipフィアルをダウンロードして解凍します．フォルダmecab-ipadic-neologd-master\seed の中に，圧縮された辞書ファイルが12個収められていますので，これを解凍しておきます（[7-zip](https://sevenzip.osdn.jp/)で解凍できます）．

<details><summary>NEologd の辞書フォルダの中身（解凍後）</summary>
![NEologd_install_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541000/3a3ae628-5add-b05c-5550-4005ff19c270.png)
</details>

# MeCabのIPA辞書ファイルの文字コード変換
NEologd辞書をMeCabのシステムファイルとして使うには，デフォルトのMeCabの辞書ファイルとNEologdの辞書ファイルを併せてコンパイルする必要があります．このときに，両者の文字コードが異なっているとうまく動かないので，MeCabの辞書ファイルの文字コードをShift-JIS[^2]からUTF-8に変換します（NEologdの辞書ファイル文字コードはUTF-8）．

MeCabの辞書フォルダにあるファイルをすべて新辞書フォルダにコピーし，これらのファイルのうち__全ての .csv ファイルとunk.def__の文字コードをUTF-8に変換します．
（自分は，文字コードの変換には．[Text Code Converter](https://www.vector.co.jp/soft/winnt/util/se493100.html) を使いました．）

コード変換時に注意したいのが，UTF-8への変換に当たって__BOM（Byte Order Mark）を付加しない__ということです．コード変換プログラムによっては，UTF-8に変換する際にBOMを付加するのがデフォルトになっている場合もあるので，そのオプションはOFFにしてください[^3]．

<details><summary>Text Code Converter のBOM付加 on/off スイッチ</summary>
![TextCodeConverter_BOM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541000/b18643d9-e308-f3de-4ed6-da2b22bfb71a.png)
</details>

# 辞書のコンパイル
NEologdの辞書とMeCabのオリジナル辞書を合わせてコンパイルするのですが，__すべての辞書を併せてコンパイルしようとすると，作業の途中で落ちてしまいます__．あれこれ試してみたところ，どうやら扱える辞書データの量に制限があるようです．（Windowsの配布用バイナリパッケージが32bit版だからでしょうか・・・）そこで， __mecab-user-seed.yyyymmdd.csvはユーザー辞書として使用する__ことにして，残りの辞書ファイルをシステム辞書に組み込むことにします．（上記ファイル名のyyyymmdd は辞書のバージョンによって異なるファイルの更新日付です）

解凍したNEologdの辞書の__mecab-user-dict-seed.yyyymmdd.csv以外__のファイルを新辞書フォルダにコピーし，mecab-dict-index.exe を使って辞書をコンパイルします．MATLABのコマンドラインからだとこんな感じ．

```matlab

newDicDir = 'C:\newDic'; % 辞書ファイルのある作業フォルダ．適宜変更してください．

cd(workDir);
system('"C:\Program Files (x86)\MeCab\bin\mecab-dict-index.exe" -f utf-8 -t utf-8');
```
これで，作業フォルダのchar.bin, matrix.bin, sys.dic, unk.dic の四つのファイルが更新されます．sys.dicのサイズが300MB位になっていれば多分OKです．

# 試してみよう
それでは，効果のほどを見てみましょう．

```matlab
>> str = "ああ，あああ，ああああ，あああああ";
>> tkn = tokenizedDocument(str)

tkn = 

  tokenizedDocument:

   11 tokens: ああ ， ああ あ ， ああ ああ ， ああ あ ああ
```
どうやら，「ああああ・・」は，「ああ」と「あ」の組み合わせとしてしか認識されないみたいです．

NEologdを組み込んだシステムファイルを使うと・・・

```matlab
>> mecabOpt = mecabOptions('Model',"C:\newDic");
>> tkn = tokenizedDocument(str,'TokenizeMethod',mecabOpt)

tkn = 

  tokenizedDocument:

   7 tokens: ああ ， あああ ， ああああ ， あああああ
```

それぞれの「ああ・・・」が別々の感嘆詞として扱われています．

# おわりに
ここで作ったしたシステム辞書に，@aoimidori さま の[記事](https://qiita.com/aoimidori/items/85aa3a5791ca86a46217)を参考に作ったユーザー辞書を加えると，mecab-ipadic-neologd辞書の完全形をMATLABで実現できます．辞書が大きくなるのと，外部辞書を参照することで多少処理速度に影響があるようにも感じられますが，固有名詞や表記揺れ対応など，恩恵は大きいのかなと思ってます．

なお，システム辞書・ユーザー辞書の更新を行うためには，それらの辞書を参照しているMATLABセッションを終了する必要があるようです（「ファイルが使用中で書き換えができない」と怒られます）．そんなときは，MATLABを終了して立ち上げ直す必要があります．一旦システム辞書・ユーザー辞書として使ったら，他の辞書に乗り換えてもそれらの辞書ファイルを解放してくれないみたいです．（コンパイルに失敗するたびに何度MATLAB立ち上げ直したことか・・・）この仕様はなんとか改善してほしいところですね．

[^2]: Windows用のインストーラでインストールした場合．辞書ファイルとして配布されているものの文字コードはEUC-JP．

[^3]: コード変換したCSVファイルをExcelで開いてみて文字化けしていれば正解．BOMは付加されていません．逆に，ちゃんと読めてしまう場合にはBOMが付いてしまっています．