「サーバ」と「サーバー」、「PC」と「PC」。同じことを指しているのに、文字として一致しない組み合わせが日本語には数多くあります。
8組で試したところ、そのままでは0組しか一致しません。処理を足していくと7組まで一致しますが、「コーヒー」と「コヒ」も同じ語になりました。
表記ゆれ8組で実際に測りました。処理を足すほど一致は増えますが、長音除去では区別したい語も潰れます。
日本語正規化がどこまで効くのかを、実際に処理を当てて測りました。用意したのは同じことを指す表記の組8つです。
処理は本当に実行しています。組の一覧と、当てる処理の順番はコードに書いてあり、そこを変えれば結果も変わります。
const nfkc = (s) => s.normalize('NFKC'); // 全角半角・互換文字を揃える
const strip = (s) => nfkc(s).replace(/[\s ]/g, ''); // 空白を落とす
const longVowel = (s) => strip(s).replace(/ー/g, ''); // 長音記号を落とす
組 そのまま NFKC 空白除去 長音除去 サーバ / サーバー 不一致 不一致 不一致 一致 ユーザ / ユーザー 不一致 不一致 不一致 一致 キャンセル / キャンセル 不一致 一致 一致 一致 12000円 / 12000円 不一致 一致 一致 一致 出張旅費 / 出張 旅費 不一致 不一致 一致 一致 PC / PC 不一致 一致 一致 一致 問合せ / 問い合わせ 不一致 不一致 不一致 不一致 A社 / A社 不一致 一致 一致 一致 一致した組 そのまま: 0/8 NFKC: 4/8 空白除去: 5/8 長音除去: 7/8 コーヒー と コヒ → 長音除去後: 同じ語になる メール と メル → 長音除去後: 同じ語になる
1行目の「そのまま: 0/8」が出発点です。何もしなければ、8組すべてが別の語として扱われます。
最初に効くのが文字種の統一です。半角カタカナ、全角の数字、全角の英字が揃って、4組が一致しました。
この処理は副作用が小さい部類です。「PC」と「PC」を区別したい場面は、まずありません。
次が空白です。「出張旅費」と「出張 旅費」が一致して5組になりました。入力する人によって空白の入れ方が変わるので、実務では効きます。
ただし英語が混ざる文書では注意が要ります。空白を落とすと、単語の区切りまで消えます。
7組まで届くのが長音の除去です。「サーバ」と「サーバー」、「ユーザ」と「ユーザー」が一致します。日本語のカタカナ語では頻出の揺れです。
ところが同じ処理で、「コーヒー」と「コヒ」、「メール」と「メル」も同じ語になりました。本来は別の語です。
全部当てても「問合せ」と「問い合わせ」は一致しません。送り仮名の違いは、文字を揃えるだけでは解けないためです。
ここは辞書の領域になります。Sudachiのような形態素解析の仕組みが、送り仮名の揺れを吸収する形を持っています。語をどう区切るかが検索の結果を左右する話はBM25の記事で扱っています。
処理を足すほど一致は増える。同時に潰れる語も増える。
DefaultInputTextPlugin normalizes an input text in the following order.原文WorksApplications/Sudachi README この内容の有効期限2027-02-18
比べる前に文字を揃える処理です。文字を揃える段と、語として揃える段に分かれます。
日本語正規化は、検索したり比べたりする前に、表記を揃える処理です。同じことを指す書き方が複数あるという、日本語の性質に対応します。
処理は大きく2段に分かれます。文字そのものを揃える段と、語として揃える段です。
前の節で当てたのは前者です。全角半角、空白、長音記号。文字の見た目を揃えているだけで、意味は見ていません。
後者は形態素解析の領域になります。Sudachiは日本語の形態素解析の仕組みで、文を語に区切ったうえで表記を揃える機能を持っています。
同じREADMEでは、入力の文字を決まった順序で正規化する仕組みが組み込みで用意されていることも書かれています。文字の段も、語の段も、まとめて扱う形です。
文字を揃える処理は、順番によって結果が変わります。先に空白を落としてから語に区切るのと、区切ってから落とすのでは別物になります。
ですから既存の仕組みを使う場合は、どういう順序で処理されるかを確かめてください。自作する場合は、順序を決めて記録に残しておく必要があります。
実装していて間違えやすいのが、片側にしか正規化を当てないことでした。登録するときだけ揃えて、検索するときの語を揃え忘れると当たりません。前の節の測り方も、両側に同じ処理を当てています。
区別したい語が同じものになります。潰れて困る語がないかを、同じ処理で確かめてください。
日本語正規化は足すほど一致が増えますが、増えた一致の中に、本来別であるべき組が混ざります。
前の節の最後を思い出してください。「コーヒー」と「コヒ」が同じ語になりました。長音を消したことによる副作用です。
この副作用は、一致数の表には出てきません。潰れて困る語を別に用意して、同じ処理を当てないと見えません。
語に区切る段でも同じ問題が起きます。Sudachiは3通りの区切り方を用意しており、細かく区切るか、まとめて扱うかを選べます。
細かく区切ると当たりやすくなりますが、関係のない文書まで拾います。まとめて扱うと精度は上がりますが、取りこぼしが増えます。前の節の一致数と同じ構造の釣り合いです。
3番目が要点です。揃えたい組と潰したくない組を、両方そろえて初めて判断できます。
一致数の表には、潰れた語は出てこない。
同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。
出品の仕組みを見る