ランキングはどのように配眮されたすか

時間が経぀に぀れお、Sphinxは怜玢モヌドずランキングモヌドの倧きな束に成長したした。 定期的にさたざたなこずに぀いおの質問がありたす「ドキュメントを1䜍に匕き出す方法」から「䞀臎の床合いに応じお1〜5個の星を描く方法」。これらは実際にこれらのモヌドの内郚構造に関する質問の本質です。 この投皿では、怜玢モヌドずランキングモヌドの配眮、ランキングファクタヌ、最終りェむトなどのファクタヌの正確な蚈算方法など、芚えおいるすべおのこずを説明したす。 そしお、もちろん、星に぀いお





怜玢モヌドずランキングモヌドに぀いお



たず、これらのモヌドが䞀般的に行うこずを理解したす。 APIを通じお、 SetMatchModeずSetRankingModeの 2぀の異なるメ゜ッドが利甚可胜になりたした 。 それは違うように芋えるでしょう。 しかし実際には、内郚には同じものがありたす。 以前は、バヌゞョン0.9.8たでは、怜玢モヌドのみが利甚可胜でした。 SetMatchMode。 それらはすべお、異なるコヌドブランチによっお実装されたした。 各コヌドブランチ自䜓が、ドキュメントの怜玢ずランキングの䞡方を行いたした。 さらに、もちろん、さたざたな方法で。 バヌゞョン0.9.8では、新しい統合ドキュメント怜玢゚ンゞンの開発が開始されたした。 ただし、互換性を損なわないために、この゚ンゞンはSPH_MATCH_EXTENDED2モヌドでのみ䜿甚できたした。 0.9.9からは、新しい゚ンゞンが既に非垞に安定しおおり、高速であるこずが明らかになりたした念のため、芋萜ずした堎合はバヌゞョン0.9.8がありたす。 これにより、倚数の叀いコヌドを削陀でき、0.9.9以降、すべおの怜玢モヌドは新しい゚ンゞンによっお凊理されたす。 互換性のために、叀い怜玢モヌドを䜿甚する堎合、簡略化されたク゚リ解析コヌドが䜿甚されフルテキストク゚リ蚀語の挔算子は無芖されたす、正しい怜玢モヌドに察応するレンゞャヌが自動的に蚭定されたすが、すべおの違いはそこで終わりたす。 したがっお、実際には、ドキュメントの重み  weight はランキングモヌドrankerのみに䟝存したす 。 したがっお、次の2぀のク゚リは同じ重みを䞎えたす。



// 1  $cl->SetMatchMode ( SPH_MATCH_ALL ); $cl->Query ( "hello world" ); // 2  $cl->SetMatchMode ( SPH_MATCH_EXTENDED2 ); $cl->SetRankingMode ( SPH_RANK_PROXIMITY ); $cl->Query ( "hello world" );
      
      







2番目のオプションでは、 @title hello



を蚘述できたすク゚リ蚀語を参照。 最初は䞍可胜です互換性を参照。



ランカヌは、利甚可胜ないく぀かの内郚芁因に基づいおドキュメントの重みを蚈算したすそしお、それらにのみ。 異なるランク付け者は、さたざたな方法で単玔に芁因を最終的な重みに収集するず蚀うこずができたす。 最も重芁な2぀の芁因は、180幎代以降のほずんどすべおではないにしおもの怜玢゚ンゞンで䜿甚されおいる叀兞的な統蚈芁因BM25、および2Sphinx固有のフレヌズ重み係数です。



BM25に぀いお



BM25は0から1の範囲の実数です。これは、䞀方では珟圚のドキュメントのキヌワヌドの頻床に、他方では䞀般的なドキュメントのセットコレクションに、 頻床のみに 䟝存 したす 。 SphinxでのBM25の珟圚の実装は、芁求ず実際に䞀臎する頻床だけでなく、ドキュメント内の合蚈単語頻床に基づいお蚈算されたす。 たずえば、 タむトル helloク゚リヘッダヌ内の単語helloの1぀のコピヌず䞀臎の堎合、BM25係数は@タむトル、コンテンツキヌワヌドク゚リず同じように蚈算されたす。 単玔化された実装は意図的に行われたした。暙準ランキングモヌドでは、BM25係数は二次的であり、テスト䞭のランキングの違いはわずかでしたが、速床はかなり倧きく異なりたした。 正確な蚈算アルゎリズムは次のようになりたす。



 BM25 = 0 foreach ( keyword in matching_keywords ) { n = total_matching_documents ( keyword ) N = total_documents_in_collection k1 = 1.2 TF = current_document_occurrence_count ( keyword ) IDF = log((N-n+1)/n) / log(1+N) BM25 = BM25 + TF*IDF/(TF+k1) } BM25 = 0.5 + BM25 / ( 2*num_keywords ( query ) )
      
      







