qa/corpus_query: wire filter_by_title_relevance into multi_route
When policy.multi_route fans across body+title+phrase+core_keyword and merges by MIN bm25, the resulting set over-recalls on noisy titles (e.g. "East Asia" outranks "Nineteen Eighty-Four" on the Orwell phrase query because raw bm25 over the merged set doesn't know about accept-path semantics). The 5-accept-path filter arborist.qa.retrieval_routes.filter_by_title_relevance (landed step 3) gates the merged set on: title-overlap / synonym / TFIDF-core match / verbatim-phrase match / hyphen-fold anchor. Wired so accept-paths 2 and 4 actually fire — core_match_roots and phrase_match_roots are passed through from this turn's core_hits / phrase_hits, so docs surfaced via those routes pass the filter even when titles miss. Smoke (multi-shard wiki corpus, "has oceania always been at war with east asia"): Nineteen Eighty-Four now ranks #1 (was rank 3 before filter). Other phrase-route hits like "Nineteen Eighty-Four in popular media" stay; the geographic "East Asia" / "Oceania" title hits get filtered out. 264 tests pass (was 263 + 1 multi-route test from 6c that confirms filter path doesn't blow up on the Anarchism fixture either).
This commit is contained in:
parent
5fdd573c0a
commit
6c2ec1b6c0
1 changed files with 20 additions and 3 deletions
|
|
@ -192,7 +192,10 @@ def run_query(
|
|||
ts = _time.time()
|
||||
multi_route = bool(policy and policy.get("multi_route", False))
|
||||
if multi_route:
|
||||
from arborist.qa.retrieval_routes import question_phrases
|
||||
from arborist.qa.retrieval_routes import (
|
||||
filter_by_title_relevance,
|
||||
question_phrases,
|
||||
)
|
||||
per_route_limit = top_k * 4
|
||||
body_hits = _safe_route(corpus, "fts_body", question, per_route_limit)
|
||||
title_hits = _safe_route(corpus, "fts_title", question, per_route_limit)
|
||||
|
|
@ -200,8 +203,6 @@ def run_query(
|
|||
phrase_hits = _safe_phrase_route(
|
||||
corpus, phrases, per_route_limit,
|
||||
) if phrases else []
|
||||
# core_keyword needs qtokens; reuse the title_query_tokens helper
|
||||
# since legacy query() does the same thing.
|
||||
from arborist.qa.query import _title_query_tokens
|
||||
qtokens = list(_title_query_tokens(question))
|
||||
core_hits = _safe_core_route(
|
||||
|
|
@ -210,6 +211,22 @@ def run_query(
|
|||
hits = _merge_routes_min_bm25(
|
||||
body_hits, title_hits, phrase_hits, core_hits,
|
||||
)
|
||||
# 5-accept-path filter from arborist.qa.retrieval_routes —
|
||||
# gates the merged set on title-overlap / synonym / TFIDF-core
|
||||
# match / verbatim-phrase match / hyphen-fold anchor. Without
|
||||
# this, multi-route over-recalls on noisy title overlaps (e.g.
|
||||
# "East Asia" outranks "Nineteen Eighty-Four" for the Orwell
|
||||
# phrase query). core_match_roots and phrase_match_roots are
|
||||
# passed through so accept-paths 2 + 4 fire on docs that
|
||||
# surfaced via those routes even when titles miss.
|
||||
core_match_roots = {h.document_root for h in core_hits}
|
||||
phrase_match_roots = {h.document_root for h in phrase_hits}
|
||||
hits = filter_by_title_relevance(
|
||||
hits, question,
|
||||
core_match_roots=core_match_roots,
|
||||
phrase_match_roots=phrase_match_roots,
|
||||
fallback_top_n=top_k,
|
||||
)
|
||||
else:
|
||||
try:
|
||||
hits = corpus.fts_body(question, limit=top_k * 4)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue