[Pyinstaller & Ginza] Ginzaを使用したpythonファイルのexe化

# [Pyinstaller & Ginza] Ginzaを使用したpythonファイルのexe化
日本語の自然言語処理ライブラリである[Ginza](https://megagonlabs.github.io/ginza/)を使ったpythonファイルを、pyinstallerでexe化するのにめちゃくちゃハマったので、記事化しました。

Google先生に聞いても解決策がほとんど出てこなかったので需要はないかもしれませんが、もし同じ問題にぶち当たった人がいたときに、その人への一助になれば幸いです。。。

## ハマったポイント
pyinstallerでexe化したアプリケーションが動かない

以下、実際出てきたエラー一覧
>unhandled exception in script

>RuntimeError: Cannot find the MXNet library.

>[E053] Could not read config.cfg

>tok = dictionary.Dictionary().create(mode=split_mode)
>Exception: Error loading config: IO Error: 指定されたパスが見つかりません。 (os error 3)

>pyo3_runtime.PanicException: system dictionary hogehoge...\sudachidict_core\resources\system.dic did not exist


## 原因（だと思われること）
上記みたいなエラーでexeが動かない場合、exe化したいpyファイルから間接参照しているモジュールをpyinstallerが読み込んでくれていない可能性が高いです（例:import spacyをした場合、spacyが参照しているモジュール群）

## 解決策
下記手順に沿って処理すれば動く・・・はずです
(今回はpyinstallerをGUIで使用できる[auto-py-to-exe](https://pypi.org/project/auto-py-to-exe/)を使いました)

※下記手順（特に手順2）は[このページ](https://githubhot.com/repo/WorksApplications/SudachiPy/issues/173)を参考にしました。


### 1. MXNetのインストール（不要な人もいるかも）
MXNetがなかったため、pip install mxnet

### 2. spacyをちょっと弄る
$python-path\Lib\site-packages\spacy\lang\ja\\\__init__.pyを一部下記のように編集
```python:__init__.py
def try_sudachi_import(split_mode="A"):
    """SudachiPy is required for Japanese support, so check for it.
    It it's not available blow up and explain how to fix it.
    split_mode should be one of these values: "A", "B", "C", None->"A"."""
    try:
        from sudachipy import dictionary, tokenizer

        split_mode = {
            None: tokenizer.Tokenizer.SplitMode.A,
            "A": tokenizer.Tokenizer.SplitMode.A,
            "B": tokenizer.Tokenizer.SplitMode.B,
            "C": tokenizer.Tokenizer.SplitMode.C,
        }[split_mode]
        sudachi_config_path = os.path.abspath(os.path.join(os.path.dirname(__file__), r'..\\..\\..\\sudachipy\\resources\\sudachi.json'))
        tok = dictionary.Dictionary(config_path=sudachi_config_path).create(mode=split_mode)
        return tok
    except ImportError:
        raise ImportError(
            "Japanese support requires SudachiPy and SudachiDict-core "
            "(https://github.com/WorksApplications/SudachiPy). "
            "Install with `pip install sudachipy sudachidict_core` or "
            "install spaCy with `pip install spacy[ja]`."
        ) from None
```
>sudachi_config_path = os.path.abspath(os.path.join(os.path.dirname(__file__), r'..\\..\\..\\sudachipy\\resources\\sudachi.json'))

>tok = dictionary.Dictionary(config_path=sudachi_config_path).create(mode=split_mode)

が追記・編集した部分です。

sudachi.jsonのパスは人によって違うかもしれませんが、pip install -U ginza ja-ginzaでginzaを入れた人はこの指定でいけるはずです。

### 3. pyinstallerのオプションを設定し、exeファイルへコンバート
Onefileオプションを「One directory」に設定し、Advanced内にあるcollect-allに下記を追加し、コンバートを開始します。

- ginza
- ja_ginza
- spacy
- sudachipy
- mxnet
- unidic_lite

### 4. outputフォルダ内へライブラリを追加
このままだとexeファイルを起動しても、冒頭でお見せしたエラーで止まってしまうため、$python-path\Lib\site-packages\sudachidict_coreを、outputフォルダ内のexeファイルと同じ階層にコピーします。

また、outputフォルダ内のsudachipy内にresourcesがない場合があり、その状態だとまた別のエラーが出てきます。この場合は、site-packages内のsudachipyから、resourcesをフォルダごと上記と同様にコピーしてください。

### 5. exeファイルの起動
これでエラーなく動作する・・・はずです。これでもまだエラーを吐く場合、collect-allにエラーの原因と思われるモジュールを追加すれば解決するかもしれません。