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

推荐系统-ALS协同过滤算法实现

从协同过滤的分类来说,ALS(Alternating Least Squares,交替最小二乘)算法属于User-Item CF,也叫做混合CF,它同时考虑了User和Item两个方面,通过数量相对少的未被观察到的隐藏因子,来解释大量用户和物品之间潜在联系。ALS基于矩阵分解通过降维的方法来补全用户-物品矩阵,对矩阵中没有出现的值进行估计。

用户和物品的关系,可以抽象为如下的三元组:<User,Item,Rating>。其中,Rating是用户对商品的评分,表征用户对该商品的喜好程度。

ALS基本假设:任何一个评分矩阵均可近似分解成两个低维的用户特征矩阵和物品特征矩阵。矩阵分解过程可理解成将用户和物品均抽象的映射到相同的低维潜在特征空间中。因此其基本思想是对稀疏矩阵进行模型分解,评估出缺失项的值,以此来得到一个基本的训练模型,然后依照此模型可以针对新的用户和物品数据进行评估。ALS是采用交替的最小二乘法来算出缺失项,交替最小二乘法是在最小二乘法的基础上发展而来的。

1、spark代码实现

1.1 数据入口

case class ProductRating(userId:Int, productId:Int, score:Double)

/** 训练最好模型输出

  • @param bestModel 模型
  • @param bestRanks 隐含因子
  • @param bestIters 迭代次数
  • @param bestLambdas 惩罚值
  • @param bestRmse 最佳方差值**/
    case class BestModel(bestModel:Option[MatrixFactorizationModel], bestRanks:Int, bestIters:Int, bestLambdas:Double, bestRmse:Double)

