文字正規化と形態素解析
辞書のエントリをふやさず多様な入力に対応するために、形態素解析をかける前に文字を正規化するのが一般的です。よくおこなわれるのがアルファベットの小文字化や Unicode 正規化です。場合によってはおなじ文字の連続をみじかくしたり、混同されやすいマイナス記号に類似する文字をマイナス記号や長音記号に統制することもあります。
正規化によって分解される文字への対応
文字正規化によって1文字が複数の文字に分解されることがあります。
irb(main):001:0> '…'.unicode_normalize(:nfkc)
=> "..."
irb(main):002:0> '㈱'.unicode_normalize(:nfkc)
=> "(株)"
この正規化後の文字列を形態素解析にかけると以下のように複数の形態素になります。
$ echo ... | java -jar sudachi-0.5.3.jar
. 補助記号,句点,*,*,*,* .
. 補助記号,句点,*,*,*,* .
. 補助記号,句点,*,*,*,* .
EOS
さて、この結果をもとの文字列と対応づけるにはどうすればいいでしょうか。2つの案がかんがえられます。
案1
それぞれの形態素をもとの文字列と対応づける。
… 補助記号,句点,*,*,*,* .
… 補助記号,句点,*,*,*,* .
… 補助記号,句点,*,*,*,* .
EOS
案2
特定の形態素だけ (この場合は先頭) を対応づけてそれ以外は対応なし (空文字列) とする。
… 補助記号,句点,*,*,*,* .
補助記号,句点,*,*,*,* .
補助記号,句点,*,*,*,* .
EOS
元文字列での位置
全文検索でヒットした語をハイライティングするなどの用途には元文字列上の位置が必要です。
元文字列上での位置を(開始位置,終了位置)
1の形式で書くと、案1は (0,1)(0,1)(0,1)
となります。
案2の表現方法はいくつかかんがえられますが、位置の前後関係と文字長を素直にあらわす (0,1)(1,1)(1,1)
とするのが妥当でしょう。
どちらがよいか
案1は単純ですが同一位置が繰り返し出力されるので出力結果を合成しても入力を再現できません。複数のツールを組み合わせてつかうにはよくない性質です。2
案2は入力の再現性は保たれていますが、元文字列上で空文字列の形態素が発生します。世の中には分割結果に長さ0のトークンがふくまれていると想定していないツールもあり、おもわぬ不具合の原因になることがあります。
形態素解析器 Sudachi では入力の再現性を重視して案2をデフォルトの動作としています。
$ echo … | java -jar sudachi-0.5.3.jar
… 補助記号,句点,*,*,*,* .
補助記号,句点,*,*,*,* .
補助記号,句点,*,*,*,* .
EOS
ですが、空文字列をあつかえないツールにもつなげるようにしぶしぶ allowEmptyMorpheme
という設定を用意しています。
$ echo … | java -jar sudachi-0.5.3.jar -s '{"allowEmptyMorpheme":false}'
… 補助記号,句点,*,*,*,* .
… 補助記号,句点,*,*,*,* .
… 補助記号,句点,*,*,*,* .
EOS
デフォルトは true
です。プロパティ名が長いのはせめてもの抵抗です。
ではよい Sudachi life を。