Fast Matrix Factorization for Online Recommendation with Implicit Feedback论文代码分析

1 数据结构

userCount:用户数
itemCount:项目数
user_ratings:ArrayList<ArrayList>,
问:此处为什么要用二维数组?
答:第1维是用户,第2维是用户对所有项目的评分。
testRatings:ArrayList
问:此处为什么只用一维数组?
答:个人认为这个处理有问题,因为每个用户有1-2个评分作为测试集,如果用一维数组,则数组的下标就不能和用户id(userId)一一对应。

2 读取评分:ReadRatings_HoldOneOut

步骤如下:

  1. 从文件中一行行读取,然后存入user_ratings中,存储后如下:
    用户0:
    [<0,0,4.0,0>,<0,1,4.0,0>,…,<0,64,5.0,0>,<0,65,3.0,0>][<0,0,4.0,0>, <0,1,4.0,0>, \dots, <0,64,5.0,0>, <0,65,3.0,0>][<0,0,4.0,0>,<0,1,4.0,0>,,<0,64,5.0,0>,<0,65,3.0,0>]
    注:<userId, itemId, score, timestamp>,<0,0,4.0,0><0,0,4.0,0><0,0,4.0,0>可以解读为用户0对项目0在0时刻评分为4.0分。
    用户1:
    [<1,0,5.0,0>,<1,66,4.0,0>,…,<1,192,1.0,0>,<1,193,5.0,0>][<1,0,5.0,0>, <1,66,4.0,0>, \dots, <1,192,1.0,0>, <1,193,5.0,0>][<1,0,5.0,0>,<1,66,4.0,0>,,<1,192,1.0,0>,<1,193,5.0,0>]
    用户2:
    [<2,0,5.0,0>,<2,194,5.0,0>,…,<2,202,5.0,0>,<2,203,5.0,0>][<2,0,5.0,0>, <2,194,5.0,0>, \dots, <2,202,5.0,0>, <2,203,5.0,0>][<2,0,5.0,0>,<2,194,5.0,0>,,<2,202,5.0,0>,<2,203,5.0,0>]
  2. 利用user_ratings构造训练集和测试集testRatings
    [<0,65,3.0,0>,<0,64,5.0,0>,<1,193,5.0,0>,<1,192,1.0,0>,<2,203,5.0,0>,<2,202,5.0,0>,<3,278,5.0,0>,<3,277,4.0,0>,<4,290,4.0,0>,<4,289,5.0,0>,<5,328,2.0,0>,<5,327,5.0,0>,<6,394,4.0,0>,<6,393,5.0,0>,<7,406,5.0,0>,<7,405,2.0,0>,<8,420,3.0,0>,<8,419,3.0,0>,<9,482,5.0,0>,<9,481,4.0,0>,…][<0,65,3.0,0>, <0,64,5.0,0>, <1,193,5.0,0>, <1,192,1.0,0>, <2,203,5.0,0>, <2,202,5.0,0>, <3,278,5.0,0>, < 3,277,4.0,0>, <4,290,4.0,0>, <4,289,5.0,0>, <5,328,2.0,0>, <5,327,5.0,0>, <6,394,4.0,0>, <6,393,5.0,0>, <7,406,5.0,0>, <7,405,2.0,0>, <8,420,3.0,0>, <8,419,3.0,0>, <9,482,5.0,0>, <9,481,4.0,0>, \dots][<0,65,3.0,0>,<0,64,5.0,0>,<1,193,5.0,0>,<1,192,1.0,0>,<2,203,5.0,0>,<2,202,5.0,0>,<3,278,5.0,0>,<3,277,4.0,0>,<4,290,4.0,0>,<4,289,5.0,0>,<5,328,2.0,0>,<5,327,5.0,0>,<6,394,4.0,0>,<6,393,5.0,0>,<7,406,5.0,0>,<7,405,2.0,0>,<8,420,3.0,0>,<8,419,3.0,0>,<9,482,5.0,0>,<9,481,4.0,0>,]
    问:这种方式有问题没有?
    答:有,测试集由于是一个一维的列表,导致利用testRatings.get(u).itemId这个代码来取数据的时候,u并不是指代某个用户id,而是列表中某个位置的下标,容易误解为用户id和项目id不匹配。

上面的不匹配是由于下面的代码导致的,由于每一个用户将最后两个评分加入到测试集,导致用户id和列表的下标对应不上。