def main(args: Array[String]): Unit = {val sparkConf = new SparkConf().setMaster(config("spark.cores")).setAppName("ALSTrainer")//创建sparkSessionval spark = SparkSession.builder().config(sparkConf).getOrCreate()//加载数据,作为rating, rdd需要应用aslval ratingRDD = getDFFromCass(spark, "cdp", "t_user_item_rating").as[ProductRating].rdd.map(rating => Rating(rating.userId, rating.productId, rating.score))//数据切分为训练集合测试集val splits = ratingRDD.randomSplit(Array(0.8, 0.2))val trainingRDD = splits(0)val testingRDD = splits(1)//核心实现,输出最优参数val bestModel = RmseUtil.predictBestRmse(trainingRDD, testingRDD)println("bestModel" + bestModel.bestRmse)val itemRecs = recommender(spark, ratingRDD, 10)//output result to cassandrasaveToCass(itemRecs.toDF(), "cdp", "t_user_recs")spark.stop()}

1.2 数据加载

我们使用cassandra大数据库,实现数据的输入与存储;

 def saveToCass(saveDF: DataFrame, keyspace: String, tableName: String): Unit = {saveDF.write.format("org.apache.spark.sql.cassandra").options(Map("keyspace" -> keyspace, "table" -> tableName)).mode(SaveMode.Append).option("spark.cassandra.output.consistency.level", "ONE").save()}def getDFFromCass(spark: SparkSession, keyspace: String, tableName: String): DataFrame = {val userItemDF = spark.read.format("org.apache.spark.sql.cassandra").options(Map("keyspace" -> keyspace, "table" -> tableName)).load().toDF("userId", "itemId", "rating")userItemDF}

1.3 基于spark mllib物品推荐

建立ALS算法模型,设置模型参数(通过模型参数评估获得最优解),调用recommendProductsForUsers方法为用户推荐指定数量的物品。

  def recommender(spark: SparkSession, ratingRDD: RDD[Rating],  recommendNum: Int): DataFrame={val splits = ratingRDD.randomSplit(Array(0.8, 0.2))val trainRDD= splits(0)val testRDD = splits(1)//建立ALS推荐模型val model = new ALS().setRank(5).setIterations(20).setLambda(0.01).setImplicitPrefs(false).setUserBlocks(-1).setProductBlocks(-1)//设置ratingRDD为所有用户推荐.run(trainRDD)val testUsersProductRDD = testRDD.map { case Rating(user, product, rate) => (user, product) }//得到预测评分的数据集val predictionRDD = model.predict(testUsersProductRDD).map {case Rating(user, product, rate) => ((user, product), rate)}//真实评分数据集与预测评分数据集进行合并val ratesAndPreds = testRDD.map { case Rating(user, product, rate) => ((user, product), rate) }.join(predictionRDD)//计算RMSE,这里的r1就是真实结果,r2就是预测结果val MSE = ratesAndPreds.map {case ((user, product), (r1, r2)) =>val err = (r1 - r2)err * err}.mean()println("Mean Squared Error = " + MSE)//用户推荐recommendNum个商品val userSubsetRecs = model.recommendProductsForUsers(recommendNum)//推荐商品列表val itemRecDF = userSubsetRecs.toDF("userId", "recommends")itemRecDF.show(5)itemRecDF}

1.4 模型参数评估

预测模型评估,预测出最好的模型参数BestModel

object RmseUtil {/*** 训练集合* @param trainingData 训练集合* @param testingData 测试集合* @return*/def predictBestRmse(trainingData:RDD[Rating], testingData:RDD[Rating]): BestModel = {var bestModel: Option[MatrixFactorizationModel] = Nonevar bestRanks = -1var bestIters = 0var bestLambdas = -1.0var bestRmse = Double.MaxValue//多重迭代法求最佳参数模型//迭代次数val numIters = List(5, 10, 20)//隐含因子val numRanks = List(8, 10, 12)//惩罚值(正则化值)val numLambdas = List(0.01, 0.1, 1)//共3*3*3种组合,每种组合迭代次数又不一样,在此会消耗大量时间for (rank <- numRanks; iter <- numIters; lambdas <- numLambdas) {//als参数为 训练集合 隐含因子 迭代次数 惩罚因子val model = ALS.train(trainingData, rank, iter, lambdas)val validationRmse = rmseComputer(model, testingData)//逐步迭代if (validationRmse < bestRmse) {bestModel = Some(model)bestRmse = validationRmsebestIters = iterbestLambdas = lambdasbestRanks = rank}}BestModel(bestModel, bestRanks, bestIters, bestLambdas, bestRmse)}
}/**** @param model       训练模型* @param dataOfTest  用于测试数据集合(一般是笛卡尔积)* @return*/def rmseComputer(model: MatrixFactorizationModel, dataOfTest: RDD[Rating]):Double= {//预测评分矩阵:预测返回结果<user product rating>val predictResult = model.predict(dataOfTest.map(item => (item.user, item.product)))//将预测值和测试值组成一个map然后比较预测的评分值和实际值val predict = predictResult.map(item => ((item.user, item.product), item.rating))val actual = dataOfTest.map(item => ((item.user, item.product), item.rating))val predJoinPrevActual = predict.join(actual).values//直接调用回归库函数需要传入一个(prediction,actualValue)val evaluator = new RegressionMetrics(predJoinPrevActual)evaluator.meanAbsoluteError}

相关文章:

推荐系统-ALS协同过滤算法实现

从协同过滤的分类来说&#xff0c;ALS&#xff08;Alternating Least Squares&#xff0c;交替最小二乘&#xff09;算法属于User-Item CF&#xff0c;也叫做混合CF&#xff0c;它同时考虑了User和Item两个方面&#xff0c;通过数量相对少的未被观察到的隐藏因子&#xff0c;来…...

QT第三讲

思维导图 蜡笔小新闹钟 需求&#xff1a; 实现 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTime> //时间类 #include<QTimerEvent> //事件处理类 #include<QtTextToSpeech> //文本转语音类 #include<QMessageBo…...

Linux内核的I2C驱动框架详解------这应该是我目前600多篇博客中耗时最长的一篇博客

目录 1 I2C驱动整体框架图 2 I2C控制器 2.1 I2C控制器设备--I2C控制器在内核中也被看做一个设备 2.2 i2c控制器驱动程序 2.3 platform_driver结构体中的probe函数做了什么 2.3.1 疑问&#xff1a; i2cdev_notifier_call函数哪里来的 2.3.2 疑问&#xff1a;为什么有两…...

【点云处理教程】05-Python 中的点云分割

一、说明 这是我的“点云处理”教程的第 5 篇文章。“点云处理”教程对初学者友好&#xff0c;我们将在其中简单地介绍从数据准备到数据分割和分类的点云处理管道。 在上一教程中&#xff0c;我们看到了如何过滤点云以减少噪声或其密度。在本教程中&#xff0c;我们将应用一些聚…...

代码随想录算法训练营之JAVA|第十七天| 654. 最大二叉树

今天是第17天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 654. 最大二叉树https://leetcode.cn/problems/maximum-binary-tree/description/ 第一想法 错误的想法&#xff0c;就不说了。 看完代码随想录之后的想法 用递归模拟真实的过程 如果我…...

C++重写函数、隐藏函数、重载函数的区别对比

目录 1.函数重载 1.1定义 1.2函数重载的规则&#xff1a; 1.3函数重载的作用&#xff1a; 2.函数重写&#xff1a; 2.1定义 2.2例子&#xff1a; 3.函数隐藏 3.1定义 3.2举个例子&#xff1a; 1.函数重载 1.1定义 我们在学类和对象的封装特性时学过一个词叫重载&#xff0c…...

15.python设计模式【函数工厂模式】

1.知识讲解 内容&#xff1a;定义一个字典&#xff0c;在python中一切皆对象&#xff0c;将所有的函数进行封装&#xff0c;然后定一个分发函数进行分发&#xff0c;将原来if…else全部干掉。角色&#xff1a; 函数&#xff08;function&#xff09;函数工厂&#xff08;funct…...

Redis主从复制、哨兵、cluster集群原理+实验

目录 一、Redis 主从复制 1、主从复制的作用 2、主从复制流程 3、搭建Redis 主从复制 安装Redis&#xff08;所有主机) 修改Master节点Redis配置文件 修改Slave节点Redis配置文件 验证主从效果 一、Redis 主从复制 主从复制&#xff0c;是指将一台Redis服务器的数据&am…...

微信小程序如何实现页面传参?

前言 只要你的小程序超过一个页面那么可能会需要涉及到页面参数的传递&#xff0c;下面我总结了 4 种页面方法。 路径传递 通过在url后面拼接参数&#xff0c;参数与路径之间使用 ? 分隔&#xff0c;参数键与参数值用 相连&#xff0c;不同参数用 & 分隔&#xff1b;如…...

OPC DA 客户端与服务器的那点事

C#开发OPC客户端&#xff0c;使用OPCDAAuto.dll。在开发过程中偶遇小坎坷&#xff0c;主要记录一下问题解决办法。 1、建立客户端&#xff0c;参考链接。建立WinFrom工程&#xff0c;将博客中代码全部复制即可运行&#xff1a; https://www.cnblogs.com/kjgagaga/p/17011730.…...

Java 错误异常介绍(Exceptions)

1、异常介绍 异常是程序执行期间发生的意外事件。它影响程序指令流&#xff0c;从而导致程序异常终止。 发生异常的原因有很多。其中包括&#xff1a; 无效的用户输入 设备故障 网络连接丢失 物理限制&#xff08;磁盘内存不足&#xff09; 代码错误 打开一个不可用的文…...

每日一题——旋转数组的最小数字

题目 有一个长度为 n 的非降序数组&#xff0c;比如[1,2,3,4,5]&#xff0c;将它进行旋转&#xff0c;即把一个数组最开始的若干个元素搬到数组的末尾&#xff0c;变成一个旋转数组&#xff0c;比如变成了[3,4,5,1,2]&#xff0c;或者[4,5,1,2,3]这样的。请问&#xff0c;给定这…...

SpringBoot Jackson 日期格式化统一配置

目录 1.在全局配置文件配置 2.通过JavaBean方式配置 1.在全局配置文件配置 spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8 该配置方式仅支持 Date 类型的日期格式化&#xff0c;不支持LocalDate 及 LocalDateTime 的格式化。 2.通过JavaBean方式配置 …...

剑指 Offer 38. 字符串的排列 / LeetCode 47. 全排列 II(回溯法)

题目&#xff1a; 链接&#xff1a;剑指 Offer 38. 字符串的排列 难度&#xff1a;中等 输入一个字符串&#xff0c;打印出该字符串中字符的所有排列。 你可以以任意顺序返回这个字符串数组&#xff0c;但里面不能有重复元素。 示例: 输入&#xff1a;s “abc” 输出&…...

【前端知识】React 基础巩固(四十三)——Effect Hook

React 基础巩固(四十三)——Effect Hook 一、Effect Hook的基本使用 Effect Hook 用来完成一些类似class中生命周期的功能。 在使用类组件时&#xff0c;不管是渲染、网路请求还是操作DOM&#xff0c;其逻辑和代码是杂糅在一起的。例如我们希望把计数器结果显示在标签上&…...

一百三十八、ClickHouse——使用clickhouse-backup备份ClickHouse库表

一、目标 使用clickhouse-backup在本地全库备份ClickHouse的数据库 二、前提 已经安装好clickhouse-backup 注意&#xff1a;由于之前同事已经按照好clickhouse-backup&#xff0c;所以我就没有安装 如有需要请参考其他人的博客安装一下&#xff0c;下面是我认为比较好的一…...

【无标题】使用Debate Dynamics在知识图谱上进行推理(2020)7.31

使用Debate Dynamics在知识图谱上进行推理 摘要介绍背景与相关工作我们的方法 摘要 我们提出了一种新的基于 Debate Dynamics 的知识图谱自动推理方法。 其主要思想是将三重分类任务定义为两个强化学习主体之间的辩论游戏&#xff0c;这两个主体提取论点&#xff08;知识图中…...

windows下若依vue项目部署

下载若依项目&#xff0c;前端后端项目本地启动前端打包&#xff0c;后端打包配置nginx.conf 需要注意的是&#xff1a;路径别用中文&#xff0c;要不然报错 #前台访问地址及端口80&#xff0c;在vue.config.js中可查看server {listen 80;server_name localhost; #后台…...

【目标检测】基于yolov5的水下垃圾检测(附代码和数据集,7684张图片)

写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 路虽远,行则将至;事虽难,做则必成。只要有愚公移山的志气、滴水穿石的毅力,脚踏实地,埋头苦干,积跬步以至千里,就…...

P1734 最大约数和

题目描述 选取和不超过 S 的若干个不同的正整数&#xff0c;使得所有数的约数&#xff08;不含它本身&#xff09;之和最大。 输入格式 输入一个正整数 S。 输出格式 输出最大的约数之和。 输入输出样例 输入 11 输出 9 说明/提示 【样例说明】 取数字 4 和 6&a…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...