1、离线评估

在推荐系统的评估过程中,离线评估往往被当做最常用也是最基本的评估方法。顾名思义,离线评估是指在将模型部署于线上环境之前,在离线环境中进行的评估。由于不用部署到生产环境,离线评估没有线上部署的工程风险,也无须浪费宝贵的线上流量资源,而且具有测试时间短,同时进行多组并行测试、能够利用丰富的线下计算资源等诸多优点。

一个好的推荐系统,除了准确度外,还需要对内容的覆盖度,推荐的内容的多样性,新颖性,是否能给用户带来惊喜等。这些标准之间不一定是相互正向作用,有些标准之间存在一定的矛盾性,比如新颖性和惊喜可能会带来覆盖度的提升,但对准确度可能有一定损耗。有些标准,如新颖性和惊喜度,量化指标需根据具体业务场景制定,而准确度的度量,业绩基本使用AUC这个指标,或者是基于AUC优化后的指标。

2、评估指标

2.1、图表

注意P=TP+FN表示实际为正例的样本个数,N=FP+TN表示实际为负例的样本个数。

2.2、几个指标的定义:

正确率是一个很好很直观的评价指标,但是有时候正确率高并不能代表一个算法就好。比如某个地区某天地震的预测,假设我们有一堆的特征作为地震分类的属性,类别只有两个:0:不发生地震、1:发生地震。一个不加思考的分类器,对每一个测试用例都将类别划分为0,那那么它就可能达到99%的正确率,但真的地震来临时,这个分类器毫无察觉,这个分类带来的损失是巨大的。为什么99%的正确率的分类器却不是我们想要的,因为这里数据分布不均衡,类别1的数据太少,完全错分类别1依然可以达到很高的正确率却忽视了我们关注的东西。

(1)正确率/准确率(accuracy) = 所有预测正确的样本数量 /总样本数量,即 (TP+TN) / (P+N)。就是被分对的样本数除以所有的样本数,通常来说,正确率越高,分类器越好;Accuracy = (TP + TN) / (TP + TN + FP + FN)

(2)精确率(precision) = 预测正确的正类样本数量 / 预测为正类的样本数量 ,TP/(TP+FP),即预测为正的样本中,真正的正类占比。表示被分为正例的示例中实际为正例的比例。Precision = TP / (TP + FP)

(3)召回率(recall) = 预测正确的正类样本数量 / 实际为正类的样本数量 TP/(TP+FN),即所有正类中,正确预测的占比。召回率是覆盖面的度量,度量有多个正例被分为正例。Recall = TP / (TP + FN)

精确率是分类正确的正样本个数占分类器判定为正样本的样本个数的比例。召回率是分类正确的正样本个数占真正的正样本个数的比例。排序模型中,通常没有一个确定的阈值把预测结果直接判定为正样本或负样本,而是采用TopN排序结果的精确率和召回率来衡量排序模型的性能,即认为模型排序的TopN的结果即是模型判定的正样本,然后计算Precision@N和Recall@N。

(4)F1值 = 精确率 * 召回率 * 2 / (精确率 + 召回率) (F 值即为精确率和召回率的调和均值)。精确率和召回率是矛盾统一的两个指标,为提高精确率,分类器需要尽量在“更有把握时”才把样本预测为正样本,但往往会因过于保守而漏掉很多“没有把握”的正样本导致召回率降低。F1 = 2 * (Precision * Recall) / (Precision + Recall)

(5)对数损失

2.3 AUC和ROC

AUC是ROC曲线下面积(Area Under roc Curve)的简称,顾名思义,AUC的值就是处于ROC curve下方的那部分面积的大小。通常,AUC的值介于0.5到1.0之间,AUC越大,诊断准确性越高。在ROC曲线上,最靠近坐标图左上方的点为敏感性和特异性均较高的临界值。

(1)ROC曲线

ROC曲线的横坐标为False Positive Rate(FPR,假阳性率);纵坐标为True Positive Rate(TPR,真阳性率)。FPR和TPR的计算方法如下:

 (2)AUC

