柚见第十二期(随机匹配)

随机匹配

目的
为了帮大家更快地发现和自己兴趣相同的朋友
问题

匹配 1 个还是匹配多个?

答:匹配多个,并且按照匹配的相似度从高到低排序

怎么匹配?(根据什么匹配)

答:标签 tags
还可以根据 user_team 匹配加入相同队伍的用户
本质:找到有相似标签的用户
举例:
用户 A:[Java, 大一, 男]
用户 B:[Java, 大二, 男]
用户 C:[Python, 大二, 女]
用户 D:[Java, 大一, 女]

1. 怎么匹配
  1. 找到有共同标签最多的用户(TopN)

  2. 共同标签越多,分数越高,越排在前面

  3. 如果没有匹配的用户,随机推荐几个(降级方案)

2. 怎么对所有用户匹配,取 TOP

直接取出所有用户,依次和当前用户计算分数,取 TOP N

优化方法:

  1. 切忌不要在数据量大的时候循环输出日志(取消掉日志后 20 秒)
  2. Map 存了所有的分数信息,占用内存解决:
    维护一个固定长度的有序集合(sortedSet),只保留分数最高的几个用户(时间换空间)
    e.g : 【3, 4, 5, 6, 7】取 TOP 5,id 为 1 的用户就不用放进去了
  3. 细节:剔除自己 √
  4. 尽量只查需要的数据:
    a. 过滤掉标签为空的用户 √
    b. 根据部分标签取用户(前提是能区分出来哪个标签比较重要)
    c. 只查需要的数据(比如 id 和 tags) √(7.0s)
  5. 提前查?(定时任务)
  6. 提前把所有用户给缓存(不适用于经常更新的数据)
  7. 提前运算出来结果,缓存(针对一些重点用户,提前缓存)

大数据推荐

比如说有几亿个商品,难道要查出来所有的商品?
难道要对所有的数据计算一遍相似度?

检索 => 召回 => 粗排 => 精排 => 重排序等等

检索:尽可能多地查符合要求的数据(比如按记录查)
召回:查询可能要用到的数据(不做运算)
粗排:粗略排序,简单地运算(运算相对轻量)
精排:精细排序,确定固定排位

分表学习建议

  1. mycat框架
  2. sharding sphere 框架
  3. 一致性hash

随机匹配实现

编辑距离算法:

https://blog.csdn.net/DBC_121/article/details/104198838
最小编辑距离:字符串 str1 通过最少多少次增删改字符的操作可以变成字符串str2

! 没学过,不要紧,直接当成黑盒导入使用即可

余弦相似度算法:

https://blog.csdn.net/m0_55613022/article/details/125683937(如果需要带权重计算,比如学什么方向最重要,性别相对次要)

后端

引入工具类

新建工具类
cv 代码过来

在这里插入图片描述

简单测试一下

在这里插入图片描述

之前都是传入字符串,而实际需要比较的是两组字符数组

在这里插入图片描述

测试一下,是可以的

在这里插入图片描述

取出所有用户,依次和当前用户计算分数

bug : 笑死,为什么这里打印出来和数据库不一样

在这里插入图片描述

解决

使用这段代码成功

for (int i = 0; i <userList.size(); i++) {  
User user = userList.get(i);  
String userTags = user.getTags();  
//无标签的  
if (StringUtils.isBlank(userTags)){  
continue;  
}  
List<String> userTagList = gson.fromJson(userTags, new TypeToken<List<String>>() {  
}.getType());  
//计算分数  
int distance = AlgorithmUtils.minDistance(tagList, userTagList);  
indexDistanceMap.put(i,distance);  
}

使用这段代码失败
明明一样

for (int i = 0; i < userList.size(); i++) {  
User user=userList.get(i);  
String userTags=user.getTags();  
//判断用户是否有标签列表  
if(StringUtils.isBlank(userTags))  
{  
continue;  
}  
//将tags字符串转换为List  
List<String> userTagList=gson.fromJson(tags,new TypeToken<List<String>>(){  
}.getType());  
//计算分数(分数越低,相似度越高)  
int distance=AlgorithmUtils.minDistance(tagList,userTagList);  
indexDistanceMap.put(i,distance);  
}

在这里插入图片描述

完整代码

