massey_ranker

Massey pairwise preference ranker. It builds the Massey coefficient matrix with diagonal entries games_i, off-diagonal entries -games_ij, and a final sum(ratings)=0 anchoring row, then solves the linear system using deterministic Gaussian elimination with partial pivoting and residual validation.

The library implements the ranker_protocol defined in the ranking_protocols library. It provides predicates for learning a ranker from pairwise preferences, using it to order candidate items, and exporting it as a list of predicate clauses or to a file.

Datasets are represented as objects implementing the pairwise_ranking_dataset_protocol protocol from the ranking_protocols library. See the test_datasets directory for examples. The current implementation requires a well-formed connected pairwise dataset so that learned rankings remain globally comparable across all ranked items.

API documentation

Open the ../../apis/library_index.html#massey_ranker link in a web browser.

Loading

To load this library, load the loader.lgt file:

| ?- logtalk_load(massey_ranker(loader)).

Testing

To test this library predicates, load the tester.lgt file:

| ?- logtalk_load(massey_ranker(tester)).

Features

  • Pairwise Preference Learning: Learns one deterministic rating per item from aggregated pairwise outcomes.

  • Massey Matrix Fidelity: Solves the standard Massey linear system with diagonal entries games_i, off-diagonal entries -games_ij, and a final anchoring row enforcing sum(ratings) = 0.

  • Numerically Hardened Solver: Uses Gaussian elimination with partial pivoting plus residual checks before accepting the learned ratings.

  • Zero-Sum Ratings: Produces ratings centered at 0.0, where positive values indicate above-average aggregate performance and negative values indicate below-average aggregate performance.

  • Deterministic Ranking: Orders candidate items by learned rating with deterministic tie-breaking.

  • Strict Dataset Validation: Rejects duplicate items, undeclared items, self-preferences, non-positive weights, and disconnected comparison graphs.

  • Ranker Export: Learned rankers can be exported as self-contained terms.

  • Shared Ranking Infrastructure: Reuses the ranking_protocols helpers for dataset validation, diagnostics, export, and candidate ranking.

Scoring semantics

This implementation aggregates pairwise preferences into matchup totals and then solves the Massey system

M r = p

where M_ii = games_i, M_ij = -games_ij for i \= j, and the final row of M is replaced with ones so that the learned ratings satisfy sum(ratings) = 0. The right-hand-side vector p is the per-item signed point-differential total wins_i - losses_i.

The linear system is solved using deterministic Gaussian elimination with partial pivoting. The implementation also verifies that the recovered solution has a small residual and only clamps negligible floating-point noise around 0.0.

The resulting ratings are relative rather than probabilistic: only their differences and ordering matter. Larger positive values indicate stronger aggregate pairwise performance against the field.

Usage

Learning a ranker

% Learn from a pairwise ranking dataset object
| ?- massey_ranker::learn(my_dataset, Ranker).
...

% Learn with an explicit empty options list
| ?- massey_ranker::learn(my_dataset, Ranker, []).
...

The current implementation accepts only the empty options list []. Any non-empty options list is rejected.

Inspecting diagnostics

% Inspect model and dataset summary metadata
| ?- massey_ranker::learn(my_dataset, Ranker),
     massey_ranker::diagnostics(Ranker, Diagnostics).
Diagnostics = [...]
...

Ranking candidate items

% Rank a candidate set from most preferred to least preferred
| ?- massey_ranker::learn(my_dataset, Ranker),
     massey_ranker::rank(Ranker, [item_a, item_b, item_c], Ranking).
Ranking = [...]
...

Candidate lists must be proper lists of unique, ground items declared by the training dataset. Invalid ranker terms, duplicate candidates, and candidates containing variables are rejected with errors instead of being silently accepted.

Exporting the ranker

Learned rankers can be exported as a list of clauses or to a file for later use.

% Export as predicate clauses
| ?- massey_ranker::learn(my_dataset, Ranker),
     massey_ranker::export_to_clauses(my_dataset, Ranker, my_ranker, Clauses).
Clauses = [my_ranker(massey_ranker(...))]
...

% Export to a file
| ?- massey_ranker::learn(my_dataset, Ranker),
     massey_ranker::export_to_file(my_dataset, Ranker, my_ranker, 'ranker.pl').
...

Diagnostics syntax

The diagnostics/2 predicate returns a list of metadata terms with the form:

[
    model(massey_ranker),
    options(Options),
    dataset_summary(DatasetSummary)
]

Ranker representation

The learned ranker is represented by a compound term of the form:

massey_ranker(Items, Ratings, Diagnostics)

Where:

  • Items: List of ranked items.

  • Ratings: List of Item-Rating pairs.

  • Diagnostics: List of metadata terms, including the effective options and dataset summary.

References

  1. Massey, K. (1997). Statistical models applied to the rating of sports teams.