データの名寄せに必要な正規化で同僚から neologdn
を進められて使おうとしたが、
Python 3.8 に対応していなくて、 unicodedata.normalize()
で事足りたけど、3日前に対応していたお話です。
広告
ユーザの入力値とデータベースを照合して最もマッチする値を取得する実装が必要になり、同僚が neologdn
( PyPI
) を教えてくれたので、さっそうと pip install neologdn
したところ、見事に使えなかった。
$ pip install neologdn ...(なにか大量のコンパイルエラー)
検索して出てくる記事や、 PyPIの配布物 を見たところ、Python 3.7 までのビルド済みパッケージしかなく、 Python 3.8 でビルドが走るがエラーになる、といった具合のようだった。
ユーザの入力値はせいぜいカタカナひらがな数字の半角全角程度の変換だったので、unicodedata.normalize()
で済ませた。
>>> unicodedata.normalize("NFKC", "あいうえお") 'あいうえお' >>> unicodedata.normalize("NFKC", "アイウエオ") 'アイウエオ' >>> unicodedata.normalize("NFKC", "12345.6") '12345.6' >>> unicodedata.normalize("NFKC", "㈱㈲") '(株)(有)'
あとはレーベンシュタイン距離でデータベースに入っている値との類似度で並べ替えることで、無事タスクを完了することができた。
from unicodedata import normalize from Levenshtein import distance onigiri_db = ["ウメボシ", "タラコ", "オカカ"] def lookup_onigiri(input_): with_similarities = [ ( onigiri, distance(onigiri, normalize("NFKC", input_)) / max(len(onigiri), len(input_)), ) for onigiri in onigiri_db ] for onigiri, similarity in sorted(with_similarities, key=lambda elem: elem[1]): print(f"{onigiri}\t{similarity:.4}") if __name__ == "__main__": import sys if len(sys.argv) >= 2: lookup_onigiri(sys.argv[1]) else: print( f""" Usage: {sys.argv[0]} おにぎりの具 """.lstrip() )
$ python similarity.py ウメ ウメボシ 0.5 タラコ 1.0 オカカ 1.0
そしてこの記事に顛末を書いている最中、 pip install neologdn
のコンパイルエラーをもう一度拝もうとしたところ、インストールが無事終了してしまった。
pip install neologdn Collecting neologdn Using cached https://files.pythonhosted.org/packages/12/46/0bb6c64ff8b9c549a3fbdff68240155fb5f938a2563ce5396278973919f0/neologdn-0.5.1.tar.gz Installing collected packages: neologdn Running setup.py install for neologdn ... done Successfully installed neologdn-0.5.1
はて…? と思って PyPI を見たところ、なんと3日前に更新されていたようだ。しかも2年と少しぶりに。
タスクが 2021/05/02 の日中で、PyPIの更新日時が "2021-05-02 20:44:14" 1 なので、半日ほどのすれ違いだったようだ。なんと…。
自身のタスクには間に合わなかったが、同僚が別のタスクで使用する予定だったので非常にタイミングが良かった。
Python自然言語処理101本ノック:: ~基礎からBERTまで~ (神草出版)
- 作者:神草 経知
- 発売日: 2020/07/25
- メディア: Kindle版
-
スクリーンショットで示した PyPI の日付にマウスオーバーすると表示される↩