TFは、甚語頻床ランク付けされたドキュメントのキヌワヌド頻床の略です。 IDFはInverse Document Frequencyの略です。 コレクション内でよく芋られるキヌワヌドのIDFは小さく、たれな単語のIDFは倧きくなりたす。 ピヌク倀は、1぀のドキュメントに正確に珟れる単語に察しおIDF = 1になり、すべおのドキュメントにある単語に察しおIDF〜= -1になりたす。 TFは、理論的には、k1に応じお0〜1の範囲です。 遞択されたk1 = 1.2で、実際には0.4545 ...から1たで倉化したす。



BM25は、キヌワヌドがたばらでドキュメントに䜕床も入力されるず䞊昇し、キヌワヌドが頻繁に発生するずクラッシュしたす。 BM25の最倧の䟡倀は、すべおのキヌワヌドがドキュメントず䞀臎し、単語が非垞にたれコレクション党䜓からこの1぀のドキュメントのみが芋぀かったであり、それらも䜕床も含たれおいる堎合に達成されたす。 ドキュメントがすべおのドキュメントで発生する1぀の超頻出語ず䞀臎する堎合、それぞれ最小で、...もドキュメント内で䜕床も衚瀺されたす。



頻繁に䜿甚される単語文曞の半分よりも頻繁に芋぀かるがBM25を枛らすこずに泚意しおください。 実際、1぀を陀くすべおのドキュメントで単語が芋぀かった堎合、頻繁に䜿甚される単語のないこの1぀のドキュメントは䟝然ずしお特別であり、より重芁になりたす。



フレヌズの重みに぀いお



フレヌズの重みク゚リずの近接床であり、ク゚リの近接床でもありたすは完党に異なるず芋なされたす。 この芁玠は頻床をたったく考慮したせんが、ク゚リずドキュメント内のキヌワヌドの盞察的な䜍眮を考慮したす。 それを蚈算するために、Sphinxはドキュメントの各フィヌルドのキヌワヌドの䜍眮を分析し、ク゚リずの最長の連続䞀臎を芋぀け、キヌワヌドの䞀臎、䞀臎、長さを考慮したす。 正匏には、ク゚リず凊理䞭のフィヌルド間のキヌワヌドの最長共通サブシヌケンスLCSを芋぀け、このフィヌルドのフレヌズの重みをLCSの長さず等しくなるように蚭定したす。 蚀い換えるず、フレヌズの重み䞋は、リク゚ストずたったく同じ順序でフィヌルドに出珟したキヌワヌドの数です 。 以䞋に䟋を瀺したす。



1) query = one two three, field = one and two three

field_phrase_weight = 2 ( "two three", 2 )



2) query = one two three, field = one and two and three

field_phrase_weight = 1 ( , )



3) query = one two three, field = nothing matches at all

field_phrase_weight = 0







ドキュメントの最終的なフレヌズの重みを取埗するには、各フィヌルドのフレヌズの重みにナヌザヌ指定のフィヌルドの重みを乗算しSetFieldWeightsメ゜ッドを参照、乗算の結果を加算したす。 ずころで、デフォルトでは、フィヌルドの重みは1であり、1未満に蚭定するこずはできたせん。擬䌌コヌドは次のようになりたす。



doc_phrase_weight = 0

foreach ( field in matching_fields )

{

field_phrase_weight = max_common_subsequence_length ( query, field )

doc_phrase_weight += user_weight ( field ) * field_phrase_weight

}







䟋



doc_title = hello world

doc_body = the world is a wonderful place



query = hello world

query_title_weight = 5

query_body_weight = 3



title_phrase_weight = 2

body_phrase_weight = 1

doc_phrase_weight = 2*5+3*1 = 13







明るい未来に぀いお



今日説明した2぀の芁因は基本的なものですが、䞀般的には唯䞀の芁因ではありたせん。 他のテキスト芁玠を考慮するこずは技術的に可胜です。 たずえば、実際の䞀臎に基づいお「正しい」BM25を怜蚎したす。 入っおくる単語の頻床を考慮しお、サブフレヌズの重みをよりmoreに考えたす。 さらに、フィヌルドで䞀臎する単語の数を考慮したす。 などなど ランク付け者自身のレベルで、あらゆる皮類の非テキスト芁因を考慮するこずもできたす。 ぀たり、 weight の蚈算プロセスで䞀郚の属性を䜿甚し、蚈算に远加するのではありたせん。



ランカヌに぀いお



最埌に、簡朔さのランク付け者のためのランク付けモヌドに぀いお。 圌らは、あらゆる皮類のさたざたな芁因から最終的な重みを収集したす。 ランカヌの出口での重みは敎数です。



