springboot集成mahout实现简单基于协同过滤算法的文章推荐算法
文章目录
- 前言
- 1.建表并且生成一些数据
- 首先,建立一个用户文章操作表(user_article_operation)
- 使用case when语句简单分析数据
- 2. 代码与测试
- 只需要根据表生成相应实体类(注意要加一个value属性来存储分数)
- 主要代码如下,其实就两个方法
- userArticleOperationMapper.getAllUserPreference()方法收集数据mapper文件如下
- 测试算法
- 3.核心代码
- 4.相关参考
前言
我这里只是简单的跑了一下,仅供参考。。
这边只是跑了个文章推荐的demo,不过什么电影,商品啥的都一样,没啥区别
温馨提醒
这个mahout包有毒。。。。很多依赖冲突。。。。
这是我的pom文件,仅仅供参考。。
<dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.3</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.30</version><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version></dependency><!--引入推荐引擎mahout,注意要先全部引入,再使用exclusion标签--><dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-mr</artifactId><version>0.12.2</version><exclusions><exclusion><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-jcl</artifactId></exclusion><exclusion><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId></exclusion><exclusion><groupId>org.apache.lucene</groupId><artifactId>lucene-analyzers-common</artifactId></exclusion><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion><exclusion><artifactId>jersey-client</artifactId><groupId>com.sun.jersey</groupId></exclusion><exclusion><artifactId>jersey-core</artifactId><groupId>com.sun.jersey</groupId></exclusion><exclusion><artifactId>jersey-apache-client4</artifactId><groupId>com.sun.jersey.contribs</groupId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
1.建表并且生成一些数据
首先,建立一个用户文章操作表(user_article_operation)
然后生成一些数据,这里使用navicat生成了50条记录(因为只是测试一下算法的准确性因此只生成了3个用户,10篇文章)
使用case when语句简单分析数据
SELECTuser_id,article_id,SUM(CASE operation_typeWHEN 0 THEN 3WHEN 1 THEN 3WHEN 2 THEN 5else 0 END) AS "value"FROMuser_article_operationGROUP BY user_id,article_idORDER BY user_id
执行语句如下
可以看出
1号用户最喜欢6,9号文章,
2号用户最喜欢4,5,6号文章
3号用户最喜欢4,5,6号文章
发现1,2,3号用户都喜欢6号文章,3个用户具有一定相似性。
(别问为啥这么规律,问就是我为了好测试修改了下数据,如果你感觉哪里不对劲的话,那你说的都对(反正我搞这个算法只是用来糊弄老师的😂😂😂))
因此如果要给1号用户推荐文章的话,应该先推荐5号,再推荐4号文章。
2. 代码与测试
只需要根据表生成相应实体类(注意要加一个value属性来存储分数)
主要代码如下,其实就两个方法
userArticleOperationMapper.getAllUserPreference()方法收集数据mapper文件如下
测试算法
输入推荐5个,但是这里只推荐了四个,应该是样本数据量太小的原因,对比了一下之前运行case when语句时做的的简单预测,5号最推荐,然后是4号,控制台打印的结果还是比较符合的。
(反正糊弄一下老师够了,这里只是提供一个小demo,读者需注意哈🚗🚗🚗🚗)
3.核心代码
public List<Long> recommend( Integer userId) throws TasteException {List<UserArticleOperation> userList = userArticleOperationMapper.getAllUserPreference();//创建数据模型DataModel dataModel = this.createDataModel(userList);//获取用户相似程度UserSimilarity similarity = new UncenteredCosineSimilarity(dataModel);//获取用户邻居UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(2, similarity, dataModel);//构建推荐器Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, similarity);//推荐2个List<RecommendedItem> recommendedItems = recommender.recommend(userId, 5);List<Long> itemIds = recommendedItems.stream().map(RecommendedItem::getItemID).collect(Collectors.toList());return itemIds;}private DataModel createDataModel(List<UserArticleOperation> userArticleOperations) {FastByIDMap<PreferenceArray> fastByIdMap = new FastByIDMap<>();Map<Integer, List<UserArticleOperation>> map = userArticleOperations.stream().collect(Collectors.groupingBy(UserArticleOperation::getUserId));Collection<List<UserArticleOperation>> list = map.values();for(List<UserArticleOperation> userPreferences : list){GenericPreference[] array = new GenericPreference[userPreferences.size()];for(int i = 0; i < userPreferences.size(); i++){UserArticleOperation userPreference = userPreferences.get(i);GenericPreference item = new GenericPreference(userPreference.getUserId(), userPreference.getArticleId(), userPreference.getValue());array[i] = item;}fastByIdMap.put(array[0].getUserID(), new GenericUserPreferenceArray(Arrays.asList(array)));}return new GenericDataModel(fastByIdMap);}
<select id="getAllUserPreference" resultType="UserArticleOperation">SELECTuser_id,article_id,SUM(CASE operation_typeWHEN 0 THEN 2WHEN 1 THEN 3WHEN 2 THEN 5else 0 END) AS "value"FROMuser_article_operationGROUP BY user_id,article_id</select>
4.相关参考
1.spring boot项目基于mahout推荐算法实现商品推荐
2.相关内容在章节5-9
相关文章:

springboot集成mahout实现简单基于协同过滤算法的文章推荐算法
文章目录前言1.建表并且生成一些数据首先,建立一个用户文章操作表(user_article_operation)使用case when语句简单分析数据2. 代码与测试只需要根据表生成相应实体类(注意要加一个value属性来存储分数)主要代码如下&am…...

自动驾驶介绍系列 ———— 看门狗
文章目录硬件看门狗软件看门狗差异分析延申窗口看门狗硬件看门狗 硬件看门狗的本质上是一个定时器电路。通常存在一个输入,输入到MCU的RST端。在正常工作状态下,MCU每隔固定时间间隔会输出一个信号给RST端,实现对看门狗端清零。如果在指定的时…...

今天打开个税APP,我直接人麻了!
点击上方“码农突围”,马上关注这里是码农充电第一站,回复“666”,获取一份专属大礼包真爱,请设置“星标”或点个“在看这是【码农突围】的第 432 篇原创分享作者 l 突围的鱼来源 l 码农突围(ID:smartyuge&…...

javascript进阶学习笔记(含AJAX)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、JS变量(var、let和const)二、for/in循环三、正则表达式语法:正则表达式修饰符:正则表达式模式字符串方法&…...
今年没有金三银四
最近好几个铁子咨询目前的大环境如何,甚至还有几个CTO和总监级别的大佬想跳槽问有没有对应的岗位。 又到了每年金三银四的时间点,往年(去年除外)这个时候用工市场都是一遍火热,大家跳槽涨薪好不快活。 面对这些咨询我…...

NFS - Network FileSystem网络文件系统的实现原理
文章目录PreNFS简介NFS共享数据结构图NFS服务器的实现原理是否安装nfs安装配置NFSPre NFS - MIPS架构下构建NFS共享目录服务 NFS简介 NFS的全称是Network FileSystem,即网络文件系统 NFS最初是由 Sun Microsytem 公司开发出来的,主要实现的功能是让网络…...

C#【汇总篇】语法糖汇总
文章目录0、语法糖简介1、自动属性2、参数默认值和命名参数3、类型实例化4、集合4.1 初始化List集合的值4.2 取List中的值5、隐式类型(var)6、扩展方法【更换测试实例】7、匿名类型(Anonymous type)【待补充】8、匿名方法…...

高完整性系统工程(一): Safety Engineering, HAZOP Fault Tree Analysis
目录 1. 因果性不等同于相关性 2. HAZOP 2.1 学习HAZOP 2.2 HAZOP概览 2.3 Assessing Hazard Risks 评估 2.4 示例场景 2.5 HAZOP Guidewords 2.6 HAZOP Process 2.7 HAZOP Outcomes 2.8 HAZOP Summary 3. FAULT TREE ANALYSIS 3.1 Analysis Outcomes 1. 因果性不等…...
VGG16分类模型的网页界面(Flask,keras)
开发一个网页版的VGG16模型界面可以分为以下几个步骤: 步骤1:数据准备 首先要准备一组图片数据集,建议使用ImageNet数据集,该数据集包含超过1000个类别和100万张图像。您可以将ImageNet数据集转换为Keras的格式。如果您没有Imag…...
互联网摸鱼日报(2023-03-12)
互联网摸鱼日报(2023-03-12) InfoQ 热门话题 又拍云邵海杨:25年Linux老兵聊DevOps八荣八耻 快猫来炜:如何端好运维的饭碗 作业帮聂安:运维如何转型,听听作业帮的OPaS思路 CTO药方:如何搭建运…...

SpringBoot异常处理?用这两个就够啦!
在日常项目中,我们难免会遇到系统错误的情况。如果对系统异常的情况不做处理,Springboot本身会默认将错误异常作为接口的请求返回。 GetMapping("/testNorError") public void testNorError() {try {throw new MyException(6000, "我…...
mysql-查询重复数据的条数-count
查询重复数据的条数 select name , count(*) from table group by name; 查询结果:查询表table中name相同重复的个数 补充:count的用法 查询一个表中总共多少行(多少条数据) select count (*) from table 小结 …...

【Java枚举类】使用enum关键词定义枚举类
使用说明 1.使用 enum 定义的枚举类默认继承了 java.lang.Enum类,因此不能再继承其他类 2.枚举类的构造器只能使用 private 权限修饰符 3.枚举类的所有实例必须在枚举类中显式列出(, 分隔 ; 结尾)。列出的 实例系统会自动添加 public static final 修饰 4.必须在…...

第十四届蓝桥杯三月真题刷题训练——第 8 天
目录 第 1 题:分数 题目描述 运行限制 代码: 第 2 题:回文日期 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码: 第 3 题:迷宫 代码: 第 1 题:分数 题目描述 本题为填空题…...

鼎阳SDS2074X Plus免费“升级”(破解)备忘录
鼎阳SDS2074X Plus从基础参数来看,在一众国产示波器里并不出彩。但作为一款可以免费“升级”到【1】4通道2GSa/s的采样率,500MHz分析带宽,200Mpts存储深度的数字示波器(可惜原配的是200MHz的探头,500MHz的探头还是贵&a…...

【C++】C++标准模板库STL (一) string类的使用详解
前言 在前一章种我们介绍了C中的模板的使用,这是一种泛型编程,模板的使用能让我们减少大量的相似代码,减少我们的代码量与工作量,写出更加高效简洁的代码,模板如此好用,但还是要我们先出写一个泛型类或函数…...

如何用SpringBoot+Thymeleaf+Echart生成好看的柱状图,折线图,饼状图
一、前言 上篇文章我们用POI技术读取Excel并生成了相应的图表。但是实际的效果比较一般,因为本身WPS生成图表就比较简单,如果用程序操作远比人工耗时费力,效果远不如一些付费模板。如下图所示: 然后我就想到前端不是有一个简单易…...
LeetCode819. 最常见的单词(python)
题目 给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。 题目保证至少有一个词不在禁用列表中,而且答案唯一。 禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。…...

【深入理解C指针】经典笔试题——指针和数组
🔹内容专栏:【C语言】进阶部分 🔹本文概括:一些指针和数组笔试题的解析 。 🔹本文作者:花香碟自来_ 🔹发布时间:2023.3.12 目录 一、指针和数组练习题 1. 一维数组 2. 字符数组 …...
雷达散射截面
雷达散射截面(Radar Cross Section, RCS)是表征目标散射强弱的物理量。 σ = 4 π R 2 ∣ E s ∣ 2 ∣ E i ∣ 2 \sigma = 4\pi R^2 \frac{|E_s |^2}{|E_i|^2}...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...