テキストデータの前処理:表記揺れ、正規化#

表記ゆれと正規化#

同じものを表す文字列が複数あることを 表記ゆれ という。

同じものを一意な文字列に揃えることを 正規化 (normalization) という。

自分で正規化のルールを書いてもいいが、便利なパッケージもある。

unicodedata パッケージ#

Pythonに標準で入っているunicodedataパッケージを使う方法

import unicodedata
unicodedata.normalize("NFKC", "金額は¥1680です")
# -> '金額は¥1680です'
unicodedata.normalize("NFKC", "㈱")
# -> '(株)'

参考:Unicode正規化 - Wikipedia

neologdn パッケージ#

MeCabのために作られた正規化パッケージ。

細かなパラメータ調整は難しそう(この正規化の機能は無効化したい、とかはできなさそう)だが、手軽に高機能な強い正規化を掛けられる

ikegami-yukino/neologdn: Japanese text normalizer for mecab-neologd

import neologdn
neologdn.normalize("ハンカクカナ")
# => 'ハンカクカナ'
neologdn.normalize("全角記号!?@#")
# => '全角記号!?@#'
neologdn.normalize("全角記号例外「・」")
# => '全角記号例外「・」'
neologdn.normalize("いろんなハイフン˗֊‐‑‒–⁃⁻₋−")
# => 'いろんなハイフン-'
neologdn.normalize("   PRML  副 読 本   ")
# => 'PRML副読本'

文字列の距離#

似てる表現の文字列については同じものを指していると考えて統合させて正規化する方法も考えられる。そのために、同じものを指している表記揺れ表現たちは「距離」が近くなるような尺度が欲しくなる。

文字列同士の距離を測りたいとき、大別して以下の方法がある

  1. 文字たちの類似度を測る

  2. 文字列をベクトルに埋め込んで、ベクトル間の類似度を測る

「1. 文字たちの類似度を測る」はレーベンシュタイン距離が最も有名。

「2. 文字列をベクトルに埋め込んで、ベクトル間の類似度を測る」の代表例にはTF-IDFやWord2Vecなどがある。

レーベンシュタイン距離#

レーベンシュタイン距離(編集距離)は2つの文字列についての距離であり、1文字の挿入・削除・置換によって、一方の文字列をもう一方の文字列に変形するのに必要な手順の最小回数を意味する。

from rapidfuzz.distance import DamerauLevenshtein
DamerauLevenshtein.distance("CA", "ABC")
2
DamerauLevenshtein.distance("トヨタ自動車株式会社", "トヨタ自動車")
4
DamerauLevenshtein.normalized_similarity("トヨタ自動車株式会社", "トヨタ自動車")
0.6
DamerauLevenshtein.normalized_similarity("トヨタ自動車株式会社", "日産自動車")
0.30000000000000004