1、 AUC作为指标衡量模型时,不依赖于分类阈值的选取,而准确率、精确率、召回率、F1值对阈值的选取依赖大,不同的阈值会带来不同的结果,而从AUC的定义(ROC的生成)知道,AUC是根据所有分类阈值得到的,因此比单独依赖一个分类阈值的指标更有优势。AUC体现的是对样本的排序能力,与具体的分值无关,和推荐系统中的大多数业务场景更贴合,因为大多数业务场景关心item之间的相对序而不关心item的预测分。AUC对正负样本比例不敏感,也是它在业界被广泛使用的原因。公式如下:

2、举例说明

在给出的例子中,包含有2个正样本(A, B)和3个负样本(C, D, E),因此一共有6个(2*3)正负样本对,即公式中分母为6。接下来计算公式中的分子,即每个正负样本对的指示函数值:以A为正样本形成的正负样本对为(A, C), (A, D), (A, E),指示函数值分别为1,0.5,0;以B为正样本形成的正负样本对为(B, C), (B, D), (B, E),指示函数值分别为1,1,1。

3、代码实现

import numpy as np
from sklearn.metrics import roc_auc_scoredef get_auc(y_lables, y_scores):auc = roc_auc_score(y_lables, y_scores)print('AUC calculated by sklearn tools is {}'.format(auc))return aucdef calculate_auc_func1(y_labels, y_scores):pos_sample_ids = [i for i in range(len(y_labels)) if y_labels[i] == 1]neg_sample_ids = [i for i in range(len(y_labels)) if y_labels[i] == 0]sum_indicator_value = 0for i in pos_sample_ids:for j in neg_sample_ids:if y_scores[i] > y_scores[j]:sum_indicator_value += 1elif y_scores[i] == y_scores[j]:sum_indicator_value += 0.5auc = sum_indicator_value / (len(pos_sample_ids) * len(neg_sample_ids))print("AUC calculated by func1 is {}".format(auc))return aucdef calculate_auc_func2(y_labels, y_scores):samples = list(zip(y_scores, y_labels))rank = [(label, score) for label, score in sorted(samples, key=lambda x: x[0])]pos_rank = [i + 1 for i in range(len(rank)) if rank[i][1] == 1]pos_cnt = np.sum(y_labels == 1)neg_cnt = np.sum(y_labels == 0)auc = (np.sum(pos_rank) - (pos_cnt * (pos_cnt + 1) / 2)) / (pos_cnt * neg_cnt)print("AUC calculated by func2 is {}".format(auc))return aucif __name__ == '__main__':y_labels = np.array([1, 1, 0, 0, 0])y_scores = np.array([0.4, 0.8, 0.2, 0.4, 0.5])get_auc(y_labels, y_scores)calculate_auc_func1(y_labels, y_scores)calculate_auc_func2(y_labels, y_scores)

2.4、举例

1、准确率和召回率

2.5、二分类准确率/正确率

公式:accuracy = (正确预测的样本数量) / (总样本数量)

# 二分类准确率pytorch代码和公式
# accuracy = (正确预测的样本数量) / (总样本数量)import torchdef binary_accuracy(y_pred, y_true):rounded_preds = torch.round(torch.sigmoid(y_pred))correct = (rounded_preds == y_true).float().sum()accuracy = correct / y_true.size(0)return accuracy# 示例数据
y_pred = torch.tensor([0.2, 0.8, 0.6, 0.3])  # 模型的预测概率
y_true = torch.tensor([0, 1, 1, 0])  # 真实的目标标签accuracy = binary_accuracy(y_pred, y_true)
print("Binary Accuracy:", accuracy.item())

2.6、召回率

