Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python製の姓名分割 ライブラリをGoに移植した話

Python製の姓名分割 ライブラリをGoに移植した話

# 背景
Go Conference 2020 SpringでLTしました。
https://gocon.jp/2022spring/sessions/lt2/

# 概要
一般的にわかち書きでは無い日本語で姓名から「姓+名」の分割を行うことは困難です。 しかし、Python製の姓名分割ライブラリ(https://github.com/rskmoi/namedivider-python)を用いるとある程度精度良く分割は可能です。 そこでシングルバイナリで扱えるGoのメリットを活かして、Python製の姓名分割ライブラリをGoに移植した話をします。 その際移植で工夫した点や気をつけた点をお話します。

# 参考
## 作成したcli
https://github.com/glassmonkey/seimei

## 移植元のpythonライブラリです
https://github.com/rskmoi/namedivider-python

## テストデータ
User Local様のツールを利用しました。
https://testdata.userlocal.jp/

## ベンチマークに使用したツール
https://github.com/sharkdp/hyperfine

glassmonenkey

April 23, 2022
Tweet

More Decks by glassmonenkey

Other Decks in Technology

Transcript

  1. © 2012-2022 BASE, Inc. 1
    Python製の姓名分割
    ライブラリをGoに移植した話
    BASE inc, Shunsuke Nagano
    (@glassmonenkey)

    View Slide

  2. © 2012-2022 BASE, Inc. 2
    #gocon
    @glassmonekey
    自己紹介
    所属
    BASE 株式会社 BASE BANKチーム Engineering Program Manager
    資金調達プロダクト「YELL BANK」の開発責任者やってます。
    Go, PHP, Pythonを書きつつ時々データエンジニアも。
    趣味
    Flutterアプリ開発
    hasura.ioやsupabaseがマイブーム
    SNS
    Twitter:@glassmonekey 
    Github: https://github.com/glassmonkey
    永野 峻輔 (ながの しゅんすけ)
    去年のGoconで発表したこと

    View Slide

  3. © 2012-2022 BASE, Inc. 3
    #gocon
    @glassmonekey
    今日話すこと
    ● 姓名を分割するCLIツールの紹介
    ● 移植元のPython製OSSの紹介
    ● Goに移植した理由
    ● 性能実験などの結果

    View Slide

  4. © 2012-2022 BASE, Inc. 4
    © 2012-2022 BASE, Inc. 4
    姓名分割について

    View Slide

  5. © 2012-2022 BASE, Inc. 5
    #gocon
    @glassmonekey
    竈門炭治郎
    → 「竈門」「炭治郎」?

    View Slide

  6. © 2012-2022 BASE, Inc. 6
    #gocon
    @glassmonekey
    Goで姓名分割を実現する
    「seimei」を作りました

    View Slide

  7. © 2012-2022 BASE, Inc. 7
    #gocon
    @glassmonekey
    -nameで分割したいフルネーム
    -parseで分割文字列 (デフォルトは半角スペース)
    Python製のrskmoi/namedivider-python を移植
    詳しくはhttps://github.com/glassmonkey/seimeiを見てね

    View Slide

  8. © 2012-2022 BASE, Inc. 8
    © 2012-2022 BASE, Inc. 8
    Python製姓名分割
    OSSの紹介

    View Slide

  9. © 2012-2022 BASE, Inc. 9
    #gocon
    @glassmonekey
    rskmoi/namedivider-python
    https://github.com/rskmoi/namedivider-python
    name の場合は名前分割
    file経由で複数分割も可能
    api用のコンテナも用意されている

    View Slide

  10. © 2012-2022 BASE, Inc. 10
    #gocon
    @glassmonekey
    分割アルゴリズム
    ● ルールベース
    ○ 2文字の場合のみ適応
    ■ 乙一 → 「乙」「一」
    ● 統計量ベース
    ○ 特徴量から最良のパターンを採用する
    ■ 篠田麻里子 → 「篠」「田麻里子」OR 「篠田」「麻里子」etc…

    View Slide

  11. © 2012-2022 BASE, Inc. 11
    #gocon
    @glassmonekey
    2つの特徴量
    ● Order Point
    ○ 文字の出現順序に着目
    ■ 篠田麻里子 → 「篠田」 「麻里子」
    ● Length Point
    ○ 名字 or 名前の長さに着目
    ■ 松高子 →「松」 「高子」
    ■ 松高萌 →「松高」 「萌」
    姓名分割プログラムをつくる-手法編-

    View Slide

  12. © 2012-2022 BASE, Inc. 12
    #gocon
    @glassmonekey
    2つの特徴量の関係
    姓名分割プログラムをつくる-訂正編-
    青が不正解
    赤が正解
    OrderPoint + LengthPoint
    が最大が最良

    View Slide

  13. © 2012-2022 BASE, Inc. 13
    © 2012-2022 BASE, Inc. 13
    なぜ移植しようと思ったのか

    View Slide

  14. © 2012-2022 BASE, Inc. 14
    #gocon
    @glassmonekey
    Goへの移植理由
    ● Python製故のRuntimeの不安定さ
    ○ 例えばPythonのバージョン
    ○ Goならシングルバイナリに
    ● 統計量マスターデータがcsvでディスクIOがある
    ○ きちんと計測したわけではないが
    ○ go:embedの使い所

    View Slide

  15. © 2012-2022 BASE, Inc. 15
    © 2012-2022 BASE, Inc. 15
    動作検証

    View Slide

  16. © 2012-2022 BASE, Inc. 16
    #gocon
    @glassmonekey
    検証データ
    User Local社のジェネレータで1万名の人名を生成して検証した
    https://testdata.userlocal.jp/
    江島 二朗
    海老原 貴子
    中橋 仁史
    水落 剛
    竹内 昭太
    緒方 聖司
    柿澤 紀子

    姓_名 の形式

    View Slide

  17. © 2012-2022 BASE, Inc. 17
    #gocon
    @glassmonekey
    回帰テスト
    input := “田中太郎” // 実際は検証用人名データが代入される
    origin, err := exec.Command("nmdiv", "name", input).Output() // 移植外部実行
    if err != nil {…}
    out := &bytes.Buffer{}
    err = seimei.Run(out, input, " ") // 該当コード
    if err != nil {…}
    if out.String() != string(origin) {…}
    移植元のツールを外部実行した結果と照らし合わせてみる

    View Slide

  18. © 2012-2022 BASE, Inc. 18
    #gocon
    @glassmonekey
    完全一致だった
    安心😂

    View Slide

  19. © 2012-2022 BASE, Inc. 19
    #gocon
    @glassmonekey
    正答率の検証
    orig := “田中 太郎” // 実際は検証データの正解データが代入される
    input :=
    s
    trings.ReplaceAll(orig, " ", "") // スペースを消して入力データを作成
    want := fmt.Sprintf("%s\n", orig) // 出力は改行を含むので加工
    out := &bytes.Buffer{}
    err := seimei.Run(out, input, " ")
    if err != nil {…}
    if out.String() != want {...}
    検証データと実行データの差分を見てみる

    View Slide

  20. © 2012-2022 BASE, Inc. 20
    #gocon
    @glassmonekey
    正解率は99.52%
    10,000件中48件が失敗

    View Slide

  21. © 2012-2022 BASE, Inc. 21
    #gocon
    @glassmonekey
    ○正解
    倉 光浩
    大友 由佳
    本多 次郎
    伊達 雄
    倉光 浩
    伊 達雄
    大 友由佳
    本 多次郎
    失敗例
    ✗不正解
    光が姓の終端?
    達が名の先頭?
    友が名の先頭?
    本が姓の終端?

    View Slide

  22. © 2012-2022 BASE, Inc. 22
    © 2012-2022 BASE, Inc. 22
    性能比較

    View Slide

  23. © 2012-2022 BASE, Inc. 23
    #gocon
    @glassmonekey
    環境
    ● MacOS (Bigsur v11.6.5)
    ● 2.3 GHz 8コアIntel Core i9
    ● 32 GB 2400 MHz DDR4
    ● 使用ツールはhyperfine(1.13)

    View Slide

  24. © 2012-2022 BASE, Inc. 24
    #gocon
    @glassmonekey
    hyperfineについて
    Rust製のcliベンチマークツール
    ウォームアップ用のオプションもあり便利

    View Slide

  25. © 2012-2022 BASE, Inc. 25
    #gocon
    @glassmonekey
    ルールベースの性能
     約98%削減

    View Slide

  26. © 2012-2022 BASE, Inc. 26
    #gocon
    @glassmonekey
    統計量ベースの性能
     約90%削減

    View Slide

  27. © 2012-2022 BASE, Inc. 27
    © 2012-2022 BASE, Inc. 27
    感想

    View Slide

  28. © 2012-2022 BASE, Inc. 28
    #gocon
    @glassmonekey
    感想
    ● Goに移植することでCLIとしての利便性は上がったと思う。
    ○ マスターデータを作るための分析などを考えるとPythonも捨てがたい
    ○ ケースバイケース
    ● ライブラリの作者の方(@rskmoiさん)から連絡が来るという嬉しい出来事
    ○ 自分ができることを少し加えて世の中をよくできるという実感
    ○ 元OSSの方にもフィードバックは適宜していきたい
    ○ 今回の実験結果はFB中

    View Slide

  29. © 2012-2022 BASE, Inc. 29
    #gocon
    @glassmonekey
    We are hiring !!
    フルサイクル開発やってます!!
    興味あったらDM待ってます!!

    View Slide