PyTorch推荐系统Hit@10计算逻辑验证及ARHR@10实现咨询
1. Hit@10计算逻辑与正确性说明
逻辑拆解
你给出的Hit@10实现是推荐系统评估里非常常用的负采样配对评估范式,核心是把1个用户的正交互物品和N个负采样物品放在一起排序,判断正样本是否进入Top10,代码行hits10 = (torch.sum(neg_r > r, 1) <= 10).numpy()的运行逻辑分三步:
- 第一步
neg_r > r:逐行比较每个负样本的预测分和对应正样本的预测分,返回布尔矩阵,True代表该负样本的排序比正样本更靠前 - 第二步
torch.sum(neg_r > r, 1):按行对布尔矩阵求和,得到每个正样本对应的「排名高于它的负样本数量k」,正样本的实际排名就是k+1 - 第三步
sum结果 <= 10:判断正样本是否进入Top序列,最终的hits10数组每个元素代表对应用户的正样本是否命中,对数组求平均就是整体Hit@10指标
正确性修正
这个实现的核心逻辑是对的,但判断条件存在细节误差:
Hit@10的标准定义是正样本排名≤10就算命中,对应k的取值应该是≤9,也就是判断条件应该改为
torch.sum(neg_r > r, 1) < 10。原代码的<=10会把排名第11位的正样本也算作命中,和标准Hit@10定义不符。
如果你的业务场景自定义Hit@10包含前11位,那原代码是符合要求的。
2. ARHR@10实现方法
ARHR(Average Reciprocal Hit Rank)又称平均倒数命中排名,ARHR@10的计算规则是:只有正样本进入Top10时,才将其排名的倒数计入总得分,未进入Top10的样本贡献为0,最终取所有样本得分的平均值。
基于你现有的代码框架,可以直接通过如下逻辑实现:
def RecEvaluate(model, g, features, users_eval, movies_eval, neg_sample_size): model.eval() with torch.no_grad(): neg_movies_eval = data.neg_valid[users_eval].flatten() r, neg_r = model.est_rating(g, features, users_eval, movies_eval, neg_movies_eval) # 计算高于正样本的负样本数量 higher_neg_cnt = torch.sum(neg_r > r, 1) # 修正后的Hit@10计算 hits10 = (higher_neg_cnt < 10).numpy() # ARHR@10计算 rank = higher_neg_cnt + 1 # 排名≤10的取1/rank,否则取0 arhr10 = torch.where(rank <=10, 1.0 / rank, torch.tensor(0.0, dtype=torch.float32)).numpy().mean() print('HITS@10:{:.4f} ARHR@10:{:.4f}'.format(np.mean(hits10), arhr10)) return np.mean(hits10), arhr10
内容的提问来源于stack exchange,提问作者Driss AL
相关产品推荐
相关产品推荐

