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

评价指标

Recall

  • 名称: 召回率(真阳性率)

  • 意义:在推荐系统中,我们只关心正确推荐的有多少,也就是用户真实喜欢的,并不会关心推荐错的,所以我们用召回率,而不是准确率;

  • 理解这个前提:混淆矩阵
    混淆矩阵: 详细的可以自己去了解
    在这里插入图片描述
    Recall = TP / (TP + FN)
    也就是你所有预测为True的里面,到底有多少是真实值!

  • Recall@n指的是推荐的前n个的召回率有多少

代码实现比较简单

ROC(AUC)

  • 名称: Curve曲线, AUC是ROC下面的面积
  • 意义:ROC的效果是看AUC的面积大小决定的; 如果AUC等于1,那么就是预测全部正确
  • 要明白这个,必须知道混淆矩阵。
    ROC的横坐标是FP,纵坐标是TP,一般而言,TP要大于FP,所以曲线是一个凸函数,而且AUC>0.5
    AUC的面积越大,说明效果更好
   def confusion_marix(predict_label,  true_label):true_lable = true_labelTP, TN, FP, FN = 0,0,0,0for predict, true in zip(predict_label, true_lable):if predict == true == 1:TP += 1elif predict == true == 0:TN += 1  # 怎么写? 先写后面的  N和P,再写前面预测正确还是错误elif predict == 1 and true == 0:  # 预测为1,但是真实的是0,所以是错误的PFP += 1else:  # predict == 0 and true == 1:  # 预测为0,但是真实的是1,所以是错误的NFN += 1ACC = (TP + TN) / (len(true_lable))TPR = TP / (TP + FN)  # 召回率PPV = FP / (TP + FP)  # 精准率F1 = 2 / (1 / TPR + 1 / PPV)return ACC, TPR, PPV, F1

NGCG(Normalized Discounted Cummulative Gain)

  • 名称:归一化折损累计增益

  • 意义:在搜索和推荐任务中,系统常返回一个item列表。如何衡量这个返回的列表是否优秀呢?可以用于评价基于打分/评分的个性推荐系统。

  • 要理解这个,得从点点了解开始; 相关性是人工打标签上去的,不要问为什么
    NDCG
    G-CG-DCG-NDCG

  • G = Gain: 表示列表中每一个item的相关性分数
    在这里插入图片描述

  • CG = Cumulative Gain:表示对K个item的相关性进行累加
    在这里插入图片描述

  • DCG = Discounted Cumulative Gain:考虑排序顺序的因素,使得排名靠前的item增益更高,对排名靠后的item进行log折损。
    在这里插入图片描述
    如果相关性分数r(i)只有(0,1)两种取值时,DCG@K有另一种表达。其实就是如果算法返回的排序列表中的item出现在真实交互列表中时,分子加1,否则跳过。
    在这里插入图片描述

  • NDCG = Normalized Discounted Cumulative Gain:
    DCG能够对一个用户的推荐列表进行评价,如果用该指标评价某个推荐算法,需要对所有用户的推荐列表进行评价,由于用户真实列表长度不同,不同用户之间的DCG相比没有意义。
    所以要对不同用户的指标进行归一化,自然的想法就是计算每个用户真实列表(指的是groudtruth)的DCG分数,用IDCG表示,然后用每个用户的DCG与IDCG之比作为每个用户归一化后的分值,最后对每个用户取平均得到最终的分值,即NDCG。
    在这里插入图片描述

