Ranking#

Stage 2 of the recommendation pipeline. Rankers score candidates with precision, narrowing thousands to tens.

Quick Start#

from corerec.ranking import PointwiseRanker

ranker = PointwiseRanker(score_fn=my_score_fn, feature_extractor=my_extractor)
ranker.fit()
result = ranker.rank(candidates, context)

API Reference#

Base classes for ranking stage.

Rankers score candidates retrieved in Stage 1. They can use richer features and more complex models since they only process hundreds of items, not millions.

class corerec.ranking.base.RankedCandidate(item_id: ~typing.Any, score: float, retrieval_score: float = 0.0, rank: int = 0, predictions: ~typing.Dict[str, float] = <factory>, features: ~typing.Dict[str, ~typing.Any] = <factory>)[source]#

Bases: object

A candidate with ranking score and optional auxiliary predictions.

item_id: Any#

unique identifier

score: float#

ranking score (higher = better)

retrieval_score: float = 0.0#

original score from retrieval

rank: int = 0#

position in ranked list (1-indexed)

predictions: Dict[str, float]#

multi-task predictions (e.g., p(click), p(purchase))

features: Dict[str, Any]#

feature values used for scoring

class corerec.ranking.base.RankingResult(candidates: List[RankedCandidate], query_id: Any = None, ranker_name: str = 'unknown', timing_ms: float = 0.0)[source]#

Bases: object

Output from ranking operation.

candidates: List[RankedCandidate]#

ranked list (best first)

query_id: Any = None#

identifier for the query

ranker_name: str = 'unknown'#

which ranker produced this

timing_ms: float = 0.0#

ranking latency

top_k(k: int) → List[RankedCandidate][source]#

Return top k candidates.

item_ids() → List[Any][source]#

Extract item IDs in ranked order.

scores() → ndarray[source]#

Extract scores as numpy array.

class corerec.ranking.base.BaseRanker(name: str | None = None)[source]#

Bases: ABC

Abstract base class for all rankers.

A ranker takes a list of candidates (from retrieval) and a context (user features, session info, etc) and produces a ranked list.

Design goals: - Precision-focused: quality over speed - Feature-rich: can use detailed user/item features - Multi-objective: can predict multiple targets

property is_fitted: bool#
abstractmethod fit(**kwargs) → BaseRanker[source]#

Train or configure the ranker.

What “fit” means depends on the ranker: - PointwiseRanker: train a scoring model - FeatureCrossRanker: configure feature interactions - PairwiseRanker: train pairwise preference model

Returns self for method chaining.

abstractmethod rank(candidates: List[Candidate] | RetrievalResult, context: Dict[str, Any] | None = None, **kwargs) → RankingResult[source]#

Rank candidates for a given context.

Parameters:
  • candidates – list of Candidate or RetrievalResult from retrieval

  • context – user features, session info, etc.

  • **kwargs – ranker-specific parameters

Returns:

RankingResult with candidates sorted by score

rank_batch(candidate_batches: List[List[Candidate] | RetrievalResult], contexts: List[Dict[str, Any]] | None = None, **kwargs) → List[RankingResult][source]#

Batch ranking. Default implementation just loops. Subclasses can override for efficiency.

Pointwise Ranker#

Pointwise Ranking

Scores each candidate independently. Simple but effective, and easy to train with standard classification/regression losses.

class corerec.ranking.pointwise.PointwiseRanker(model: Any | None = None, score_fn: Callable[[Dict], float] | None = None, feature_extractor: Callable[[Any, Dict], Dict] | None = None, name: str = 'pointwise')[source]#

Bases: BaseRanker

Ranks candidates by scoring each one independently.

The scoring function can be: - A trained ML model (sklearn, torch, etc) - A simple callable that takes features and returns score - A weighted combination of feature values

Example:

# with a trained model
ranker = PointwiseRanker(model=trained_model)
ranker.fit(feature_extractor=my_feature_fn)

# with a simple scoring function
ranker = PointwiseRanker(
    score_fn=lambda feats: feats['quality'] * 0.7 + feats['recency'] * 0.3
)
ranker.fit()
__init__(model: Any | None = None, score_fn: Callable[[Dict], float] | None = None, feature_extractor: Callable[[Any, Dict], Dict] | None = None, name: str = 'pointwise')[source]#
Parameters:
  • model – ML model with predict() or predict_proba() method

  • score_fn – custom scoring function (features -> score)

  • feature_extractor – function to extract features from (item_id, context)

  • name – identifier for this ranker

Provide either model or score_fn.

