KerasRS / API 文档 / 指标 / nDCG 指标

nDCG 指标

[源代码]

NDCG

keras_rs.metrics.NDCG(
    k: Optional[int] = None,
    gain_fn: Callable[[Any], Any] = default_gain_fn,
    rank_discount_fn: Callable[[Any], Any] = default_rank_discount_fn,
    **kwargs: Any
)

计算归一化折损累计增益 (nDCG)。

此指标评估排名质量。它通过理想折损累计增益 (IDCG) 对每个列表的折损累计增益 (DCG) 进行归一化。此指标处理 y_true 中的真实相关性标签(分级相关性分数(非负数,值越高表示相关性越高))与 y_pred 中的预测分数。y_pred 中的分数用于确定项目的排序顺序,通过降序排序。返回归一化分数(介于 0 和 1 之间)。分数为 1 表示根据真实相关性(在 top-k 内)的完美排名,而 0 通常表示没有相关项的排名。分数越高表示相对于最佳可能排名具有更好的排名质量。

对于 y_pred 中每个预测分数列表 sy_true 中相应的真实标签列表 y,每次查询的 nDCG 分数计算如下:

nDCG@k = DCG@k / IDCG@k

其中 DCG@k 是根据预测排名 (y_pred) 计算的

DCG@k(y') = sum_{i=1}^{k} (gain_fn(y'_i) / rank_discount_fn(i))

IDCG@k 是理想 DCG,使用相同的公式计算,但应用于根据其真实相关性 (y_true) 完美排序的项目

IDCG@k(y'') = sum_{i=1}^{k} (gain_fn(y''_i) / rank_discount_fn(i))

其中

  • y'_i:在 y_pred 引起的排名中位于排名 i 的项的真实相关性。
  • y''_i:在*理想*排名(按 y_true 降序排序)中位于排名 i 的项的真实相关性。
  • gain_fn 是用户提供的将相关性映射到增益的函数。默认函数 (default_gain_fn) 通常等同于 lambda y: 2**y - 1
  • rank_discount_fn 是用户提供的将排名 i(从 1 开始计数)映射到折损值的函数。默认函数 (default_rank_discount_fn) 通常等同于 lambda rank: 1 / log2(rank + 1)
  • 如果 IDCG@k 为 0(例如,没有相关项),则 nDCG@k 定义为 0。
  • 最终结果通常会汇总这些每个列表的 nDCG 分数,可能涉及按列表特定权重进行归一化,以产生加权平均值。

报告的最终 nDCG 分数通常是数据集中所有查询/列表的这些每次查询分数的加权平均值。

注意:对于排名指标,sample_weight 的处理方式有所不同。对于批量输入,sample_weight 可以是标量、1D 或 2D。标量情况和 1D 情况(列表级权重)很简单。2D 情况(项目级权重)则不同,因为样本权重会被汇总以获得 1D 权重。有关更多详细信息,请参阅 keras_rs.src.metrics.ranking_metrics_utils.get_list_weights

参数

  • gain_fn:可调用对象。将相关性分数 (y_true) 映射到增益值。默认实现为 2**y - 1
  • rank_discount_fn:函数。将排名位置映射到折损值。默认函数 (default_rank_discount_fn) 实现为 1 / log2(rank + 1)
  • k:int。要考虑的排名靠前项的数量(“top-k”中的“k”)。必须是正整数。
  • shuffle_ties:bool。在排序之前是否随机打乱分数。这样做是为了打破平局。默认为 True
  • seed:int。用于打乱的随机种子。
  • name:可选的损失实例名称。
  • dtype:指标计算的数据类型 (dtype)。默认为 None,表示使用 keras.backend.floatx()keras.backend.floatx() 默认为 "float32",除非设置为其他值(通过 keras.backend.set_floatx())。如果提供了 keras.DTypePolicy,则将使用其 compute_dtype

示例

>>> batch_size = 2
>>> list_size = 5
>>> labels = np.random.randint(0, 3, size=(batch_size, list_size))
>>> scores = np.random.random(size=(batch_size, list_size))
>>> metric = keras_rs.metrics.NDCG()(
...     y_true=labels, y_pred=scores
... )

遮盖某些元素(可用于处理不均匀输入)

>>> batch_size = 2
>>> list_size = 5
>>> labels = np.random.randint(0, 3, size=(batch_size, list_size))
>>> scores = np.random.random(size=(batch_size, list_size))
>>> mask = np.random.randint(0, 2, size=(batch_size, list_size), dtype=bool)
>>> metric = keras_rs.metrics.NDCG()(
...     y_true={"labels": labels, "mask": mask}, y_pred=scores
... )