#coding=utf-8import numpy as np# 复现求和运算的公式# 有求和运算的,K一般是传入的list的长度
# 单元素:一般是先处理求和符号右边的;
# 多元素:生成列表;
# 然后最后再聚合(np.sum)# 1. 得到一个用户的DCG评分
# 这种是相关性分数是连续的
def getDCG_list(scores):return np.sum([np.divide(score, np.log2(1+i)) for i, score in enumerate(scores)])
# 这种相关性分数是0和1
def getDCG2_list(scores):return np.sum([np.divide(2 ** score - 1, np.log2(1+i)) for i, score in enumerate(scores, start=1)])# 但是,其实np里面所有的加减乘除都是传播的,单个元素之间分别操作! 所以不用遍历
def getDCG(relavance):return np.divide(relavance, np.log2(1 + np.arange(1, len(relavance) + 1)))def getDCG2(scores): # 如果相关性只有0和1用这个return np.divide(2 ** scores - 1, np.log2(1 + np.arange(1, scores.shape[0] + 1)))# 2. DCG / IDCG 所有真实列表的全部
def getNDCG(predict_list, true_list, true_relavance, true_rel_dict):# 结果为1的原因是因为代码里相关性得分的定义是只要出现在真实列表中就为1,推荐问题里这么设置是比较常见的preict_relavance = np.asarray([true_rel_dict.get(it, 1.0) for it in predict_list], dtype=np.float32) # 获得precit的分数idcg = getDCG(true_relavance)dcg = getDCG(preict_relavance)# if dcg == 0.0:#     return 0.0ndcg = dcg / idcgreturn ndcg
predict_list = [3, 2, 1]   # 预测结果
true_list = [1, 2, 3]   # 真实的结果
true_relavance = [i for i in range(3, 0, -1)]
true_rel_dict = {it: r for it, r in zip(true_list, true_relavance)}  # 定义相关性字典,方便predict_item查找相应的分数
a = getNDCG(predict_list, true_list, true_relavance, true_rel_dict)
print(a)

Hit(Hit Ratio)

  • 名称:击中率
  • 意义:在top-K推荐中,HR是一种常用的衡量召回率的指标,而且只是在测试为用户推荐的items是不是在用户的真实集合中,并不在乎先后顺序!
  • 计算公式为:
    在这里插入图片描述
# coding=utf-8# HR@K: 表示模型推荐的top-K中有几个被推荐了
# 可以发现是永远小于1的,而且应该是增长的! 不用质疑错没错,就是这么定义的
def hit(pred_items, gt_items):  # 这里指的是一个用户的预测! 不在乎排序! 只要推荐了就行hititems = [pred_item for pred_item in pred_items if pred_item in gt_items]hr = len(hititems) / len(gt_items)return hr, hititems# 加入hit@5
pred_items = [3, 4, 2, 100, 1000]
gt_items = [1, 2, 3, 4, 5, 6, 7, 8]
hr, hititems = hit(pred_items, gt_items)
print(hr)

MAP(Mean Average Precision)

  • 所有用户的平均命中率AP = MAP
  • 意义: 仅仅是准确率(召回率或者是HR)是不行的,还得看你的推荐顺序,比如搜索引擎里的推荐TOPK,是不是把命中的的排序到前面,而未命中的排序到了后面(这里只有命中和非命中的顺序之分,而没有区分具体的每个item的顺序);
    比如:【命中,命中,未命中,未命中,未命中】和【未命中,未命中,未命中,命中,命中】显然它们的准确率都是2/5,但是第一个更好。

注意: 预测的items只要在gt中有,那么就是命中了,我们关系的是命中的顺序,而不是精确的,物品2在gt中是第一个,那么预测的物品2也必须是第一个。

  • 先看AP,一个用户的
    在这里插入图片描述
    在这里插入图片描述

KKK表示推荐列表的长度;
UUU表示的用户数量;
mmm用户实际选择的物品数;
nnn给用户推荐的项目数;
P(k)P(k)P(k)指的是截止到第k个,有多少项目命中
如预测的第一个排名命中了,截止到第一个,命中率是1/1;
第二个排名没有命中,那么就是0;
第三个排名命中了,截止到第三个,有两个命中,命中率就是2/3
rel(k)rel(k)rel(k)指的是排名第k的项目是不是被用户实际选择;是为1,不是为0
所以对于推荐列表【命中,命中,未命中,未命中,未命中】,假设该用户在测试集中实际选择了3个项目,则

在这里插入图片描述

def AP(pred_items, gt_items):cu_hits = 0   # 累计命中cu_precision = 0  # 累加命中率for i, pred_item in enumerate(pred_items, start=1):if pred_item in gt_items:cu_hits += 1cu_precision += cu_hits / i # 每步一算if cu_hits > 0:return cu_precision / len(gt_items)else:return 0pred_items = [3, 4, 2, 100, 1000]
gt_items = [1, 2, 3, 4, 5, 6, 7, 8]
AP = AP(pred_items, gt_items)
print(AP)

