ASEホーム サイトマップ 交通アクセス お問い合わせ chineese english
             
                                          
最近の技術情報  一覧

                 
 


                 
 


                 
 


                 
 


                 
 


                 
 


                 
 


                 
 


                 
 


                 
 


                 
 


 
トップページ > 技術情報 > その他

UTL_MATCHで行う文字列比較(Oracle)

2009年10月20日

oracle
 

二つの文字列がどの程度異なっているかを示す数値として Levenshtein距離 Jaro-Winkler距離 というものがあることを最近知りました。

ものすごく簡単に言うと、片方の文字列をもう一方の文字列に変換するためには、置換、挿入、削除を何回行う必要があるかという観点で二つの文字列の相違度を数値化しようとするものらしいです。

internet 上には、色々な方がこれらの算出ロジックを様々言語でインプリメントした例が見られますが、なんとORACLEの10gR2以降のバージョンには"UTL_MATCH"というパッケージで標準にこれらの機能が実装されていました。

このUTL_MATCHパッケージには次の4つのファンクションが用意されています。

  • EDIT_DISTANCE
  • EDIT_DISTANCE_SIMILARITY
  • JARO_WINKLER
  • JARO_WINKLER_SIMILARITY

後ろに"_SIMILARITY"がついているファンクションは、二つの文字列の類似度を0~100のスコアであらわした数値を返してくれます。100なら完全に一致している、0なら全く一致していないということですね。

というわけで、早速手元のORACLE XEで実験してみたいと思います。

SELECT UTL_MATCH.EDIT_DISTANCE('Sapporo','Nopporo') AS EDIT_DISTANCE FROM DUAL;

EDIT_DISTANCE
-------------
         2

SELECT UTL_MATCH.EDIT_DISTANCE_SIMILARITY('Sapporo','Nopporo') AS EDIT_DISTANCE_SIMILARITY FROM DUAL;

EDIT_DISTANCE_SIMILARITY
------------------------
                   72

SELECT UTL_MATCH.JARO_WINKLER('Sapporo','Nopporo') AS JARO_WINKLER FROM DUAL;

JARO_WINKLER
-------------
   8.095E-001

SELECT UTL_MATCH.JARO_WINKLER_SIMILARITY('Sapporo','Nopporo') AS JARO_WINKLER_SIMILARITY FROM DUAL;

JARO_WINKLER_SIMILARITY
-----------------------
                  80
 

ほぼインストールしたそのままの状態のデータベースなのですが、何の問題も無く実行できました。

EDIT_DISTANCEは分かりやすいですね。'Sapporo'と'Nopporo'では先頭の二文字を置換すればよいので操作が2回必要ということが分かります。また、EDIT_DISTANCEとJARO_WINKLERでは、後者の方が比較的スコアは高く出るようです。


SELECT UTL_MATCH.EDIT_DISTANCE_SIMILARITY('Sapporo','Sappoki') AS EDIT_DISTANCE_SIMILARITY FROM DUAL;

EDIT_DISTANCE_SIMILARITY
------------------------
                   72

SELECT UTL_MATCH.JARO_WINKLER_SIMILARITY('Sapporo','Sappoki') AS JARO_WINKLER_SIMILARITY FROM DUAL;

JARO_WINKLER_SIMILARITY
-----------------------
                  88
 


今度は末尾の二文字が異なるパターンです。EDIT_DISTANCEの方はスコアは変わりませんが、JARO_WINKLERの方は先頭二文字が異なる場合と比べてスコアが高くなっています。

JARO_WINKLERのロジックでは二つの文字列の間の差異が先頭に近いほどスコアは低くなるという傾向があります。一般的にスペルミスをする場合も先頭の文字から間違うことは少ないということを反映しているようです。

なお、今回使用しているORACLEはキャラクタセットがSJISのデータベースなのですが、日本語の比較は難しいようです。


SELECT UTL_MATCH.EDIT_DISTANCE_SIMILARITY('あいうえお','かきくけこ') AS EDIT_DISTANCE_SIMILARITY FROM DUAL;

EDIT_DISTANCE_SIMILARITY
------------------------
                   50

SELECT UTL_MATCH.JARO_WINKLER_SIMILARITY('あいうえお','かきくけこ') AS JARO_WINKLER_SIMILARITY FROM DUAL;

JARO_WINKLER_SIMILARITY
-----------------------
                  70
 

といったように全く異なる文字列でも、0ではないスコアが算出されてしまいます。キャラクタセットをUTF-8とかにするともしかしたらうまくいくのかもしれませんが、手元で環境が作れないのでまたの機会に検証してみようと思います。

他にも色々と試してみたいパターンはあるのですが、今日のところはこの辺で。




このエントリーをはてなブックマークに追加
 
現在ページの上部へ戻る