Tasuku SUENAGA
a****@razil*****
2006年 9月 14日 (木) 23:43:00 JST
末永です。 ちょっと長文になっちゃいました。 > Senna の N-gram インデックスについて以下のような事例から、1byte のインデッ > クスについては、分かち書きになっている??との疑問を持ちましたのでメール > させていただきました。 SennaのN-gramは、いわゆるアルファベット、数字、記号については、 連続している同じ種類の文字は 1つの単語として切り出すようにしています。 さて、MySQL経由でSennaインデックスを作成する場合、 デフォルトで「NORMALIZE」という正規化を行うフラグが立ちます。 正規化とは、A->aやA->aのように 文字列をある単一の形に合わせる処理です。 この正規化の際に、個々の文字の文字種を判定しています。 正規化を行わない場合、文字種判定は行われません。 [Senna-dev 336]で島村さんが指摘されているとおり、 NO NORMALIZEを指定すると、 正規化処理によって行われる文字種判定が行われず、 すべてが同じ文字種と判定され、 したがって宮本さんが想定されるようなN-gramでの切り出しが行われます。 (これは、将来的には修正されるべきだと認識しています) しかし、NO NORMALIZEを指定した場合には、 たとえば「Smap」で「SMAP」を検索することができません。 -- さて、N-gram時に「perl」という単語が インデックスされているとしましょう。 Sennaでは、アルファベット・数字・記号からなる単語について、 前方一致検索しか対応しておりません。 それ以外の文字からなる単語は、 前方一致検索も後方一致検索も可能です。 よって、「per」では検索できますが、「erl」では検索できません。 理由としては、 英単語は語尾の変更はよくあるが、 語幹の変更が少ないためです。 インデックスサイズを減らし、 検索速度を向上し、 さらにノイズが少ない検索を実現するために、 ニーズが低いと考えられる単語については インデックスしないようにしています。 -- ちなみに、今回の話題とは直接は関係ないですが、 デフォルトのクエリでは、 他に「per」という単語を含む文書がある場合、 「perl」を含んだ文書は結果に含まれません。 これは、完全一致する単語のみを結果に含めることによって、 精度の高い(適合率の高い)検索を実現するためです。 -- 宮本さんがどのような用途にSennaを利用されるかにもよるのですが、 「型番に対する高速なLIKE検索を行いたい」、といった用途であった場合、 Sennaの設計で想定していた問題領域と少しズレてしまいます。 なお、Sennaの内部に手を入れれば、 完全なN-gramインデックスの作成も、 アルファベット単語の後方一致検索も可能となります。