J3Medium★ Core Essential · Industrial BedrockPart J · RecSys & Search Metrics
NDCG@K (Normalized Discounted Cumulative Gain)
Industrial-grade implementation and mathematical foundations of NDCG@K (Normalized Discounted Cumulative Gain).
⏱️ Time Complexity:
O(K log K) 理想排序开销💾 Space Complexity:
O(K)💡
Core Mental Anchor / Mnemonic
Master NDCG@K (Normalized Discounted Cumulative Gain): enforce numerical stability, check tensor shapes, and eliminate redundant memory allocations.
📐 Mathematical Derivation & Core Formula
### Mathematical Derivation & Theoretical Principles
Detailed first-principles formulation and architectural mechanics for NDCG@K (Normalized Discounted Cumulative Gain).
Refer to the LaTeX equation above for the core operator definition. The operator is designed to ensure strict numerical bounds, avoiding floating-point overflows and gradient anomalies.
Detailed first-principles formulation and architectural mechanics for NDCG@K (Normalized Discounted Cumulative Gain).
Refer to the LaTeX equation above for the core operator definition. The operator is designed to ensure strict numerical bounds, avoiding floating-point overflows and gradient anomalies.
🔄 Tensor Dimensions & Shape Flow
相关度列表 -> 截取前 K -> (2^rel - 1)/log2(i+2) sum 得 DCG -> 降序理想排列算 IDCG -> DCG/IDCG
🛡️ Industrial Numerical Stability & Pitfalls
- Ensure proper multi-dimensional tensor broadcasting and keepdims retention.
- Enforce numerical guards (eps clamping and overflow thresholds) during exponentiation and division.
- Verify train versus eval mode behavioral distinctions (e.g. frozen running statistics and dropout bypass).
💻 Industrial Code Implementation
import numpy as np
def compute_ndcg_at_k(relevance_scores: list, k: int = 10) -> float:
"""
参数:
relevance_scores: 按推荐/搜索排序给出的真实相关度得分列表 (如 [3, 2, 0, 1])
k: 截断位置
"""
rel = np.asarray(relevance_scores)[:k]
if len(rel) == 0:
return 0.0
# 1. 计算实际预测顺序的 DCG@K
discounts = np.log2(np.arange(len(rel)) + 2) # i=0 时 log2(2)=1.0
gains = 2.0 ** rel - 1.0
dcg = np.sum(gains / discounts)
# 2. 计算理想完美顺序下的 IDCG@K
ideal_rel = np.sort(np.asarray(relevance_scores))[::-1][:k]
ideal_gains = 2.0 ** ideal_rel - 1.0
ideal_discounts = np.log2(np.arange(len(ideal_rel)) + 2)
idcg = np.sum(ideal_gains / ideal_discounts)
if idcg == 0.0:
return 0.0
return float(dcg / idcg)
🧪 Runnable Assertions & Validation
Copy and run directly in Python / Jupyter to verify correctness:
import numpy as np
# 完美排序
assert compute_ndcg_at_k([3, 2, 1, 0], k=3) == 1.0
# 最差逆序
ndcg_bad = compute_ndcg_at_k([0, 1, 2, 3], k=4)
assert 0.0 < ndcg_bad < 1.0
print("✓ NDCG@K 排名增益评估自测通过")🎯 Core Architecture Follow-up Q&A
Q1:What are the key trade-offs and memory bottlenecks when deploying NDCG@K (Normalized Discounted Cumulative Gain) in high-throughput inference?
Memory bandwidth (HBM to SRAM I/O) is the primary latency factor. Fusing element-wise operations and avoiding intermediate tensor materialization significantly outperforms naive implementations.
Q2:How does NDCG@K (Normalized Discounted Cumulative Gain) handle extreme numerical boundaries or precision reduction (FP16/BF16/INT8)?
Under low precision, operations must be upcasted to FP32 during accumulation to prevent underflow/overflow, followed by proper scaling and clamping before converting back to the target format.