Serendipity

class rectools.metrics.serendipity.Serendipity(k: int)[source]

Bases: MetricAtK

Serendipity metric.

Evaluates novelty and relevance together.

\[Serendipity@k = (\sum_{i=1}^{k} max(p(i) - pu(i), 0) * rel(i)) / k\]
where
  • \(p(i) = (n\_items + 1 - i) / n\_items\) is probability to recommend item with rank i to current user;

  • \(pu(i) = (n\_items + 1 - popularity(i)) / n_items\) is probability to recommend item with rank i to any user;

  • \(rel(i)\) is an indicator function, it equals to 1 if the item at rank i is relevant, 0 otherwise;

  • \(n\_items\) is an overall number of items that could be used for recommendations.

  • \(popularity(i)\) is popularity rank of the i-th item in recommendations list.

Parameters

k (int) – Number of items at the top of recommendations list that will be used to calculate metric.

Notes

Method is inspired by the article: https://gab41.lab41.org/recommender-systems-its-not-all-about-the-accuracy-562c7dceeaff

Examples

>>> reco = pd.DataFrame(
...     {
...         Columns.User: ["u1", "u1", "u2", "u2", "u3", "u4", "u4"],
...         Columns.Item: ["i1", "i2", "i2", "i3", "i3", "i2", "i3"],
...         Columns.Rank: [   1,    2,    1,    2,    1,    1,    2],
...     }
... )
>>> interactions = pd.DataFrame(
...     {
...         Columns.User: ["u1", "u1", "u2", "u2", "u3", "u4"],
...         Columns.Item: ["i1", "i2", "i2", "i3", "i2", "i2"],
...     }
... )
>>> prev_interactions = pd.DataFrame(
...     {
...         Columns.User: ["u1", "u1", "u2", "u2", "u3"],
...         Columns.Item: ["i1", "i2", "i1", "i2", "i1"],
...     }
... )
>>> catalog = ("i1", "i2", "i3", "i4")
>>> Serendipity(k=1).calc_per_user(reco, interactions, prev_interactions, catalog).values
array([0. , 0.25, 0. , 0.25])
>>> Serendipity(k=2).calc_per_user(reco, interactions, prev_interactions, catalog).values
array([0.  , 0.5 , 0.  , 0.125])
Inherited-members

Parameters

k (int) –

Methods

calc(reco, interactions, prev_interactions, ...)

Calculate metric value.

calc_from_fitted(fitted)

Calculate metric value from fitted data.

calc_per_user(reco, interactions, ...)

Calculate metric values for all users.

calc_per_user_from_fitted(fitted)

Calculate metric values for all users from fitted data.

fit(reco, interactions, prev_interactions, ...)

Prepare intermediate data for effective calculation.

Attributes

calc(reco: DataFrame, interactions: DataFrame, prev_interactions: DataFrame, catalog: Collection[Union[str, int]]) float[source]

Calculate metric value.

Parameters
  • reco (pd.DataFrame) – Recommendations table with columns Columns.User, Columns.Item, Columns.Rank.

  • interactions (pd.DataFrame) – Interactions table with columns Columns.User, Columns.Item.

  • prev_interactions (pd.DataFrame) – Table with previous user-item interactions, with columns Columns.User, Columns.Item.

  • catalog (collection) – Collection of unique item ids that could be used for recommendations.

Returns

Value of metric (average between users).

Return type

float

calc_from_fitted(fitted: SerendipityFitted) float[source]

Calculate metric value from fitted data.

For parameters used result of fit method.

Parameters

fitted (SerendipityFitted) – Meta data that got from .fit method.

Returns

Value of metric (average between users).

Return type

float

calc_per_user(reco: DataFrame, interactions: DataFrame, prev_interactions: DataFrame, catalog: Collection[Union[str, int]]) Series[source]

Calculate metric values for all users.

Parameters
  • reco (pd.DataFrame) – Recommendations table with columns Columns.User, Columns.Item, Columns.Rank.

  • interactions (pd.DataFrame) – Interactions table with columns Columns.User, Columns.Item.

  • prev_interactions (pd.DataFrame) – Table with previous user-item interactions, with columns Columns.User, Columns.Item.

  • catalog (collection) – Collection of unique item ids that could be used for recommendations.

Returns

Values of metric (index - user id, values - metric value for every user).

Return type

pd.Series

calc_per_user_from_fitted(fitted: SerendipityFitted) Series[source]

Calculate metric values for all users from fitted data.

For parameters used result of fit method.

Parameters

fitted (SerendipityFitted) – Meta data that got from .fit method.

Returns

Values of metric (index - user id, values - metric value for every user).

Return type

pd.Series

classmethod fit(reco: DataFrame, interactions: DataFrame, prev_interactions: DataFrame, catalog: Collection[Union[str, int]], k_max: int) SerendipityFitted[source]

Prepare intermediate data for effective calculation.

You can use this method to prepare some intermediate data for later calculation. It can optimize calculations if you want calculate metric value for different k or distance_calculator.

Parameters
  • reco (pd.DataFrame) – Recommendations table with columns Columns.User, Columns.Item, Columns.Rank.

  • interactions (pd.DataFrame) – Interactions table with columns Columns.User, Columns.Item.

  • prev_interactions (pd.DataFrame) – Table with previous user-item interactions, with columns Columns.User, Columns.Item.

  • catalog (collection) – Collection of unique item ids that could be used for recommendations.

  • k_max (int) – k is number of items at the top of recommendations list that will be used to calculate metric. So k_max is maximum value of k parameter for which you want to calculate metric.

Return type

SerendipityFitted