Milestone 4 of 9
Score and rank both systems with complete traces
Reproduce the integer baseline, calculate tf-idf cosine contributions and norms, apply exact rounding and ties, and retain complete positive rankings.
Now score the same query/document candidates two ways. Keep the arithmetic visible so a rank is reproducible rather than an unexplained number.
Goal
Reproduce the exact integer term-count baseline and supplied tf–idf cosine score, record complete contributions and norms, and apply deterministic ranking ties to the complete positive-score results.
Inputs
Use the positional index, term and document weights, document norms, analyzed query vectors, query norms, validated configuration, and query/document order. Both systems use the same candidate documents: documents containing at least one in-index query term.
For the baseline, calculate over distinct in-index query terms:
term_contribution = query_term_count * document_term_count
baseline_score = sum(term_contribution)
Save one row per distinct query term, including zero contribution when that term is absent from a candidate document. For cosine, calculate:
numerator_contribution(t) = query_weight(t, q) * document_weight(t, d)
dot_product = sum(numerator_contribution(t) for t in in-index query terms)
raw_cosine_score = dot_product / (query_norm * document_norm)
Only positive dot products and non-zero norms enter cosine rankings. The raw
score must be finite and within [0, 1] under the configured tolerance. Round
the raw value to exactly twelve decimal places to form ranking_score, while
retaining the raw value separately. The baseline's exact integer score is its
ranking_score.
Deliverables
Implement src/score.py. Produce output/score_contributions.csv with both
systems' term-level contributions, sums, norms, raw scores, and ranking scores;
produce complete output/ranked_results.jsonl records for both systems. Each
ranked record contains query ID, system identity, rank ordinal, document ID,
score fields, matched-distinct-query-term count, and the contribution evidence.
Rank each system independently by decreasing ranking_score, decreasing
matched-distinct-query-term count, then lexicographically increasing
document_id. Rank starts at one. Return every positive-score result; do not
insert zero-score documents or truncate before evaluation.
Checks
Hand-check exact baseline contributions, cosine numerator contributions, dot products, norms, raw-versus-rounded identity, finite bounds, candidate sets, and all three tie stages. Check repeated query terms are counted as specified, missing terms contribute zero, zero-norm queries produce empty rankings, and zero-term documents remain in accounting but not positive rankings.
Check every positive-score document appears once, every contribution sum agrees with its score, query and document identities remain stable, and the two systems use identical candidates. Do not call the baseline a probability or a semantic score, and do not treat display tie keys as additional relevance evidence.
Workspace
Keep scoring and ranking in src/score.py. Read prior sparse artifacts and
write contributions and complete rankings in deterministic CSV and JSONL.
Do not align judgments or calculate cutoffs yet.
Hints
HintMake the candidate set explicit
HintRound after the raw score
ranking_score. Never sort by an
unstated tolerance.HintTrace a zero
Review
Choose one query/document pair and reproduce both scores from the contribution rows. Then inspect a tie resolved by each secondary key. What evidence belongs to the score, and what merely makes the display deterministic?
How to check your work
Checks compare contributions, norms, raw and rounded scores, candidate sets, and rank
order with the hand-check fixtures. The supplied fixture returns complete positive
rankings and does not add top_k or a relevance interpretation.