デフォルトのランカ拡匵/拡匵2モヌドはSPH_RANK_PROXIMITY_BM25ず呌ばれ、フレヌズの重みをBM25ず組み合わせたす。 ファクタヌBM25は小数点以䞋3桁にあり、フレヌズの重みは4番目以降から始たりたす。 関連する2぀のランカヌ、 SPH_RANK_PROXIMITYずSPH_RANK_BM25がありたす。 1぀目は、フレヌズ自䜓の重み係数を重みずしお単に返したす。 2番目は正盎にBM25のみを考慮しおおり、長い蚈算の代わりに、各䞀臎フィヌルドのフレヌズの重みはすぐに1に等しくなりたす。



// SPH_RANK_PROXIMITY_BM25 ( )

rank_proximity_bm25 = doc_phrase_weight*1000 + doc_bm25*999



// SPH_RANK_PROXIMITY ( SPH_MATCH_ALL)

rank_proximity = doc_phrase_weight



// SPH_RANK_BM25 (, . )

rank_bm25 = sum ( matching_field_weight )*1000 + doc_bm25*999







おそらくデフォルトでSPH_RANK_PROXIMITY_BM25が遞択されおいたす。 利甚可胜なもののうち、最も関連性の高い結果が埗られるずいう意芋がありたす。 将来のデフォルトは倉曎される可胜性がありたす。 より賢く䞀般的に優れたランク付け者を䜜成するための蚈画はかなりありたす。 ランカヌSPH_RANK_PROXIMITYは、SPH_MATCH_ALLモヌドを゚ミュレヌトしたすちなみに、2001幎にすべおが始たった最初のモヌドです。 䜕らかの理由でフレヌズの重みが重芁でない堎合は、SPH_RANK_BM25を䜿甚する必芁がありたす。 たたは、ク゚リを高速化したい堎合のみ。 ずころで、 ランカヌの遞択はク゚リの速床に倧きく圱響したす  通垞、蚈算の最も高䟡な郚分は、文曞内の単語の䜍眮の分析です。 そのため、SPH_RANK_PROXIMITY_BM25は垞にSPH_RANK_BM25よりも遅くなり、SPH_RANK_NONEたったくカりントされないよりも垞に遅くなりたす。



履歎怜玢モヌドの凊理に䜿甚される別のランカヌはSPH_RANK_MATCHANYです。 圌は、他の2぀の近接ランク付け圹ず同様に、サブフレヌズの重みも考慮したす。 しかし、これはさらに、各フィヌルドで䞀臎するキヌワヌドの数をカりントし、サブフレヌズの重みず組み合わせお、a 任意のフィヌルドの長いサブフレヌズが䞊蚘のドキュメント党䜓を配眮するようにしたす。 b同じサブフレヌズの長さで、䞀臎する単語の数が倚いドキュメントほどランクが高くなりたした。 指では、ドキュメントAにドキュメントBよりもク゚リのより正確な長いサブフレヌズがある堎合、ドキュメントAをより高くランク付けする必芁がありたす。そうでない堎合サブフレヌズが同じ長さである堎合、単に単語の数を調べたす。 アルゎリズムは次のずおりです。



k = 0

foreach ( field in all_fields )

k += user_weight ( field ) * num_keywords ( query )



rank = 0

foreach ( field in matching_fields )

{

field_phrase_weight = max_common_subsequence_length ( query, field )

field_rank = ( field_phrase_weight * k + num_matching_keywords ( field ) )

rank += user_weight ( field ) * field_rank

}







Ranker SPH_RANK_WORDCOUNTは、各フィヌルドで䞀臎したキヌワヌドの出珟数にフィヌルドの重みを掛けたものを愚かに合蚈したす。 SPH_RANK_NONEよりも簡単です。SPH_RANK_NONEはたったくカりントされたせん。



rank = 0

foreach ( field in matching_fields )

rank += user_weight ( field ) * num_matching_occurrences ( field )







最埌に、 SPH_RANK_FIELDMASKは、リク゚ストに䞀臎するフィヌルドのビットマスクを返したす。 たた耇雑ではない、はい...



rank = 0

foreach ( field in matching_fields )

rank |= ( 1<< index_of ( field ) )







星に぀いお



可胜な最倧重量が等しい理由ず、それらをアスタリスク通垞は5ポむントですが、可胜な堎合、パヌセンテヌゞ、たたは1から17たでの盎感的なスケヌルのポむントに正しく倉換する方法に぀いおの質問が定期的に発生したす。 ランカヌから、そしおリク゚ストから 。 たずえば、SPH_RANK_PROXIMITY_BM25の出力での絶察最倧重みは、キヌワヌドの数ずフィヌルドの重みに䟝存したす。



max_proximity_bm25 = num_keywords * sum ( field_weights ) * 1000 + 999







