Module: RerankerRuby::ScoreNormalizer

Defined in:
lib/reranker_ruby/score_normalizer.rb

Overview

Normalizes scores across different reranker models to a common [0, 1] scale. Different models produce scores on different scales — this makes them comparable.

Class Method Summary collapse

Class Method Details

.min_max(results) ⇒ Object

Min-max normalization to [0, 1]



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/reranker_ruby/score_normalizer.rb', line 8

def self.min_max(results)
  return results if results.empty?

  scores = results.map(&:score)
  if scores.any? { |s| s.nan? || s.infinite? }
    return results.map { |r| with_score(r, 0.0) }
  end

  min = scores.min
  max = scores.max
  range = max - min

  return results.map { |r| with_score(r, 1.0) } if range.zero?

  results.map { |r| with_score(r, (r.score - min) / range) }
end

.sigmoid(results) ⇒ Object

Sigmoid normalization — each score independently mapped to [0, 1]



44
45
46
47
48
49
50
51
52
53
# File 'lib/reranker_ruby/score_normalizer.rb', line 44

def self.sigmoid(results)
  return results if results.empty?

  scores = results.map(&:score)
  if scores.any? { |s| s.nan? || s.infinite? }
    return results.map { |r| with_score(r, 0.0) }
  end

  results.map { |r| with_score(r, 1.0 / (1.0 + Math.exp(-r.score))) }
end

.softmax(results) ⇒ Object

Softmax normalization — scores sum to 1.0, preserves relative ordering



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/reranker_ruby/score_normalizer.rb', line 26

def self.softmax(results)
  return results if results.empty?

  scores = results.map(&:score)
  if scores.any? { |s| s.nan? || s.infinite? }
    return results.map { |r| with_score(r, 0.0) }
  end

  max_score = scores.max
  exps = scores.map { |s| Math.exp(s - max_score) } # subtract max for numerical stability
  sum = exps.sum

  results.each_with_index.map do |r, i|
    with_score(r, exps[i] / sum)
  end
end