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

评价指标

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…

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

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

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

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

所有算法库的使用(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…

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

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

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

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

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

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

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

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

BN / LN / IN / GN /

链接 但是代码不敢苟同! 所以自己写了两种代码! 由于这只是测试, 并不是用来训练, 所以α和β参数就没有加! def BN(inputs):c inputs.shape[1]for i in range(c):channel inputs[:,i,:,:]mu np.mean(channel)var np.var(channel)channel_new ((channel - mu)/(np.sqrt(…

中文验证码 php_还在苦恼验证码怎么实现?看看这个验证码组件合集,你想要的都有...

随着安全性的要求越来越高&#xff0c;如今的验证码已经不再是简单的四个数字或者字母了&#xff0c;更复杂的图形验证码和行为验证码已经成为了更流行的趋势&#xff0c;但更难的实现也让很多开发者头秃&#xff0c;Gitee 已经替你们想到了这一点。不多说了&#xff0c;下面这…

reload端口 tomcat_tomcat上部署网站的三种方式

一、利用webapps文件夹自动部署这是最简单的方式&#xff0c;只要将网站直接拷贝到&#xff1a;tomcat根目录下的webapps文件夹里举例&#xff1a;helloworld文件夹下创建里index.html文件&#xff0c;然后把helloworld文件夹移动到tomcat根目录下webapps文件夹里&#xff0c;重…

不能用蛮力法解决的问题_溆浦事蒙汉:脱贫攻坚绝不能心浮气躁骄傲自满疲倦厌战...

脱贫攻坚绝不能心浮气躁骄傲自满疲倦厌战——蒙汉到卢峰镇检查“四支队伍”集村部工作情况检查南华山村“四支队伍”集村部工作情况与大潭村贫困户舒采米座谈红网溆浦讯(记者 伍交才)8月28日&#xff0c;市人大常委会副主任、县委书记蒙汉到卢峰镇南华山村、大潭村检查“四支队…

mock模拟接口测试 vue_vue+mock.js实现前后端分离

之前都是介绍在普通项目中使用mock.js&#xff0c;那么本次就来介绍一下在vue中使用mock.js实现前后端分离。安装&#xff1a;npm install mockjs这里先写个小案例介绍一下具体使用&#xff0c;写法不规范&#xff0c;仅供参考。然后案例讲完后我们讲具体的规范使用那么一起来看…

mysql slow log 分析工具_mysql slow log分析工具的比较

mysql 中的 slow log 是用来记录执行时间较长(超过 long_query_time 秒)的 sql 的一种日志工具。启用 slow log在 my.cnf 中设置[mysqld]slow_query_logonslow_query_log_filemysql-slow重启 MySQL 服务。五款常用工具mysqldumpslowmysqlslamyprofimysql-explain-slow-logmysql…

利用寄存器进入栈值交换

代码 varA, B: Word;beginA :1; B :2; asmmov ax, a //赋值 mov bx, b push ax //进栈 push bx pop ax //退栈 pop bx mov a, ax //利用栈先进后出, ax已退栈, 寄存器里的值为原bx 的值 mov b, bx //利用栈先进后出, bx已退栈, 寄存…

处理Excel,填充空白区域

在企业应用开发中经常是业务人员提供Excel的数据源&#xff0c;而开发人员将Excel数据导入到数据库中&#xff0c;然后在数据库中进行处理。在Excel中为了表示一种层次和所属关系&#xff0c;很多时候会产生很多空白的单元格。比如一个CRM数据&#xff0c;里面有销售团队、销售…

LeetCode 901. 股票价格跨度(单调栈)

1. 题目 编写一个 StockSpanner 类&#xff0c;它收集某些股票的每日报价&#xff0c;并返回该股票当日价格的跨度。 今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数&#xff08;从今天开始往回数&#xff0c;包括今天&#xff09;。 例如&#xff0c…

LeetCode 1300. 转变数组后最接近目标值的数组和(二分查找)

1. 题目 给你一个整数数组 arr 和一个目标值 target &#xff0c;请你返回一个整数 value &#xff0c; 使得将数组中所有大于 value 的值变成 value 后&#xff0c;数组的和 最接近 target &#xff08;最接近表示两者之差的绝对值最小&#xff09;。 如果有多种使得和最接近…

潜在语义分析(Latent Semantic Analysis,LSA)

文章目录1. 单词向量空间、话题向量空间1.1 单词向量空间1.2 话题向量空间2. 潜在语义分析算法2.1 例子3. 非负矩阵分解算法4. TruncatedSVD 潜在语义分析实践一种无监督学习方法&#xff0c;主要用于文本的话题分析其特点是通过矩阵分解发现文本与单词之间的基于话题的语义关系…