public List<User> matchUsers(int num, User loginUser) {  
  
QueryWrapper<User> queryWrapper = new QueryWrapper<>();  
queryWrapper.isNotNull("tags");  
queryWrapper.select("id","tags");  
//1.查询所有用户  
List<User> userList=this.list(queryWrapper);  
//2.获取当前登录用户的标签  
//todo 前端传来可能是多个标签,这里是以字符串形式传递的吗?????  
String tags=loginUser.getTags();  
Gson gson=new Gson();  
//将字符串转换为List  
List<String> tagList=gson.fromJson(tags,new TypeToken<List<String>>(){  
  
}.getType());  
System.out.println("当前登录用户的tagList : "+tagList);  
//用户列表的下标:相似度  
List<Pair<User,Integer>> list=new ArrayList<>();  
//3.遍历用户列表,获得相似度分数  
for (int i = 0; i < userList.size(); i++) {  
User user=userList.get(i);  
String userTags=user.getTags();  
//判断无标签或者当前user是登录用户  
if(StringUtils.isBlank(userTags) || loginUser.getId().equals(user.getId()))  
{  
continue;  
}  
//将tags字符串转换为List  
List<String> userTagList=gson.fromJson(userTags,new TypeToken<List<String>>(){  
}.getType());  
//计算分数(分数越低,相似度越高)  
int distance=AlgorithmUtils.minDistance(tagList,userTagList);  
list.add(new Pair<>(user,distance));  
}  
//4.按照编辑距离由小到大排序  
List<Pair<User, Integer>> topUserPairList = list.stream()  
.sorted((a, b) ->(int) (a.getValue() - b.getValue()))  
.limit(num)  
.collect(Collectors.toList());  
//有顺序的userID列表  
List<Integer> userListVo = topUserPairList.stream().map(pari -> pari.getKey().getId()).collect(Collectors.toList());  
  
//根据id查询user完整信息  
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();  
userQueryWrapper.in("id",userListVo);  
  
Map<Integer, List<User>> userIdUserListMap = this.list(userQueryWrapper)  
.stream()  
.map(user -> getSafetyUser(user))  
.collect(Collectors.groupingBy(User::getId));  
  
// 因为上面查询打乱了顺序,这里根据上面有序的userID列表赋值  
List<User> finalUserList = new ArrayList<>();  
for (Integer userId : userListVo){  
finalUserList.add(userIdUserListMap.get(userId).get(0));  
}  
return finalUserList;  
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据可视化】使用Python + Gephi,构建中医方剂关系网络图!

代码和示例数据下载 前言 在这篇文章中&#xff0c;我们将会可视化 《七版方剂学》 的药材的关系&#xff0c;我们将使用Python制作节点和边的数据&#xff0c;然后在Gephi中绘制出方剂的网络图。 Gephi是一个专门用于构建网络图的工具&#xff0c;只要你能提供节点和边的数…

Microsoft Word 符号 / 特殊符号

Microsoft Word 符号 / 特殊符号 1. 插入 -> 符号 -> 其他符号 -> Wingdings 2References 1. 插入 -> 符号 -> 其他符号 -> Wingdings 2 ​ References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

Android FrameWork 学习路线

目录 前言 学习路线&#xff1a; 1.基础知识 2、AOSP 源码学习 3. AOSP 源码编译系统 4. Hal与硬件服务 5.基础组件 6. Binder 7. 系统启动过程分析 8. 应用层框架​编辑 9. 显示系统 10. Android 输入系统 11. 系统应用 前言 Android Framework 涉及的行业相当广…

SpringAI——Java生态接入LLM

最近&#xff0c;Spring官网发布了SpringAI&#xff0c;可点此查看https://spring.io/blog/2024/03/12/spring-ai-0-8-1-released&#xff0c;对于SpringAI的介绍&#xff0c;可看官方文档&#xff1a;https://spring.io/projects/spring-ai#overview。 本文将使用SpringAI配合…

Linux内核有什么之块设备驱动有什么第四回 —— 邂逅的三个文件系统之二:实际文件系统(1)

接前一篇文章&#xff1a;Linux内核有什么之块设备驱动有什么第三回 —— 邂逅的三个文件系统之一&#xff1a;devtmpfs 本文内容参考&#xff1a; 34 | 块设备&#xff08;上&#xff09;&#xff1a;如何建立代理商销售模式&#xff1f;-趣谈Linux操作系统-极客时间 Linux内…

vscode通过多个跳板机连接目标机(两种方案亲测成功)

1、ProxyJump&#xff08;推荐使用&#xff09; 需要OpenSSH 7.3以上版本才可使用&#xff0c;可用下列命令查看&#xff1a; ssh -V ProxyJump命令行使用方法 ssh -J [email protected]:port1,[email protected]:port2 一层跳板机&#xff1a; ssh dst_usernamedst_ip -…

【Spring 篇】SpringMVC拦截器:给你的应用增添色彩

嗨&#xff0c;亲爱的小伙伴们&#xff01;欢迎来到这段关于SpringMVC拦截器的奇妙之旅。今天我们要一探究竟&#xff0c;深入挖掘拦截器的神秘面纱&#xff0c;看看它是如何在你的应用中悄然发挥作用的。别怕&#xff0c;我会用最通俗易懂的语言&#xff0c;一步一步带你走进这…

Python之requests实现github模拟登录

文章目录 github 模拟登录前言模拟登录流程抓包操作查看登录表单的内容登录操作 模拟登录操作在 main函数的调用获得 auth_token调用/session接口登录处理检测登录是否成功 总结&#xff1a; github 模拟登录 前言 前面学习了requests模块的基础学习后&#xff0c;接下来做一个…

c++算法学习笔记 (8) 树与图部分

1.树与图的存储 &#xff08;1&#xff09;邻接矩阵 &#xff08;2&#xff09;邻接表 // 链式前向星模板&#xff08;数组模拟&#xff09; #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N 100010, M …

GAMES104-现代游戏引擎 1

主要学习重点还是面向就业&#xff0c;重点复习八股和算法 每天早上八点到九点用来学习这个课程 持续更新中... 第一节 游戏引擎导论 第二节 引擎架构分层

jvm的垃圾回收器以及触发full gc的场景

JVM&#xff08;Java虚拟机&#xff09;的垃圾回收器有很多种&#xff0c;主要包括以下几种&#xff1a; Serial收集器&#xff1a;串行收集器是最古老、最稳定的收集器。它使用单个线程进行垃圾收集工作&#xff0c;在进行垃圾回收时会暂停所有用户线程。 ParNew收集器&#…

Mr-Robot1靶场练习靶场推荐小白入门练习靶场渗透靶场bp爆破wordpress

下载链接&#xff1a; Mr-Robot: 1 ~ VulnHub 安装&#xff1a; 打开vxbox&#xff0c;菜单栏----管理----导入虚拟电脑 选择下载完的ova文件&#xff0c;并修改想要保存的位置&#xff08;也可以保持默认位置&#xff09; 导入完成后可以根据自己的情况去配置网络链接方式 完成…

AI健身教练-引体向上-俯卧撑计数代码-仰卧起坐姿态估计-康复训练姿态识别-姿态矫正(附代码)

在AI健身应用中&#xff0c;通过关键点检测技术可以实现对用户动作的精准捕捉和分析&#xff0c;从而进行统计计数和规范性姿态识别。 统计计数&#xff1a;比如在做瑜伽、健身操等运动时&#xff0c;系统可以通过对人体关键点&#xff08;如手部、脚部、关节等&#xff09;的…

【Java设计模式】二十五、自定义Spring IoC

文章目录 1、IoC类的定义1.1 定义bean相关的pojo类PropertyValue1.2 定义MutablePropertyValues类1.3 定义BeanDefinition类 2、定义注册表相关类2.1 BeanDefinitionRegistry接口2.2 SimpleBeanDefinitionRegistry类 3、定义解析器相关类3.1 BeanDefinitionReader接口3.2 XmlBe…

还是了解下吧,大语言模型调研汇总

大语言模型调研汇总 一. Basic Language ModelT5GPT-3LaMDAJurassic-1MT-NLGGopherChinchillaPaLMU-PaLMOPTLLaMABLOOMGLM-130BERNIE 3.0 Titan 二. Instruction-Finetuned Language ModelT0FLANFlan-LMBLOOMZ & mT0GPT-3.5ChatGPTGPT-4AlpacaChatGLMERNIE BotBard 自从Cha…

FFmpeg转码参数说明及视频转码示例

-b : 设置音频或者视频的转码码率 -b:v 只设置视频码率 -b:a 只设置音频码率 -ab: 只设置音频码率, 默认码率大小为: 128k bit/s -g: 设置视频GOP大小,表示I帧之间的间隔,默认为12 -ar: 设置音频采样率,默认0 -ac: 设置音频通道数量 默认0 -bf: 设置连…

[自研开源] MyData 数据集成之数据过滤 v0.7.2

开源地址&#xff1a;gitee | github 详细介绍&#xff1a;MyData 基于 Web API 的数据集成平台 部署文档&#xff1a;用 Docker 部署 MyData 使用手册&#xff1a;MyData 使用手册 试用体验&#xff1a;https://demo.mydata.work 交流Q群&#xff1a;430089673 概述 本篇基于…

spring boot nacos注册微服务示例demo_亲测成功

spring boot nacos注册微服务示例demo_亲测成功 先安装好Nacos Nacos安装使用 创建Maven项目 结构如图 例如项目名为: test-demo 下面有个子模块: test-demo-data-process 父模块pom.xml <?xml version"1.0" encoding"UTF-8"?> <project …

【Flink SQL】Flink SQL 基础概念(三):SQL 动态表 连续查询

《Flink SQL 基础概念》系列&#xff0c;共包含以下 5 篇文章&#xff1a; Flink SQL 基础概念&#xff08;一&#xff09;&#xff1a;SQL & Table 运行环境、基本概念及常用 APIFlink SQL 基础概念&#xff08;二&#xff09;&#xff1a;数据类型Flink SQL 基础概念&am…

数据有噪声?滤它!Python数据滤波详解

文章目录 维纳滤波巴特沃斯滤波器中值滤波排序滤波 Python科学计算&#xff1a;数组&#x1f4af;数据生成&#x1f4af;数据交互&#x1f4af;微积分&#x1f4af;插值&#x1f4af;拟合&#x1f4af;FFT&#x1f4af;卷积 维纳滤波 信号经过系统之后&#xff0c;相当于进行…