feat: RRF and cross-segment max-score dedupe
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
use alpha_id::fusion::{rrf_merge, cross_segment_dedupe};
|
||||
use alpha_id::model::Candidate;
|
||||
|
||||
fn cand(code: &str, seg: usize, rerank: Option<f32>) -> Candidate {
|
||||
Candidate { icd_code: code.into(), alpha_text: code.into(),
|
||||
segment_idx: seg, lexical: None, semantic: None, rerank }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rrf_merges_two_rankings_by_reciprocal_rank() {
|
||||
let lex = vec![0usize, 1, 2]; // entry indices ranked
|
||||
let sem = vec![2usize, 0, 3];
|
||||
let merged = rrf_merge(&lex, &sem, 60);
|
||||
// entry 0 appears rank0 in lex and rank1 in sem -> highest
|
||||
assert_eq!(merged[0], 0);
|
||||
assert!(merged.contains(&3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cross_segment_keeps_max_score_and_all_sources() {
|
||||
let cands = vec![
|
||||
cand("E11.9", 0, Some(0.4)),
|
||||
cand("E11.9", 2, Some(0.9)),
|
||||
cand("I10.90", 1, Some(0.5)),
|
||||
];
|
||||
let mut merged = cross_segment_dedupe(cands);
|
||||
merged.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
|
||||
assert_eq!(merged[0].0.icd_code, "E11.9");
|
||||
assert_eq!(merged[0].1, 0.9); // max
|
||||
assert_eq!(merged[0].0.source_segments, vec![0, 2]); // all sources
|
||||
}
|
||||
Reference in New Issue
Block a user