2021年9月8日水曜日

CEDEC でやってた表記ゆれ検出をお試し実装してみた

CEDEC2021: ゲーム制作効率化のためのAIによる画像認識・自然言語処理への取り組み
ゲーム制作効率化のためのAIによる画像認識・自然言語処理への取り組み - Speaker Deck

こちらの講演の中であった表記ゆれ検出の実装実験をしてみました。
ポイントとなるのは「形態素解析」と「編集距離」です。

形態素解析はこのブログでもたまに扱ってました。
ブログズミ: TreeTagger を使ってソースコード中の単語をリストアップしてみた
ブログズミ: ソースコード中の単語からの略語/スペルミス検出に挑戦

↑これらは TreeTagger 使ったものでした。

実は、前職でも同じような表記ゆれ検出はしたことがあって、そのときは MeCab で形態素解析し、単語の出現数をカウントしてソート出力するだけのものでした。
出現数の少ない単語から見ていくと、「あ、これは揺れてそう」ってのがわかったのでそれなりに有用でした。
なので、CEDEC の方法であった「出現数の差が大きいほどスコアが上がる」は良いと思いました。

で、今回は形態素解析には Jumanpp を編集距離はレーベンシュタイン距離を使いました。
実装はこちら。
講演の内容そのものの実装ではないです。スコア計算の部分はテスト対象の入力に合わせて書いたので万能ではないと思いますが、なるべく一般化したルールにしてるつもり。

https://github.com/srz-zumix/tails-of-words

PyPI でも公開してるので pip でインストールできます。
https://pypi.org/project/tails-of-words/0.1.2/
また Dockerhub にイメージもおいてるのでそれ使っても実行できます。
https://hub.docker.com/r/srzzumix/tails-of-words

実装メモ

実装上のポイントをメモしてます。

  • yomi がひらがなの場合とカタカナの場合がある
  • yomi に長音(ー)が追加される場合がある
  • 総当りで調べるのですべての単語差分を記録すると killed される
  • 半角スペース、"、@、# を含んでると pknp で例外出るので全角にする
  • 「えー!?」のように全角!・?があると、つながった状態で1単語になるので、分解するため半角にする

テスト

試しに拙著をチェックしてみました。

拙著の場合、未定義語(15)まで集計対象にするとアルファベットのみの単語の大文字・小文字違いがスコアが高くなり、ノイズだったので -i 6 で名詞のみに制限。
-t 1 で 1.0 以上のスコアのものを表示してます。

画像をご覧いただくと、「コンパイラー vs コンパイラ」の表記ゆれを検出してるのが見つかります。それ以外は表記ゆれではないと思いますが、書き損じの可能性はあるかもしれませんね。

最後に

実装自体は1日、スコア計算の部分とかの調整で1日。
あとは周辺機能の整理とかで1日くらいですかね。
(仕事じゃなくて夜中に書いてたやつなので工数じゃないよ)

とりあえず最低限のものを作るだけなら、めちゃくちゃ簡単にできます。
ただし、精度はいまいちだと思います。
リストアップされたものを人間がチェックする必要性がありますが、リストアップする部分まで人間がやるよりはかなりマシでしょう。

ここから検出精度を上げるのはとても大変だと思います。
トライアンドエラーで色々評価軸を追加したり、スコア計算の調整したりすることになると思いますが、コスパがどんどん悪くなっていくと思います。
(業務外だったら関係ないのかもしれないけど・・)
流行りの機械学習で精度アップできるかもしれないですが、どうなんでしょうね?
(この辺は詳しくないのでわかりません)

実はこの手の話をすると、似たようなこと昔やったことあるって人が結構います。
みんなサクッと実装できたといいますが、精度・コスパの話も同じような感想でした。

これは完全な余談なんですが、
Jumanpp の出力をいい感じに print したいなーと思って Power-Assert みたいな出力にしようと(すぐ道草をする悪い癖が出そうになったのを我慢)して、適当に作った print が割といい感じにできたのが良かった :D


対して難しいことはしてませんが、この実装が役に立てば幸いです。
では。

0 件のコメント:

コメントを投稿