当前位置: 首页 > 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…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...