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