Class: RerankerRuby::Ensemble

Inherits:
Base
  • Object
show all
Defined in:
lib/reranker_ruby/ensemble.rb

Overview

Combines results from multiple rerankers using weighted score aggregation.

Usage:

ensemble = RerankerRuby::Ensemble.new(
rerankers: [cohere_reranker, jina_reranker],
weights: [0.6, 0.4],
normalize: :min_max
)
results = ensemble.rerank(query, documents, top_k: 5)

Instance Method Summary collapse

Constructor Details

#initialize(rerankers:, weights: nil, normalize: :min_max, **options) ⇒ Ensemble

Returns a new instance of Ensemble.

Parameters:

  • rerankers (Array<Base>) —

    list of reranker instances

  • weights (Array<Float>, nil) (defaults to: nil) —

    weights for each reranker (default: equal)

  • normalize (Symbol) (defaults to: :min_max) —

    normalization strategy (:min_max, :softmax, :sigmoid, or :none)



18
19
20
21
22
23
24
25
26
27
# File 'lib/reranker_ruby/ensemble.rb', line 18

def initialize(rerankers:, weights: nil, normalize: :min_max, **options)
  super(**options)
  @rerankers = rerankers
  @weights = weights || Array.new(rerankers.length, 1.0 / rerankers.length)
  @normalize = normalize

  if @weights.length != @rerankers.length
    raise ArgumentError, "weights length (#{@weights.length}) must match rerankers length (#{@rerankers.length})"
  end
end

Instance Method Details

#rerank(query, documents, top_k: 10) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/reranker_ruby/ensemble.rb', line 29

def rerank(query, documents, top_k: 10)
  validate_inputs!(query, documents, top_k)
  with_cache(query, documents, top_k: top_k) do
    texts = extract_texts(documents)

    # Collect and normalize results from each reranker
    all_results = @rerankers.map do |reranker|
      raw = reranker.rerank(query, documents, top_k: texts.length)
      normalize_results(raw)
    end

    # Aggregate scores by original document index
    aggregated = Hash.new(0.0)
    all_results.each_with_index do |results, reranker_idx|
      weight = @weights[reranker_idx]
      results.each do |result|
        aggregated[result.index] += result.score * weight
      end
    end

    # Build final results sorted by aggregated score
    aggregated.map do |idx, score|
      Result.new(
        text: texts[idx],
        score: score,
        index: idx,
        metadata: (documents[idx])
      )
    end.sort.first(top_k)
  end
end