//if (i == ratings.size() - 1) { // test
if (i == ratings.size() - 1 || i == ratings.size() - 2) { // testtestRatings.add(ratings.get(i));//the size of testing =	 the number of users.
} else { // traintrainMatrix.setValue(userId, itemId, ratings.get(i).score);
}//of if

方案(1):改成如下代码即可,使得每个用户只有一个评分加入测试集,即测试集大小和用户数一致

if (i == ratings.size() - 1) { // test
//if (i == ratings.size() - 1 || i == ratings.size() - 2) { // testtestRatings.add(ratings.get(i));//the size of testing =	 the number of users.
} else { // traintrainMatrix.setValue(userId, itemId, ratings.get(i).score);
}//of if

方案(2):可以用二维列表来存储测试集。

3 evaluate_for_user的理解

3.1 数据结构

map_item_score:HashMap<Integer, Double>,散列表。HashMap的主干是一个Entry数组,Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。

HashMap<Integer, Double> map_item_score = new HashMap<Integer, Double>();

ignoreSet:HashSet ,HashSet 基于 HashMap 来实现的,一个不允许有重复元素的集合。

3.2 代码解读

	/*** Evaluation for a specific user with given GT item.对具有给定Groud-Truth项目的特定用户的评估* @return:* 	 result[0]: hit ratio* 	 result[1]: ndcg* 	 result[2]: precision*/protected double[] evaluate_for_user(int u, int gtItem) {double[] result = new double[3];HashMap<Integer, Double> map_item_score = new HashMap<Integer, Double>();// Get the score of the test item first.double maxScore = predict(u, gtItem);// Early stopping if there are topK items larger than maxScore.int countLarger = 0;for (int i = 0; i < itemCount; i++) {double score = predict(u, i);//预测用户u对所有项目的评分map_item_score.put(i, score);//将预测评分放入散列表中,key为i,value为score//下面的两句的作用是只要gtItem没有进入TopK则不计算三个评价指标?if (score > maxScore)	countLarger ++;if (countLarger > topK)	return result;	// early stopping}// Selecting topK items (does not exclude train items).ArrayList<Integer> rankList = ignoreTrain ? CommonUtils.TopKeysByValue(map_item_score, topK, trainMatrix.getRowRef(u).indexList()) : CommonUtils.TopKeysByValue(map_item_score, topK, null);result[0] = getHitRatio(rankList, gtItem);result[1] = getNDCG(rankList, gtItem);result[2] = getPrecision(rankList, gtItem);return result;}/*** Get the topK keys (by its value) of a map. Does not consider the keys which are in ignoreKeys.* @param map* @return*/public static<K, V extends Comparable<? super V>> ArrayList<K> TopKeysByValue(Map<K, V> map, int topK, ArrayList<K> ignoreKeys) {HashSet<K> ignoreSet;if (ignoreKeys == null) {ignoreSet = new HashSet<K>();} else {ignoreSet = new HashSet<K> (ignoreKeys);//将训练集中用户u购买过的项目放入ignoreSet}//因为map保存的是所有项目,如果要忽略训练集中的项目,则将训练集之外的项目写入topQueueTopKPriorityQueue<K, V> topQueue = new TopKPriorityQueue<K, V>(topK);for (Map.Entry<K, V> entry : map.entrySet()) {if (!ignoreSet.contains(entry.getKey())) {topQueue.add(entry);}}//对topQueue中的元素进行排序,排序后保存在topKeys并返回ArrayList<K> topKeys = new ArrayList<K>();for (Map.Entry<K, V> entry : topQueue.sortedList()) {topKeys.add(entry.getKey());}return topKeys;}public ArrayList<Map.Entry<K, V>> sortedList() {ArrayList<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(queue); Collections.sort(list, c.reversed()); return list;}

Collections.sort参考博客https://baijiahao.baidu.com/s?id=1660417080221659283&wfr=spider&for=pc

这里还用到了一个非常重要的接口Comparable。
功能: Comparable接口可用于对象的排序或者对象的分组

介绍: Comparable接口强行对实现它的类的每个实例进行自然排序,该接口的唯一方法compareTo方法被称为自然比较方法
方法: int compareTo(Object o)

利用当前对象和传入的目标对象进行比较:

  • 若是当前对象比目标对象大,则返回1,那么当前对象会排在目标对象的后面
  • 若是当前对象比目标对象小,则返回-1,那么当前对象会排在目标对象的后面
  • 若是两个对象相等,则返回0
import java.util.Arrays;public class User implements Comparable<User> {public int age;public String username;public User(int age, String username) {this.age = age;this.username = username;}@Overridepublic String toString() {return this.username;}@Overridepublic int compareTo(User o) {if(this.age>o.age) {return 1;} else if(this.age<o.age) {return -1;} else {return 0;}}public static void main(String[] args) {User[] arr = new User[3];arr[0] = new User(15,"user1");arr[1] = new User(10,"user2");arr[2] = new User(20,"user3");System.out.println("排序前:" + Arrays.toString(arr));Arrays.sort(arr);System.out.println("排序后:" + Arrays.toString(arr));}
}排序前:[user1, user2, user3]
排序后:[user2, user1, user3]

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

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

相关文章

stacking模型融合_【干货】比赛后期大招之stacking技术分享

各位同学大家好&#xff0c;我是本次参赛选手李博&#xff0c;比赛ID是深蓝&#xff08;DeePBluE&#xff09;。现在就读于北京邮电大学&#xff0c;是一名研一的在校生&#xff0c;研究方向是数据分析和机器学习。是的&#xff0c;我又来分&#xff08;na&#xff09;享&#…

多stream_基础之Lambda和Stream的邂逅

基础之Lambda和Stream的邂逅show me the code and take to me,做的出来更要说的明白GitHub项目JavaHouse同步收录喜欢就点个赞呗! 你的支持是我分享的动力&#xff01;引入是否有遇到看不懂身边同事代码的情况&#xff0c;是否有被面试官问到 Java 新特性不懂的情况。我掐指一算…

注意力机制--转载自我的学生隆兴写的博客

原文链接为&#xff1a;https://a-egoist.com/posts/a44b8419/&#xff0c;学生自己搭建的博客&#xff0c;点赞&#xff01; 1 Attention 1.1 什么是 Attention 灵长类动物的视觉系统中的视神经接受了大量的感官输入。在检查视觉场景时&#xff0c;我们的视觉神经系统大约每…

python正弦波和等腰三角波_正弦波脉宽调制(SPWM)原理

1、QPWM的概念 在进行脉宽调制时&#xff0c;使脉冲系列的占空比按正弦规律来安排。当正弦值为最大值时&#xff0c;脉冲的宽度也最大&#xff0c;而脉冲间的间隔则最小&#xff0c;反之&#xff0c;当正弦值较小时&#xff0c;脉冲的宽度也小&#xff0c;而脉冲间的间隔则较大…

推荐系统--矩阵分解(1)

推荐系统–矩阵分解(1) 推荐系统–矩阵分解(2) 推荐系统–矩阵分解(3) 推荐系统–矩阵分解(4) 推荐系统–矩阵分解(5) 推荐系统–矩阵分解(6) 1 引入 一个矩阵可以分解为两个小矩阵的乘积&#xff0c;以音乐为例&#xff0c;利用潜在特征向量来给用户和音乐打上标签&#xff…

python dag调度系统开发_基于机器学习的DAG调度平台

什么是DAG?有向无环图树形结构&#xff1a;除根节点&#xff0c;每个节点有且仅有一个上级节点&#xff0c;下级节点不限。根节点没有上级节点。图结构&#xff1a;每个节点上级、下级节点数不限。DAG调度平台的定义及场景任务调度是在各行各业是个基础问题&#xff0c;当任务…

轻量级人脸识别算法

1 概述 轻量级人脸识别算法

python元组与列表的区别、简答题_细解python面试题(一)元组和列表的区别

可能略去了一些内容。1、列表VS元组在python编程中&#xff0c;我们经常搞不懂列表和元组的区别&#xff0c;或者哪些函数可以用于列表&#xff0c;哪些用于元组&#xff0c;那么跟随本文我们来深入的探索。2、元组元组是值的集合&#xff0c;我们用圆括号来申明它。元组中的类…

Yolo家族算法分析

1 历史简介 2 YOLO算法思想 YOLO算法的基本思想&#xff1a; &#xff08;1&#xff09;将图片划分为SSS \times SSS个网格&#xff1b; &#xff08;2&#xff09;计算每个边界框和置信度&#xff1b; &#xff08;3&#xff09;计算每个网格属于某个类别的概率&#xff1b; &…

u8 附件上传后存放路径_织梦DedeCms附件按月份保存的修改方法

正常情况下&#xff0c;dedecms织梦系统的图片附件是按日保存的&#xff0c;一天一个文件夹, 时间长了, 这样在allimg中就会生成很多文件夹, 不方便管理&#xff0e;虽然&#xff0c;dedecms织梦的后台设置有”附件保存形式”的先项, 但功能太弱&#xff0c;如果是在后台上传和…

推荐系统--矩阵分解(2)

推荐系统–矩阵分解(1) 推荐系统–矩阵分解(2) 推荐系统–矩阵分解(3) 推荐系统–矩阵分解(4) 推荐系统–矩阵分解(5) 推荐系统–矩阵分解(6) 3 BiasSVD&#xff1a;考虑偏置 有一些用户会给出偏高的评分&#xff0c;有一些物品也会收到偏高的评分&#xff0c;比如电影观众为…

tga文件怎么打开_教你win10系统怎么打开stp文件

stp文件怎么打开呢&#xff1f;近来有很多小伙伴反映有朋友发送了一个stp文件给它&#xff0c;搞了半天也没能打开。其实打开stp文件很简单&#xff0c;不过前提是需要有绘图软件。我给大家整理了打开stp文件的图文教程&#xff0c;赶紧来瞧瞧吧有些朋友在使用win10系统的过程中…

python爬取电子病历_一种基于中文电子病历的实体识别方法技术

本发明专利技术提供了一种基于中文电子病历的实体识别方法&#xff0c;涉及医疗实体识别技术领域。针对目前国内缺少公开中文电子病历标注语料库的缺陷&#xff0c;本发明专利技术通过构建整理医学词典&#xff0c;提出了一种半自动语料库标注方法&#xff0c;节省了人工标注的…

推荐系统--矩阵分解(4)

推荐系统–矩阵分解(1) 推荐系统–矩阵分解(2) 推荐系统–矩阵分解(3) 推荐系统–矩阵分解(4) 推荐系统–矩阵分解(5) 推荐系统–矩阵分解(6) 7 基于情感分析的矩阵分解 7.1 引入 【摘要】推荐系统旨在基于丰富的信息预测用户的偏好&#xff0c;例如用户评分、人口统计和评论…

yarn 卸载包_0609-6.1.0-如何卸载CDH6.1

1.文档编写目的Fayson在两年前的文章中介绍过CDH的卸载&#xff0c;参考《如何卸载CDH(附一键卸载github源码)》。除非你是使用Cloudera官方提供的一键安装脚本安装的CDH&#xff0c;否则并没有现成的一键卸载的脚本供使用。为了更好的理解CDH的卸载&#xff0c;这里再次简单介…

推荐系统--矩阵分解(3)

推荐系统–矩阵分解(1) 推荐系统–矩阵分解(2) 推荐系统–矩阵分解(3) 推荐系统–矩阵分解(4) 推荐系统–矩阵分解(5) 推荐系统–矩阵分解(6) 5 TimeSVD&#xff1a;增加时间因素 物品的受欢迎度随着时间而改变&#xff0c;例如&#xff0c;电影可以因外部事件(如新电影中演员…

python安装不了是什么问题_安装不上python的模块怎么办?别怕,我这有妙招!

之前我们介绍过如何在Python中安装第三方的包&#xff1a;Python以第三方包丰富而著称&#xff0c;你想要的功能几乎都可以通过pip命令安装&#xff0c;避免什么都要自己重新造轮子尬尴。但是pip安装有两个常见问题&#xff0c;第一是下载慢&#xff0c;第二是无法安装。慢的原…

推荐系统--矩阵分解(5)

推荐系统–矩阵分解(1) 推荐系统–矩阵分解(2) 推荐系统–矩阵分解(3) 推荐系统–矩阵分解(4) 推荐系统–矩阵分解(5) 推荐系统–矩阵分解(6) 8 基于隐式反馈的矩阵分解 8.1 引入 相对于显示反馈的评分数据&#xff0c;隐式反馈有以下几方面的特征&#xff1a; 只有正反馈&…

xss跨站脚本攻击_网络安全xss跨站脚本攻击原理

以下在未经授权的网站操作均为违法行为XSS跨站脚本攻击xss的危害网络钓鱼&#xff0c;盗取各类账号密码我们先来看一下下面的案例&#xff1a;先来记住一下下面中的表我们来做一个转发上面页面显示已经登录&#xff0c;但是突然页面中提醒再此登录此时&#xff0c;我们并没有多…

推荐系统--联邦学习下的矩阵分解(6)

推荐系统–矩阵分解(1) 推荐系统–矩阵分解(2) 推荐系统–矩阵分解(3) 推荐系统–矩阵分解(4) 推荐系统–矩阵分解(5) 推荐系统–矩阵分解(6) 9 应用于联邦学习的矩阵分解 这个部分主要参考以下两篇论文&#xff1a; 2008-Collaborative Filtering for Implicit Feedback Dat…