springboot集成mahout实现简单基于协同过滤算法的文章推荐算法

news/2024/5/19 23:57:22 标签: 算法, spring boot, 推荐算法

文章目录

  • 前言
  • 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语句简单分析数据

        SELECT
            user_id,
            article_id,
            SUM(
                    CASE operation_type
                        WHEN 0 THEN 3
                        WHEN 1 THEN 3
                        WHEN 2 THEN 5
                        else 0 END
                ) AS "value"
        FROM
            user_article_operation
        GROUP BY user_id,article_id
				ORDER BY user_id

执行语句如下
在这里插入图片描述

可以看出
1号用户最喜欢6,9号文章,
2号用户最喜欢4,5,6号文章
3号用户最喜欢4,5,6号文章
发现1,2,3号用户都喜欢6号文章,3个用户具有一定相似性。
(别问为啥这么规律,问就是我为了好测试修改了下数据,如果你感觉哪里不对劲的话,那你说的都对(反正我搞这个算法只是用来糊弄老师的😂😂😂))
因此如果要给1号用户推荐文章的话,应该先推荐5号,再推荐4号文章。

2. 代码与测试

只需要根据表生成相应实体类(注意要加一个value属性来存储分数)

在这里插入图片描述

主要代码如下,其实就两个方法

![在这里插入图片描述](https://img-blog.csdnimg.cn/e70aea3c224f4c13b17de84f476016e6.png

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">
        SELECT
            user_id,
            article_id,
            SUM(
                    CASE operation_type
                        WHEN 0 THEN 2
                        WHEN 1 THEN 3
                        WHEN 2 THEN 5
                        else 0 END
                ) AS "value"
        FROM
            user_article_operation
        GROUP BY user_id,article_id
    </select>

4.相关参考

1.spring boot项目基于mahout推荐算法实现商品推荐
2.相关内容在章节5-9


http://www.niftyadmin.cn/n/142950.html

相关文章

visual-chatgpt国内劝退指南

首先别的不看&#xff0c;我们就看这个图 看起来非常简单对不对 但经过我长达6个小时的摸索最终失败的经验告诉大家 没有一流的GPU和正确的姿势直接不用尝试 前期准备 1.一台带有桌面Linux系统的主机&#xff0c;如ubuntu 18.04 desktop 2.装了显卡且能够跑CUDA&#xff0c;最…

AWS组织和整合账单

AWS组织&#xff08;Organization&#xff09;是一项账户管理服务&#xff0c;它可以将你的多个AWS账号整合到集中管理的组织中。 AWS组织包含了整合账单&#xff08;Consolidated Billing&#xff09;和账号管理功能&#xff0c;通过这些功能&#xff0c;你能够更好地满足企业…

js判断当前是哪个浏览器

var userAgent navigator.userAgent; //取得浏览器的userAgent字符串var isOpera userAgent.indexOf("Opera") > -1;var choreBox document.getElementById(choreBox)var ieBox document.getElementById(ieBox)//判断是否Opera浏览器if (isOpera) {alert(&quo…

stm32外设-RCC

0. 写在最前 本栏目笔记都是基于stm32F10x 1. RCC简介 RCC是Reset and Clock Control (复位和时钟控制)的缩写&#xff0c;它是STM32内部的一个重要外设&#xff0c;负责管理各种时钟源和时钟分频&#xff0c;以及为各个外设提供时钟使能。RCC模块可以通过寄存器操作或者库函数…

Java知识复习(十七)SpringCloud

1、什么是微服务架构 微服务架构就是将单体的应用程序分成多个应用程序&#xff0c;这多个应用程序就成为微服务&#xff0c;每个微服务运行在自己的进程中&#xff0c;并使用轻量级的机制通信这些服务围绕业务能力来划分&#xff0c;并通过自动化部署机制来独立部署。这些服务…

Linux入门教程——VI/VIM 编辑器

前言 本文小新为大家带来 Linux入门教程——VI/VIM 编辑器 相关知识&#xff0c;具体内容包括VI/VIM是什么&#xff0c;VIM的三种工作模式介绍&#xff0c;包括&#xff1a;一般模式&#xff0c;编辑模式&#xff0c;指令模式&#xff0c;以及模式间转换等进行详尽介绍~ 不积跬…

【第十四届蓝桥杯单片机组客观题1】

第十四届蓝桥杯单片机组客观题1 以下客观题来自4T测评的模拟题&#xff0c;希望可以帮助到大家&#xff0c;加油丫 1、C 若希望将IAP15F2K61S2单片机的IO口输出电流能力较强&#xff0c;应将IO配置为&#xff08; &#xff09;模式。 A : 准双向IO B : 输入/高阻 C : 推挽输出 …

二分法的原理及其应用举例

首先&#xff0c;什么是二分法&#xff1a; 最简单的例子就是类似于二分查找的用法来实现快速查找有序区间内的给定的目标值是否存在&#xff0c;当然&#xff0c;这也可以应用在别的问题中&#xff0c;二分查找是一个时间效率极高的算法&#xff0c;尤其是面对大量的数据时&am…