非一般名称（宝塚芸名）でNameDividerによる姓名分離を試みる


[この記事](https://qiita.com/muto-jo/items/79c41aa2fb8ff27c047c)を書いたとき、Wikipediaの宝塚の生徒一覧は、芸名が姓名に分かれていないと記載しました。

せっかくなので、芸名も姓名に分けてみたいなと思っていたところ、[こちらの記事](https://qiita.com/tanaka_n/items/0bb58c3e7ccfd3ef6b07)でNameDividerなる姓名を分離するPythonライブラリがあるのを見つけたので、トライしてみました。

# サンプルコードでずっこける

インストールはNameDividerの[公式サイト](https://github.com/rskmoi/namedivider-python)にある通りのコマンドで完了。
同じく公式サイトにあるサンプルのコードを実行したところ、FileNotFoundErrorでずっこけました…

```Python
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
/var/folders/cl/wm2yh_cj509fjnj8d5nw0vtw0000gn/T/ipykernel_12025/2559231275.py in <module>
      8 basic_divider = BasicNameDivider() # BasicNameDivider is fast but accuracy is 99.2%
      9 
---> 10 gbdt_divider = GBDTNameDivider() # GBDTNameDivider is slow but accuracy is 99.9%
     11 divided_name = gbdt_divider.divide_name("菅義偉")
     12 print(divided_name)

~/.pyenv/versions/anaconda3-2021.11/envs/ai_study/lib/python3.9/site-packages/namedivider/divider/gbdt_name_divider.py in __init__(self, config)
     21             config = GBDTNameDividerConfig()
     22         super().__init__(config=config)
---> 23         download_family_name_pickle_if_needed(config.path_family_names)
     24         download_gbdt_model_v1_if_needed(config.path_model)
     25         kanji_statistics_repository = KanjiStatisticsRepository(path_csv=config.path_csv)

~/.pyenv/versions/anaconda3-2021.11/envs/ai_study/lib/python3.9/site-packages/namedivider/util.py in download_family_name_pickle_if_needed(path)
     39     if path.exists():
     40         return None
---> 41     DEFAULT_CACHE_DIR.mkdir(exist_ok=True)
     42     print("Download FamilyNameRepository from GitHub...")
     43     content = requests.get(FAMILY_NAME_REPOSITORY_URL).content

~/.pyenv/versions/anaconda3-2021.11/envs/ai_study/lib/python3.9/pathlib.py in mkdir(self, mode, parents, exist_ok)
   1321         """
   1322         try:
-> 1323             self._accessor.mkdir(self, mode)
   1324         except FileNotFoundError:
   1325             if not parents or self.parent == self:

FileNotFoundError: [Errno 2] No such file or directory: '/Users/"user_name"/.cache/namedivider-python'
```

Pathlibの仕様から、/Users/"user_name"/.cache/がないのが原因だなとアタリをつけたので、

```shell
mkdir /Users/"user_name"/.cache/
```

して、無事このエラーを回避（解決しましたが念の為、作者の方に同エラーはご報告）。

回避したと思ったのも束の間。今度は次のエラーが起きました…

```Python
Download FamilyNameRepository from GitHub...
Download GBDT Model from GitHub...
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/var/folders/cl/wm2yh_cj509fjnj8d5nw0vtw0000gn/T/ipykernel_12025/2559231275.py in <module>
      8 basic_divider = BasicNameDivider() # BasicNameDivider is fast but accuracy is 99.2%
      9 
---> 10 gbdt_divider = GBDTNameDivider() # GBDTNameDivider is slow but accuracy is 99.9%
     11 divided_name = gbdt_divider.divide_name("菅義偉")
     12 print(divided_name)

~/.pyenv/versions/anaconda3-2021.11/envs/ai_study/lib/python3.9/site-packages/namedivider/divider/gbdt_name_divider.py in __init__(self, config)
     31         self.feature_extractor = FamilyRankingFeatureExtractor(kanji_statistics_repository=kanji_statistics_repository,
     32                                                                family_name_repository=family_name_repository)
---> 33         self.model = lgb.Booster(model_file=config.path_model)
     34 
     35     def calc_score(self, family: str, given: str) -> float:

~/.pyenv/versions/anaconda3-2021.11/envs/ai_study/lib/python3.9/site-packages/lightgbm/basic.py in __init__(self, params, train_set, model_file, model_str, silent)
   2262             self.handle = ctypes.c_void_p()
   2263             _safe_call(_LIB.LGBM_BoosterCreateFromModelfile(
-> 2264                 c_str(model_file),
   2265                 ctypes.byref(out_num_iterations),
   2266                 ctypes.byref(self.handle)))

~/.pyenv/versions/anaconda3-2021.11/envs/ai_study/lib/python3.9/site-packages/lightgbm/basic.py in c_str(string)
    200 def c_str(string):
    201     """Convert a Python string to C string."""
--> 202     return ctypes.c_char_p(string.encode('utf-8'))
    203 
    204 

AttributeError: 'PosixPath' object has no attribute 'encode'
```

こっちのエラーは、多分NameDividerではなく、依存するlightgbmの方の不備です。
lightgbm.Booster(model_file)は、[公式ドキュメント](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.Booster.html)によれば、

> model_file (str, pathlib.Path or None, optional (default=None)) – Path to the model file.

なので、pathilib.Pathで呼び出しているNameDividerは間違ってないと思うので。
なおこちらは自分でも未解決かつ未報告です。

と、エラーにぶち当たり、未解決なので、より精度の高いGBDTNameDivider()の使用は諦め、BasicNameDivider()で姓名を分けてみます

# 宝塚の生徒の芸名を姓名に分けてみる

９２期の生徒一覧を姓名に分けてみます。参考に読み仮名も併記します。

```Python
import csv
from namedivider import BasicNameDivider

basic_divider = BasicNameDivider()

with open("takaraduka_actress/takaraduka_actress_92period.csv".format(period), "rt") as f:
    reader = csv.DictReader(f)
    for row in reader:
        actress_name = row["芸名"]
        divided_name = basic_divider.divide_name(actress_name)

        print(divided_name, row["読み仮名"])
```

結果は下記の通りです。
48名中、6名がNGと精度としては87.5%でした。
NameDividerは、実在する名前をソースにしていますが、流石に一般的な名前ではない芸名の場合、精度は落ちるようです。

```
百 千糸 ももち いと -> NG: 百千 糸が正しい
真瀬 はるか まなせ はるか
美春 あやか みはる あやか
蘭乃 はな らんの はな
鞠花 ゆめ まりか ゆめ
透水 さらさ とうみ さらさ
松風 輝 まつかぜ あきら
煌月 爽矢 あきづき さや
千海 華蘭 ちなみ からん
天輝 トニカ あまき とにか
すみれ 乃麗 すみれのれい
天真 みちる てんま みちる
妃白 ゆあ ひしろ ゆあ
初花 美咲 はつはな みさき
真風 涼帆 まかぜ すずほ
凛城 きら りんじょう きら
彩 凪翔 あやなぎ しょう　　-> NG: 彩凪 翔が正しい
瀬稀 ゆりと せき ゆりと
笙 乃茅桜 しょうの ちお　-> NG: 笙乃 茅桜が正しい
舞乃 ゆか まいの ゆか
貴澄 隼人 たかすみ はやと
天咲 千華 あまさき ちはな
日高 大地 ひだか だいち
月 映樹茉 つきえ じゅま　-> NG: 月映 樹茉が正しい
夢莉 みこ ゆめり みこ
鳳月 杏 ほうづき あん
桃花 ひな ももはな ひな
真那 春人 まな はると
大澄 れい おおすみ れい
銀 華水 ぎんか すい -> NG: 銀華 水が正しい
花城 舞 はなしろ まい
花織 千桜 はなおり ちさ
紫月 音寧 しづき おとね
本城 くれは ほんじょう くれは
風凛水 花 ふうり みずか -> NG: 風凛 水花が正しい
真愛 涼歌 まあい すずか
月野 姫花 つきの ひめか
若夏 あやめ わかなつ あやめ
輝咲 玲央 きざき れお
紗羽 優那 さはね ゆな
貴月 美礼 きづき みれい
安里 舞生 あんり まう
千紗 れいな ちさ れいな
愛那 結梨 あいな ゆうり
神房 佳希 かずさ よしき
花輝 真帆 はなき まほ
剣崎 裕歌 けんざき ゆうか
白百合 ひめ しらゆり ひめ
```