fit(model: Any | None = None, feature_extractor: Callable | None = None, **kwargs) → PointwiseRanker[source]#

Configure the ranker.

Parameters:
  • model – ML model to use for scoring

  • feature_extractor – function(item_id, context) -> feature_dict

rank(candidates: List[Candidate] | RetrievalResult, context: Dict[str, Any] | None = None, **kwargs) → RankingResult[source]#

Score and rank candidates.

Parameters:
  • candidates – candidates from retrieval

  • context – user features, session info, etc.

rank_batch(candidate_batches: List[List[Candidate] | RetrievalResult], contexts: List[Dict[str, Any]] | None = None, **kwargs) → List[RankingResult][source]#

Batch ranking - can be more efficient with batched feature extraction.

Pairwise Ranker#

Pairwise Ranking

Learns preferences between item pairs rather than absolute scores. Good for learning-to-rank with implicit feedback.

class corerec.ranking.pairwise.PairwiseRanker(compare_fn: Callable[[Any, Any, Dict], float] | None = None, aggregation: str = 'wins', max_comparisons: int | None = None, name: str = 'pairwise')[source]#

Bases: BaseRanker

Ranks by comparing pairs of candidates.

Instead of predicting absolute scores, pairwise ranking learns P(item_a > item_b | context). This is more natural for implicit feedback where we only observe relative preferences.

Final ranking is computed by aggregating pairwise comparisons (e.g., via Bradley-Terry model or simple win counting).

Example:

ranker = PairwiseRanker(
    compare_fn=my_pairwise_model.predict_proba
)
ranker.fit()
ranked = ranker.rank(candidates, context)
__init__(compare_fn: Callable[[Any, Any, Dict], float] | None = None, aggregation: str = 'wins', max_comparisons: int | None = None, name: str = 'pairwise')[source]#
Parameters:
  • compare_fn – function(item_a, item_b, context) -> P(a > b)

  • aggregation – how to aggregate comparisons: ‘wins’ - count wins ‘bradley_terry’ - fit BT model

  • max_comparisons – limit comparisons for efficiency

  • name – identifier for this ranker

fit(compare_fn: Callable | None = None, **kwargs) → PairwiseRanker[source]#

Configure the ranker.

Parameters:

compare_fn – pairwise comparison function

rank(candidates: List[Candidate] | RetrievalResult, context: Dict[str, Any] | None = None, **kwargs) → RankingResult[source]#

Rank candidates via pairwise comparisons.

Feature Cross Ranker#

Feature Cross Ranking

Ranking with explicit feature interactions (DCN-style). Useful when you have rich user/item features and want to capture their interactions.

class corerec.ranking.feature_cross.FeatureCrossRanker(feature_extractor: Callable[[Any, Dict], Dict] | None = None, crosses: List[tuple] | None = None, weights: Dict[str, float] | None = None, model: Any | None = None, name: str = 'feature_cross')[source]#

Bases: BaseRanker

Ranker that explicitly models feature interactions.

Inspired by DCN (Deep & Cross Network), this ranker computes scores by considering both individual features and their cross-products. Good for capturing “users who buy X also like Y”.

Can be used with: - Pre-defined feature crosses (manual feature engineering) - Learned crosses (if you have a trained DCN model) - Simple polynomial features

Example:

ranker = FeatureCrossRanker(
    feature_extractor=extract_user_item_features,
    crosses=[
        ('user_age_bucket', 'item_category'),
        ('user_gender', 'item_brand'),
    ],
    weights={'user_age_bucket:item_category': 0.3, ...}
)
ranker.fit()
ranked = ranker.rank(candidates, user_context)
__init__(feature_extractor: Callable[[Any, Dict], Dict] | None = None, crosses: List[tuple] | None = None, weights: Dict[str, float] | None = None, model: Any | None = None, name: str = 'feature_cross')[source]#
Parameters:
  • feature_extractor – function(item_id, context) -> feature_dict

  • crosses – list of feature name tuples to cross

  • weights – weights for each feature/cross (learned or manual)

  • model – trained model with predict() (overrides manual weights)

  • name – identifier for this ranker

fit(feature_extractor: Callable | None = None, crosses: List[tuple] | None = None, weights: Dict[str, float] | None = None, model: Any | None = None, **kwargs) → FeatureCrossRanker[source]#

Configure the ranker.

Parameters:
  • feature_extractor – feature extraction function

  • crosses – feature crosses to compute

  • weights – feature weights

  • model – trained model

rank(candidates: List[Candidate] | RetrievalResult, context: Dict[str, Any] | None = None, **kwargs) → RankingResult[source]#

Rank candidates using feature crosses.