当前位置: 首页 > ai >正文

基于Jaccard算法的用户浏览历史推荐商品系统实战+springboot+vue源码实现

大家好,这里是小罗毕设工作室。今天给大家带来了一套完整的推荐系统: “基于Jaccard算法的用户浏览历史推荐商品系统”。 系统源码后端实现是springboot,前端是vue3。 

视频演示

基于Jaccard算法的用户浏览历史推荐商品系统实战

图片截图

算法原理介绍

假设我们有两个商品:商品A和商品B。商品A被用户{小明,小红,小张}浏览过,商品B被用户{小红,小张,小李}浏览过。

得到两个用户群体集合 : {小明,小红,小张}    {小红,小张,小李}  。

我们通过Jaccard算法,将两个集合先取交集得到 {小红,小张} ,大小是2 , 在取并集得到 {小明,小红,小张,小李},大小是4。

因此Jaccard相似度=2/4=0.5,这个值表示两个商品的相似程度,值越接近1表示两个商品越相似(被相同用户群体浏览),系统会优先推荐相似度高的商品。

实现流程

基础数据准备

首先我们需要准备用户的行为数据表:

CREATE TABLE `user_behaviors` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '行为ID,自增主键',`user_id` bigint NOT NULL COMMENT '用户ID',`item_id` bigint NOT NULL COMMENT '物品ID',`rating` decimal(3,1) DEFAULT NULL COMMENT '评分(1-5分)',`behavior_type` varchar(20) NOT NULL COMMENT '行为类型(VIEW-浏览,LIKE-喜欢,PURCHASE-购买)',`timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '行为发生时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户行为记录表';

之所以这里有评分字段,是因为后续要扩展 基于协同过滤算法的用户评分推荐系统

当然这里还要有用户表和商品表:

CREATE TABLE `items` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '物品ID,自增主键',`name` varchar(200) NOT NULL COMMENT '物品名称',`description` text COMMENT '物品描述',`category` varchar(50) DEFAULT NULL COMMENT '物品类别',`price` decimal(10,2) DEFAULT NULL COMMENT '物品价格',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='商品表';CREATE TABLE `users` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID,自增主键',
`username` varchar(50) NOT NULL COMMENT '用户名',
`email` varchar(100) NOT NULL COMMENT '用户邮箱',
`password` varchar(100) NOT NULL COMMENT '用户密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB  COMMENT='用户表';

表建立好之后,我们需要写好基本的用户登录,商品列表,商品详情等基础接口,然后保证有丰富的行为数据落库,这样推荐系统才能发挥作用。

这些基本的接口我就不讲了,主要讲解一下用户推荐接口的实现。

完整系统源码我已经整理清除:

gitcode巅抗目/hadluo2/springboot_vue.git

用户推荐接口的实现

我将代码的流程整理成了一个流程图,首先我们需要构造一个Map结构数据:

 这些数据就是查询用户行为表,将所有的行为数据,按照商品分类,每一个商品都对应了一个用户群体集合。

然后还是查询用户行为表 , 将当前用户的行为数据查询出来,进行下面流程:

 关键的核心点就是:将当前推荐用户买过的商品id对应其他也买过的这个商品的用户作为一个用户集合,然后取所有商品对应的用户群体集合(很多个),然后一个一个经过Jaccard算法计算相似度,把这个相似度最为评分,最后取出评分高的商品最为推荐商品。

讲到这里,你应该能懂了,下面看下关键代码实现:


/**完整代码实现:gitcode巅抗目/hadluo2/springboot_vue.git* 基于用户浏览历史推荐物品* 主要步骤如下:* 1. 获取用户最近的浏览记录,按时间倒序排列* 2. 获取所有用户的浏览记录,构建物品-用户倒排索引* 3. 计算用户最近浏览物品与其他物品的相似度* 4. 考虑时间衰减因素,为每个候选物品计算最终得分* 5. 返回得分最高的N个物品作为推荐结果* @param userId 用户ID* @param numRecommendations 推荐数量* @return 推荐的物品列表*/
public List<Item> recommendBasedOnBrowsingHistory(Long userId, int numRecommendations) {// 1. 获取用户最近的浏览记录// 创建查询条件:匹配用户ID和浏览行为,按时间戳降序排序LambdaQueryWrapper<UserBehavior> wrapper = new LambdaQueryWrapper<>();wrapper.eq(UserBehavior::getUserId, userId).eq(UserBehavior::getBehaviorType, "VIEW").orderByDesc(UserBehavior::getTimestamp);List<UserBehavior> userViews = userBehaviorRepository.selectList(wrapper);// 如果用户没有浏览记录,返回空列表if (CollectionUtils.isEmpty(userViews)) {return Collections.emptyList();}// 2. 获取所有用户的浏览记录// 查询所有用户的浏览行为,用于后续计算物品相似度List<UserBehavior> allViews = userBehaviorRepository.selectList(new LambdaQueryWrapper<UserBehavior>().eq(UserBehavior::getBehaviorType, "VIEW"));// 3. 构建物品-用户的倒排索引// key: 物品ID, value: 浏览过该物品的用户ID集合Map<Long, Set<Long>> itemUserMap = new HashMap<>();for (UserBehavior view : allViews) {// computeIfAbsent: 如果key不存在,则创建一个新的HashSetitemUserMap.computeIfAbsent(view.getItemId(), k -> new HashSet<>()).add(view.getUserId());}// 4. 计算物品相似度和推荐得分// 存储每个候选物品的最终得分Map<Long, Double> itemScores = new HashMap<>();// 获取用户已浏览过的物品ID集合,用于排除推荐Set<Long> userViewedItemIds = userViews.stream().map(UserBehavior::getItemId).collect(Collectors.toSet());// 遍历用户的每个浏览记录for (UserBehavior userView : userViews) {// 获取 浏览该物品的 所有用户Set<Long> itemUsers = itemUserMap.get(userView.getItemId());if (itemUsers == null) continue;// 遍历所有物品,计算与当前浏览物品的相似度for (Map.Entry<Long, Set<Long>> entry : itemUserMap.entrySet()) {Long otherItemId = entry.getKey();// 该用户浏览过了这个商品id, 直接排除if (userViewedItemIds.contains(otherItemId)) continue;// 浏览过这个商品的 其他用户Set<Long> otherItemUsers = entry.getValue();// 使用Jaccard相似度计算物品相似度// Jaccard相似度 = 两个集合的交集大小 / 并集大小//完整代码请见:gitcode巅抗目/hadluo2/springboot_vue.gitdouble similarity = calculateJaccardSimilarity(itemUsers, otherItemUsers);// 考虑时间衰减因素   相当于一个优化因子// 浏览时间越近,权重越大(1/1, 1/2, 1/3, ...)//完整代码请见:gitcode巅抗目/hadluo2/springboot_vue.git// 累加相似度得分(考虑时间权重)itemScores.merge(otherItemId, similarity * timeWeight, Double::sum);}}// 5. 生成推荐结果// 对候选物品按得分降序排序,选择前N个return itemScores.entrySet().stream().sorted(Map.Entry.<Long, Double>comparingByValue().reversed()).limit(numRecommendations).map(e -> itemRepository.selectById(e.getKey())).filter(Objects::nonNull).collect(Collectors.toList());
}

 代码只贴了部分,原理已经教给大家。

http://www.xdnf.cn/news/4040.html

相关文章:

  • 【东枫科技】代理销售 NVIDIA DGX Spark 您的桌上有一台 Grace Blackwell AI 超级计算机。
  • [Survey]Remote Sensing Temporal Vision-Language Models: A Comprehensive Survey
  • C++【继承】
  • 1688平台商品详情接口开发指南(含Python代码示例)
  • 【东枫科技】代理英伟达产品:智能网卡
  • DTU_DTU厂家_5G/4G DTU终端_DTU模块_厦门计讯物联科技有限公司
  • 为什么Transformer推理需要做KV缓存
  • 2025年游戏行业DDoS攻防指南:智能防御体系构建与实战策略
  • 【C++】类和对象(一)
  • 【FreeRTOS-时间管理】
  • 0-1背包问题基础概念
  • 家政平台派单系统设计与实现详解
  • transformer读后感
  • Linux系统编程--基础指令(!!详细讲解+知识拓展)
  • 位运算题目:按位与为零的三元组
  • 代码训练营day56图论岛屿数量与面积
  • LIO-SAM笔记(三)适配Livox 激光雷达
  • CSS兼容性:挑战与策略
  • 新Blue引擎启动M2提示该授权文件已经到期怎么解决?
  • 第五节:图像基本操作-图像读取、显示与保存
  • 拆解GCN(Graph Convolutional Network)单层迭代公式
  • 基于MicroPython的ESP32开发
  • YOLOv8 标签透明化与可视化优化指南
  • 两次解析格式化字符串 + 使用SQLAlchemy的relationship执行任意命令 -- link-shortener b01lersCTF 2025
  • C语言|函数的递归调用
  • 智算中心建设方案和前景分析
  • RHCE 第二次作业
  • LeetCode 热题 100 118. 杨辉三角
  • boke luntan shop edu自动化脚本
  • 民宿管理系统5