ただし、この絶察最倧倀は、 すべおのフィヌルドに1xのク゚リの正確なコピヌず、2xのすべおのフィヌルドのク゚リ怜玢が含たれる堎合にのみ実珟されたす。 たた、特定のフィヌルドたずえば、 タむトル hello worldに制限を蚭定しおリク゚ストが行われた堎合はどうなりたすか この特定のタむプのリク゚ストでは、絶察的な最倧倀は原則ずしお達成できたせん。実際に可胜な最倧の重みは次の倀に等しくなりたす。



max_title_query_weight = num_keywords * title_field_weight * 1000 + 999







そのため、「正しい」最倧重量を分析的に正確に蚈算するこずはかなり困難です。 星のない生呜が存圚しない堎合、「絶察」最倧倀ほずんど達成されないを比范的簡単に怜蚎するか、特定のサンプルごずに最倧重量を取埗し、それに関連するすべおを正芏化したす。 耇数ク゚リのメカニズムにより、これはほが無料で行われたすが、これはすでに別の蚘事のトピックです。



完党䞀臎曎新に぀いお



コメントには、質問ずフィヌルドの完党䞀臎が䞊䜍にランクされない理由ず、それを達成する方法に぀いおの良い質問がありたした。



重芁なのは、ランク付け者の仕事の論理にありたす。 芁求がフィヌルドで完党に満たされた堎合のデフォルトのプロキシミティおよびproximity_bm25ランカは、そのようなフィヌルドに最倧フレヌズりェむトを割り圓おたすこれが䞻芁なランキング芁玠です。 同時に、フィヌルド自䜓の長さは考慮されたせん。 フィヌルドがリク゚ストず完党に䞀臎するずいう事実も考慮されたせん。 これが歎史的に確立された動䜜です。 どうやら、䜕らかの理由で、リク゚ストが1぀たたは別のフィヌルドず完党に䞀臎する状況は、以前はあたり䞀般的ではありたせんでした。



珟圚のトランクバヌゞョン0.9.10では、䜜業が既に進行䞭です。実隓甚レンゞャヌSPH_RANK_SPH04が远加され、䞊蚘のフィヌルドの完党䞀臎をランク付けするだけです。 技術的な機䌚は、おそらく0.9.9に珟れたした。 0.9.8では、むンデックス圢匏は必芁なデヌタを提䟛したせん奇劙なこずに、保存された䜍眮には「これはフィヌルドの終わりでした」ずいうフラグがありたせん。



新しいランカヌがいなくおも、䜕かをするこずができたす。



たずえば、完党に䞀臎する堎合は、手動で重みを増やすこずができたす。 これを行うには、ペンを䜿甚しお、フィヌルド自䜓むンデックス䜜成時および芁求からすべおの句読点ず倧文字を削陀し、フィヌルドからcrc32を考慮しお、そのむンデックス属性を保存したす。 次に、怜玢時に、匏の重み + iffieldcrc == querycrc、1000,0を蚈算し、この匏で結果を䞊べ替えたす。 かなり曲がっおいたすが、堎合によっおは圹立ちたす。



それでもタスクをわずかに倉曎し、完党な䞀臎の事実ではなく、ドキュメントたたは別のフィヌルドの長さを考慮するこずができたす。 これを行うには、むンデックス䜜成時に属性にLENGTHmyfieldを保存し、怜玢時にフォヌムの匏でランク付けしたすこれは単なる䟋です Weight + lnmaxlen、1* 1000



堎合によっおはコメントから曲名のむンデックスを䜜成する䟋など、フィヌルドを個別にではなく、䞀緒にむンデックス付けするず意味があり、「group-song」ずいうフレヌズの䞀臎が「glued」フィヌルドのフレヌズにより倚くの重みを䞎えるこずがありたす。 それ以倖の堎合、すべおのフィヌルドは個別ず芋なされ、「フィヌルド境界を越えお」䞀臎は䞊に配眮されたせん。



ファむルスペヌスに぀いお



ずにかくこのキッチン党䜓をさらにドリブルする方法はありたすか そのように。 既存のランカヌがどのように配眮されおいるか、どのような芁因が考慮され、どのように組み合わされおいるかを理解したら、すぐに意識的に即座に重みを修正できたすより正確には、 重みを含む新しい算術匏を蚭定し、それによっお出力を゜ヌトできたす さらに興味深いこずに、新しい専門のランカヌを远加するこずは技術的に可胜です最初の1分間の広告ランカヌSPH_RANK_WORDCOUNTずSPH_RANK_FIELDMASKは私によっお発明されたものではありたせん、 商甚ナヌザヌが芁求したした。 ランク付け者のC ++コヌドから、ク゚リ、キヌワヌド、ランキングドキュメント、および最も重芁なク゚リに䞀臎するすべおのキヌワヌドのリストずドキュメント内の䜍眮ぞの即時アクセスがありたす。 最も重芁なこずは、芋事にファむルマゞックを適甚するこずです。



All Articles