Skip to main content
NDCG (Normalized Discounted Cumulative Gain) is a ranking quality metric that handles graded relevance — items can be highly relevant, somewhat relevant, or not relevant at all, rather than just relevant or not. It also applies a logarithmic discount so that items ranked higher contribute more to the score than items ranked lower.

Constants

const (
    AbsTol = 1e-08
    RelTol = 1e-05
)
These tolerances are used by IsClose and IsZero for floating-point comparisons throughout the library.
ConstantValueDescription
AbsTol1e-08Absolute tolerance for float comparison
RelTol1e-05Relative tolerance for float comparison

NDCG

func NDCG(predicted []string, relevance map[string]int, k int) float64
Returns the Normalized Discounted Cumulative Gain at cutoff K. NDCG compares the DCG of the actual ranked list against the ideal DCG (the best possible ordering of the same items). A score of 1.0 indicates a perfect ranking; 0.0 means no relevant items were retrieved. Returns 0.0 when the ideal DCG is zero.
predicted
[]string
required
The ranked list of item identifiers returned by the system, ordered from most to least relevant.
relevance
map[string]int
required
A map of item identifier to integer relevance grade. Higher grades indicate greater relevance. Items not present in the map are treated as grade 0.
k
int
required
The cutoff depth. Only the first k positions are evaluated.
Returns float64 — DCG of the predicted ranking divided by the ideal DCG, in the range [0, 1].

Example

func ExampleNDCG() {
	predicted := []string{"A", "B", "C", "D"}
	relevance := map[string]int{
		"A": 3,
		"B": 2,
		"C": 1,
		"D": 0,
		"E": 3,
	}

	s := reval.NDCG(predicted, relevance, 3)
	fmt.Println("NDCG@3:", s)

	// Output:
	// NDCG@3: 0.7271926019583822
}
The ideal top-3 ranking would be “A” (grade 3), “E” (grade 3), “B” (grade 2). The actual top-3 is “A” (3), “B” (2), “C” (1). The actual DCG is lower because “E” was not retrieved at rank 2, giving NDCG ≈ 0.727.

DCG

func DCG(relevance []int) float64
Computes the Discounted Cumulative Gain for a sequence of relevance grades. Grades are discounted by the logarithm of their rank position so that higher-ranked items contribute more to the total. The formula applied at each position i (0-indexed) is:
DCG = Σ (2^rel_i - 1) / log2(i + 2)
relevance
[]int
required
A slice of integer relevance grades in rank order. The first element is rank 1, the second is rank 2, and so on.
Returns float64 — the summed discounted gain across all positions.

IsClose

func IsClose(a, b float64) bool
Reports whether two float64 values are approximately equal, using both absolute and relative tolerances defined by AbsTol and RelTol. The comparison uses the formula:
|a - b| ≤ AbsTol + RelTol × max(|a|, |b|)
a
float64
required
The first value to compare.
b
float64
required
The second value to compare.
Returns booltrue if a and b are within tolerance of each other.

IsZero

func IsZero(a float64) bool
Reports whether a float64 value is approximately zero. Equivalent to calling IsClose(a, 0.0).
a
float64
required
The value to test.
Returns booltrue if a is within tolerance of 0.0.

Build docs developers (and LLMs) love