import torch
from sklearn.metrics import recall_scoredef recall_score_fun(y_pred, y_true):rounded_preds = torch.round(torch.sigmoid(y_pred))true_positives = torch.sum((rounded_preds == 1) & (y_true == 1)).float()false_negatives = torch.sum((rounded_preds == 0) & (y_true == 1)).float()recall = true_positives / (true_positives + false_negatives)return recall# todo 方式一(一直为1)
y_pred = torch.tensor([0.8, 0.1, 0.6, 0.8])  # 模型的预测概率
y_true = torch.tensor([0, 1, 1, 1])  # 真实的目标标签recall = recall_score_fun(y_pred, y_true)
print("Recall:", recall.item())# 将张量转换为NumPy数组,方式二
y_pred_np = y_pred.numpy()
y_true_np = y_true.numpy()recall = recall_score(y_true_np, y_pred_np.round())
print("Recall:", recall)

2.7、精确率

import torch
from sklearn.metrics import precision_scoredef precision_score_fun(y_pred, y_true):rounded_preds = torch.round(torch.sigmoid(y_pred))true_positives = torch.sum((rounded_preds == 1) & (y_true == 1)).float()false_positives = torch.sum((rounded_preds == 1) & (y_true == 0)).float()precision = true_positives / (true_positives + false_positives) if (true_positives + false_positives) != 0 else 0.0return precision# 方式一
y_pred = torch.tensor([0.2, 0.8, 0.6, 0.3])  # 模型的预测概率
y_true = torch.tensor([1, 0, 1, 1])  # 真实的目标标签precision = precision_score_fun(y_pred, y_true)
print("Precision:", precision.item())# 方式二
y_pred_np = y_pred.numpy()
y_true_np = y_true.numpy()precision = precision_score(y_true_np, y_pred_np.round())
print("Precision:", precision)

2.8、F1

import torch
from sklearn.metrics import f1_scoredef f1_score_fun(y_pred, y_true):rounded_preds = torch.round(torch.sigmoid(y_pred))true_positives = torch.sum((rounded_preds == 1) & (y_true == 1)).float()false_positives = torch.sum((rounded_preds == 1) & (y_true == 0)).float()false_negatives = torch.sum((rounded_preds == 0) & (y_true == 1)).float()precision = true_positives / (true_positives + false_positives) if (true_positives + false_positives) != 0 else 0.0recall = true_positives / (true_positives + false_negatives) if (true_positives + false_negatives) != 0 else 0.0f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) != 0 else 0.0return f1# 方式一
y_pred = torch.tensor([0.2, 0.8, 0.6, 0.3])  # 模型的预测概率
y_true = torch.tensor([0, 1, 1, 0])  # 真实的目标标签f1 = f1_score_fun(y_pred, y_true)
print("F1 Score:", f1.item())# 方式二
y_pred_np = y_pred.numpy()
y_true_np = y_true.numpy()f1 = f1_score(y_true_np, y_pred_np.round())
print("F1 Score:", f1)

参考:

推荐系统评测指标—准确率(Precision)、召回率(Recall)、F值(F-Measure) - 茄子_2008 - 博客园

CTR预估和auc的渊源 - 知乎

分类指标准确率(Precision)和正确率(Accuracy)的区别_青椒炒代码的博客-CSDN博客_precision分类