MRR(Mean Reciprocal Rank)

  • 名称:平均倒数排序
  • 意义: 要查询的结果值在返回的结果中的排名。)是一个国际上通用的对搜索算法进行评价的机制。(仅仅是排名)
    可以用在序列推荐中
    在这里插入图片描述
  • 正确检索结果值在检索结果中的排名来评估检索系统的性能
    在这里插入图片描述
    假如检索三次的结果如下,需要的结果(cat,torus,virus)分别排在3,2,1的话,排在results的第三个结果就是1/3,排在第二个则是1/2
    (注意分母不是所有的结果的个数,而是排名)
    在这里插入图片描述
def MRR(pred_items, gt_items):rank = 0for pred_item in pred_items:if pred_item in pred_items:rank = gt_items.index(pred_item) + 1rank += 1/rankreturn rankpred_items = [3, 4, 2, 100, 1000]
gt_items = [1, 2, 3, 4, 5, 6, 7, 8]
MRR = MRR(pred_items, gt_items)
print(MRR)

ILS

  • 意义:ILS 衡量推荐列表多样性的指标,计算公式
    在这里插入图片描述
    如果,S(bi,bj)S(b_i, b_j)S(bi,bj)计算的是iiijjj两个物品的相似性,如果推荐列表中的物品越不相似,ILS越小,那么推荐结果的多样性越好。

coverage

推荐系统能够推荐出来的物品占总物品集合的比例。
热门排行榜的推荐覆盖率是很低的! 因为热门物品占总体物品是很低的一部分

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/476053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

哥谈的是语言,不是寂寞

经常看到一些文章在谈论语言,例如“哪个语言更有前途”,“语言选择是否关键”。我是个语言粉丝,但是看到这些文章总有一些奇怪的感觉。因为在我看来,这些文章谈的东西都不是我眼中的语言——可能与国内技术环境有关,语…

python timeit用法_十大Python开发技巧

Python开发指南, 超级实用足以让您震撼> Photo by Christina Morillo from StockSnap时不时地,当我了解Python的新功能时,或者我发现其他一些人不知道该功能时,我会记下它。在过去的几周中,我最近了解或实现了一些有趣的功能-S…

python编程中的经验(一直更新)

文章目录1. python基础语法1.1 怎么让两个list或者其它可以迭代的放到一起1.2 random.choice(x, n, replaceTrue) numpy中从某个数据集中选择1.3 如何根据key返回字典的value1.4 The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all…

LeetCode 953. 验证外星语词典

1. 题目 某种外星语也使用英文小写字母,但可能顺序 order 不同。 字母表的顺序(order)是一些小写字母的排列。 给定一组用外星语书写的单词 words,以及其字母表的顺序 order,只有当给定的单词在这种外星语中按字典序…

Cairngorm初学者入门教程 第六节--Cairngorm中Command利用Delegate与Service连接

在上一节,我们利用FrontController 去映射 Event与Command 在这一节我们主要针对Command这部分动作做介紹。在RIA应用程序中,不可或缺的部份就是跟后台服务器连接进行数据传递。Command通过Delegate去做Services的部份(包含Remoting,WebServices,…等) C…

3d点击_3D打印服务加工在医疗器械行业的应用

3D打印技术如今已经很常见的出现在了我们日常的制造生产中。普通的3D打印机从最开始的几万块到如今的几千块,设备价格的降低也使得3D打印技术普及率的增加,而技术的普及也推动着技术的发展。3D打印开始应用到许多行业当中,下面悟空打印坊3D打…

LeetCode 1033. 移动石子直到连续

1. 题目 三枚石子放置在数轴上&#xff0c;位置分别为 a&#xff0c;b&#xff0c;c。 每一回合&#xff0c;我们假设这三枚石子当前分别位于位置 x, y, z 且 x < y < z。 从位置 x 或者是位置 z 拿起一枚石子&#xff0c;并将该石子移动到某一整数位置 k 处&#xff0…

所有算法库的使用(sklearn,scipy)

文章目录1. sklearn1.1 sklearn.preprocessing 之 fit 和 transform 以及 fit_transform1.2 算法之 fit 和 predict和predict_proba1.3 predict_proba1.4 各种评测指标1.4.1 R2R^2R21.4.2 准确度、精准率、召回率1.4.3 平均绝对误差(MAE)和均方误差(MSE)1.5 特征缩放 StandardS…

Perl文档操作选项

文件测试操作符 操作符 描述 -b 是否为块设备 -c 是否为字符设备 -d 是否为目录 -e 是否存在 -f 是否为普通文件 -g 是否设置了setgid位 -k 是否设置了sticky位 -l 是否为符号链接 -o 是否拥有该文件 -p 是否为管道 -r 是否可读 -s 是否非空 -t 是否表…

