[groonga-dev,01300] Re: 複数カラムのスコアリングについて

Back to archive index

Kouhei Sutou kou****@clear*****
2013年 4月 19日 (金) 11:38:44 JST


須藤です。

In <CADTaU+Y=vMUJq=swPoe****@mail*****>
  "[groonga-dev,01299] 複数カラムのスコアリングについて" on Thu, 18 Apr 2013 19:17:59 +0900,
  Tokuhiro Matsuno <tokuh****@gmail*****> wrote:

> groonga を http でつかっているのですが、スコアリングについて悩んでおりまして、教えていただけるとありがたいです。
> 
> スキーマで "kanji" と "yomigana" というカラムがあったときに、
> 
>   --match_columns kanji || yomigana --sortby -_score
> 
> などとしたいのですが、こうしますと、kanji が "けいおん!" で yomigana が "けいおん"なものの方が、kanji が
> "ケイト・スペード" で yomigana が "けいと・すぺーど" のものより高く評価されてしまいます。
> 
> このように、2つのカラムでマッチしても、スコアをおなじにする、すなわち _score = max(_score_of_kanji,
> _score_of_yomigana) のような処理をする方法はありますでしょうか?

少し強引なので、もう少しすっきりしたやり方がありそうな気はし
ますが。。。

groongaはスコアは必ず_scoreに入るため、複数のスコアを別々に
扱いたい場合は_scoreへの入れ方を工夫する必要があります。どう
工夫するかというと桁をずらします。

今回はkanjiとyomiganaで別々に扱いたいということなので、

  * kanjiのスコアは_scoreの1万の位に入れる
  * yomiganaのスコアは_scoreの100の位に入れる

と決めます。それぞれのスコアの桁の差は最大でどのくらいのスコ
アになるかで決めます。10以上にならないだろうということであれ
ば、1桁ずらすだけで大丈夫です。↑のやり方では99まで大丈夫で
す。

groongaのクエリの書き方で言うと、

  --match_columns 'kanji * 10000 || yomigana * 100'

となります。

その後、スコアを扱いたい時に_scoreをデコードして該当するスコ
アを抽出します。

groongaのクエリの書き方で言うと、

  --scorer '_score = max(_score / 10000, _score % 10000 / 100)'

となります。

ちなみに、この例では100の位と1の位だけ使った方がもっとシンプ
ルだったりします。


実際に動く例が以下になります。

table_create  Movies          TABLE_NO_KEY
column_create Movies kanji    COLUMN_SCALAR ShortText
column_create Movies yomigana COLUMN_SCALAR ShortText

table_create  Terms                TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram
column_create Terms kanji_index    COLUMN_INDEX|WITH_POSITION Movies kanji
column_create Terms yomigana_index COLUMN_INDEX|WITH_POSITION Movies yomigana

load --table Movies
[
{"kanji": "けいおん!",      "yomigana": "けいおん"},
{"kanji": "ケイト・スペード", "yomigana": "けいと・すぺーど"}
]

select Movies \
  --match_columns 'kanji * 10000 || yomigana * 100' \
  --query 'けいおん' \
  --scorer '_score = max(_score / 10000, _score % 10000 / 100)' \
  --output_columns kanji,_score
# ->
# [[0,1366338562.82411,0.000585556030273438],
#  [[[1],
#    [["kanji","ShortText"],["_score","Int32"]],
#    ["けいおん!",1]]]]

select Movies \
  --match_columns 'kanji * 10000 || yomigana * 100' \
  --query 'けいと' \
  --scorer '_score = max(_score / 10000, _score % 10000 / 100)' \
  --output_columns kanji,_score
# ->
# [[0,1366338562.82473,0.00044560432434082],
#  [[[1],
#    [["kanji","ShortText"],["_score","Int32"]],
#    ["ケイト・スペード",1]]]]


という感じで実現はできるのですが、なんかもっとすんなりできな
いかなぁという気はします。

-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)

groongaサポート:
  http://groonga.org/ja/support/
パッチ採用はじめました:
  http://www.clear-code.com/recruitment/
コミットへのコメントサービスはじめました:
  http://www.clear-code.com/services/commit-comment.html




groonga-dev メーリングリストの案内
Back to archive index