【0】推荐系统中评价指标相关推荐

  1. 从0到1详解推荐系统中的嵌入方法,原理、算法到应用都讲明白了

    (图片由AI科技大本营付费下载自视觉中国) 作者丨gongyouliu 编辑丨lily 来源 | 大数据与人工智能(ID:) 前言 作者曾在这篇文章中提到,矩阵分解算法是一类嵌入方法,通过将用户行为矩 ...

  2. 【推荐系统】推荐系统中的排序学习

    " 本文首先介绍排序学习的三种主要类别,然后详细介绍推荐领域最常用的两种高层排序学习算法框架:BPR和LambdaMART.因为排序学习的算法和实践大都来源于信息检索,一些理论也必须从信息检 ...

  3. 浅谈微视推荐系统中的特征工程

    本文作者:hannahguo,腾讯 PCG 推荐算法工程师 在推荐系统中,特征工程扮演着重要的角色.俗话说数据和特征决定了机器学习算法的上限,而模型.算法的选择和优化只是在不断逼近这个上限.特征工程的 ...

  4. [转]矩阵分解在推荐系统中的应用

    矩阵分解是最近几年比较火的算法,经过kddcup和netflix比赛的多人多次检验,矩阵分解可以带来更好的结果,而且可以充分地考虑各种因素的影响,有非常好的扩展性,因为要考虑多种因素的综合作用,往往需 ...

  5. 推荐系统常用评价指标和代码实现

    评价指标 Recall 名称: 召回率(真阳性率) 意义:在推荐系统中,我们只关心正确推荐的有多少,也就是用户真实喜欢的,并不会关心推荐错的,所以我们用召回率,而不是准确率: 理解这个前提:混淆矩阵 ...

  6. 浅谈矩阵分解在推荐系统中的应用

    为了方便介绍,假设推荐系统中有用户集合有6个用户,即U={u1,u2,u3,u4,u5,u6},项目(物品)集合有7个项目,即V={v1,v2,v3,v4,v5,v6,v7},用户对项目的评分结合为R ...

  7. 推荐系统中的排序学习

    " 本文首先介绍排序学习的三种主要类别,然后详细介绍推荐领域最常用的两种高层排序学习算法框架:BPR和LambdaMART.因为排序学习的算法和实践大都来源于信息检索,一些理论也必须从信息检 ...

  8. 关于推荐系统中的DOA

    关于推荐系统中的DOA 背景 DOA介绍 背景 在阅读文章<DisenQNet:Disentangled Representation Learning for Educational Ques ...

  9. 自己动手写一个推荐系统,推荐系统小结,推荐系统:总体介绍、推荐算法、性能比较, 漫谈“推荐系统”, 浅谈矩阵分解在推荐系统中的应用...

    自己动手写一个推荐系统 废话: 最近朋友在学习推荐系统相关,说是实现完整的推荐系统,于是我们三不之一会有一些讨论和推导,想想索性整理出来. 在文中主要以工程中做推荐系统的流程着手,穿插一些经验之谈,并 ...

最新文章

  1. axure按钮切换颜色_如何用Axure画出Web产品的列表组件:基础画法
  2. Highmaps网页图表教程之图表配置项结构与商业授权
  3. 权限管理系统中 管理员能看到所有用户的密码么_计算机毕设项目002之学生成绩管理系统...
  4. 大剑无锋之TCP和UDP区别【面试推荐】
  5. phalcon: 资源文件管 理 引入css,js
  6. android 揭示动画_如何使用意图揭示函数名称使代码更好
  7. C#LeetCode刷题之#7-反转整数(Reverse Integer)
  8. antimalware service executable占用内存过高_SQLServer占用服务器内存过高,更改这个设置就能降低内存使用率
  9. php函数里面传指针
  10. java中的criteria_java-jpa-criteriaBuilder使用入门
  11. 用Python分析了我的微信好友,原来我身边都是这样的人……绝了
  12. Java打包exe文件
  13. 单片机4x4矩阵键盘c语言,MSP430单片机控制LED数码管显示4X4矩阵键盘键值C语言程序...
  14. mac 右键 启动终端
  15. 自己集成的android容联云IMdemo效果展示
  16. ionic4 监听事件
  17. [工作必备]pandas数据分析处理52个常用技巧
  18. 行走在数据库上的行癫(四)
  19. 在word 页眉插入章编号+标题
  20. 2019年,免费微信多开软件哪个好?5款多开软件评测

热门文章

  1. 为什么要做特征归一化/标准化?
  2. Vue-axios使用QS(QueryString)插件,Vue-axios无法发送参数给后端(包含但不限于php)。
  3. 手机网站——移动互联网新趋势
  4. 医疗数字化:区块链或成最强辅助
  5. apple公司的潮起潮落——浪潮之巅
  6. 2020年7月份世界计算机编程语言排行榜
  7. 1. 创建第一个harmonyos工程
  8. (十五)路过师大 - 4
  9. idea 实时更新网页内容(修改代码同时刷新网页即可同步内同)
  10. Python中ArcPy实现对大量长时间序列栅格遥感影像批量逐像元求取像素平均值