android aar保存图片文件异常_我去!合并AAR时踩坑了!

点击上方“刘望舒”&#xff0c;马上关注&#xff0c;早上8:42推送真爱&#xff0c;请置顶或星标作者: leeon7https://www.jianshu.com/p/8f7e32015836背景在输出Android模块时&#xff0c;有时会因为个别原因(比如来自业务的不可抗力)&#xff0c;要求将模块打包成一个文件提供…

LeetCode 1037. 有效的回旋镖

1. 题目 回旋镖定义为一组三个点&#xff0c;这些点各不相同且不在一条直线上。 给出平面上三个点组成的列表&#xff0c;判断这些点是否可以构成回旋镖。 示例 1&#xff1a; 输入&#xff1a;[[1,1],[2,3],[3,2]] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a…

与kylin_Kylin 迁移到 HBase 实践在小米的实践

背景小米Kylin生产环境部署的是基于社区2.5.2修改的内部版本&#xff0c;所依赖HBase集群是一个公共集群&#xff0c;小米内部很多离线计算服务共享使用该HBase集群。由于Kylin已经产生超过6000张HBase表&#xff0c;给HBase的metadata管理造成了不小的压力&#xff0c;HBase m…

jupyter切换内核

激活环境 conda activate envname 安装jupyter pip install jupyter pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jupyter 安装ipkernel pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ipykernel 设置名字 python -m ipykernel install --use…

LeetCode 1227. 飞机座位分配概率(DP+数学归纳法)

1. 题目 有 n 位乘客即将登机&#xff0c;飞机正好有 n 个座位。第一位乘客的票丢了&#xff0c;他随便选了一个座位坐下。 剩下的乘客将会&#xff1a; 如果他们自己的座位还空着&#xff0c;就坐到自己的座位上&#xff0c; 当他们自己的座位被占用时&#xff0c;随机选择…

应广单片机adc_应广PMC232系列单片机 12位ADC PWM LCD 双核心8位MCU

PMC232系列 台湾应广 一级代理 现货批发 长期供应带12位ADC、采用FPPATM技术、双核心8位单片机PMC232为P232的升级版&#xff0c;内部基准电压更准&#xff0c;节省TL431。工作电压更宽&#xff0c;功耗更低&#xff0c;可用于移动式手持设备。引入单一FPPA运作模式&#xff0c…

网络动态负载均衡算法分析

转自CSDN博客&#xff1a;http://blog.csdn.net/wallacexiang/archive/2009/07/24/4376147.aspx   随着Internet的日益普及&#xff0c;无论在企业网、园区网还是在广域网如Internet上&#xff0c;用户与业务量呈现出指数性增长&#xff0c;尤其是在网络的关键节点和核心网络…

pymysql连接以及连接池的理解

mysql连接 1. 不使用连接池 我们知道使用pymysql连接数据库一般需要下面的步骤: 创建连接对象(一般使用connect或者是连接池) 创建游标对象 使用游标执行代码 使用游标获取结果并返回 # 返回的是元组(每个实例一个元组)! 关闭游标和连接 conn pymysql.connect(host, p…

LeetCode 1025. 除数博弈(动态规划)

1. 题目 爱丽丝和鲍勃一起玩游戏&#xff0c;他们轮流行动。爱丽丝先手开局。 最初&#xff0c;黑板上有一个数字 N 。在每个玩家的回合&#xff0c;玩家需要执行以下操作&#xff1a; 选出任一 x&#xff0c;满足 0 < x < N 且 N % x 0 。用 N - x 替换黑板上的数字…

python iterator iterable_Python中Iterator和Iterable的区别

python中list, str&#xff0c;truple, dict都是可以被迭代的&#xff0c;但他们不是迭代器。why?list/truple/map/dict这些数据的大小是确定的&#xff0c;我们可以准确知道他们的size。迭代器不知道要执行多少次&#xff0c;所以可以理解为不知道有多少个元素&#xff0c;每…

javascript之嵌套函数

在javascript中允许使用嵌套函数: <head><meta http-equiv"Content-Type" content"text/html; charsetgb2312" /><title>嵌套函数</title><script type"text/javascript"> function fun1(){ function fun…