推荐系统-基于标签的Top-N个性化推荐实现

随着移动互联网的快速发展,UGC标签系统受到越来越多推荐应用,标签不但能反映用户的兴趣又能描述物品的本身特征。现有的标签推荐算法没有考虑用户的连续行为所产生的影响,于是人们提出了一种基于标签的个性化推荐算法。该算法将〈用户-标签-物品〉的三维关系拆分为〈用户-标签〉和〈标签-物品〉两个二维关系。 通过推荐标签集来匹配与其相对应的物品,为了提高推荐的精准率,该算法利用标签之间的影响,并基于匹配物品中所含标签间存在的关联关系对物品进行满意度建模,该模型是一种概率模型。在计算用户-标签和用户-物品之间的兴趣度和满意度时使用了协同过滤的思想来补全稀疏值。在公开的数据集中,与现有算法相比,该算法在精准率、召回率上均有明显提高。
因此,本文将主要探讨如何利用用户打标签的行为为其推荐物品。一个用户标签行为的数据集可以由一个三元组集合表示,其中每条样本(u,i,b)表示用户u为物品i打上了标签b。

1、标签作为特征/类别划分

我们可以将标签看做是LFM中的隐类(这里是显式的),用户u对物品i的兴趣度可表示为:
p ( u , i ) = ∑ b n u b n b i p(u,i)=\sum_{b}n_{ub}n_{bi} p(u,i)=bnubnbi
n u b n_{ub} nub:用户u打过标签b的次数,可以看做是用户u对b类物品的喜好程度;
n b i n_{bi} nbi:物品i被打过b标签的次数,可以看做物品i属于b类的”概率“值
仔细研究以上公式我们可以发现如下缺点:

  • 热门标签给 n u b n_{ub} nub的权重很大;
  • 热门物品给 n b i n_{bi} nbi的权重也很大;

借鉴TF-IDF的思路,可以通过惩罚用户或物品中热门标签的方式来优化以上公式:
p ( u , i ) = ∑ b n u b l o g ( 1 + n b u ) n b i l o g ( 1 + n i u ) p(u,i)=\sum_{b}\frac{n_{ub}}{log(1+n_b^u)}\frac{n_{bi}}{log(1+n_i^u)} p(u,i)=blog(1+nbu)nublog(1+niu)nbi

  • 1 + n b u 1+n_b^u 1+nbu:标签b被多少个用户使用过;
  • n i u n_i^u niu:物品i被多少个用户打过标签;
    标签的稀疏性:对于新用户或新物品,集合B(u)⋂B(i)中的标签数量很少。

1.1 标签扩展

为提高推荐准确率,需要对标签集合进行进一步扩展,如果用户使用过某个标签,我们可以将与这个标签相似的其他标签也加入到用户标签集合中去。扩展标签的方式有很多,常用的有话题模型,这里介绍一种基于邻域的方法,核心是计算标签之间的相似度。可以用两个标签下物品的重合度来计算它们之间的相似度
Alt

2、 适用场景:

  • 商城类:用户偏好商品UGC标签推荐;
  • 社交类:用户喜欢UGC标签推荐;

3、冷启动问题解决方案:

  • 客户注册时,勾选喜欢的标签,如是商城勾选喜欢的商品标签,如是社交内网站勾选喜欢社交类别;
  • 热门商品填充;

4、基于商品标签推荐代码

/**商品数据*/
case class Product(productId:Int, name:String, imageUrl:String, categories:String, tags:String)
//mongodb 配置
case class MongoConfig(uri:String, db:String)
//定义标准推荐对象
case class Recommendation(productId:Int, score:Double)
//定义商品相似度列表
case class ProductRecs(productId:Int, recs:Seq[Recommendation])object ContentRecommender {//定义数据存储mongodb存储的表名val MONGODB_PRODUCT_COLLECTION = "product"//定义一个基于内容推荐商品列表val CONTENT_PRODUCT_RECS = "ContentBasedProductRecs"//总特征数量:本身词汇比较多,不设置会按照很大特征值(消耗内存高), 特征数量其实Hash桶数量,设置少会导致hash碰撞var NUM_FEATURES = 800//推荐商品数,通过商品最小相似度值控制val PRODUCT_SIMILAR_RATE = 0.4def main(args: Array[String]): Unit = {val config = Map("spark.cores" -> "local[*]","mongo.uri" -> "mongodb://localhost:27017/spark-recommender","mongo.db" -> "spark-recommender")val sparkConf = new SparkConf().setMaster(config("spark.cores")).setAppName("ContentRecommender")val spark = SparkSession.builder().config(sparkConf).getOrCreate()import spark.implicits._implicit val mongoConfig = MongoConfig(config("mongo.uri"), config("mongo.db"))//1、加载商品数据val productTagsDF = spark.read.option("uri", mongoConfig.uri).option("collection", MONGODB_PRODUCT_COLLECTION).format("com.mongodb.spark.sql").load().as[Product].map {item =>//通过对tags的|替换为 ' '空格,后面分词器默认按照空格分割val tags = item.tags.replace('|', ' ')(item.productId, item.name, tags)}.toDF("productId", "name", "tags").cache()//2、计算文档总分词数val dsTags:Dataset[Array[String]] = productTagsDF.select("tags").map(x => x.toString.split(" "))//使用flatMap合并Array[String]所有项val all_terms: Array[String] = dsTags.flatMap(iterArr => iterArr).distinct().collect()//所有词典(总词)特征数量NUM_FEATURES = all_terms.length//3: 用TF-IDF提取商品特征向量val tokenizer = new Tokenizer().setInputCol("tags").setOutputCol("words")val wordsDataDF = tokenizer.transform(productTagsDF)//4、计算TF:定义一个HashingTF工具,计算频次val hashingTF = new HashingTF().setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(NUM_FEATURES)val featurizedDataDF = hashingTF.transform(wordsDataDF)//5、定义一个IDF工具,计算TF-IDFval idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")//计算逆文件频率: 训练一个idf的模型val idfModel = idf.fit(featurizedDataDF)//将词频(TF)转换为TF-IDF向量: 得到增加新列feature的DF,(最终特征向量)val rescaledTfIDF = idfModel.transform(featurizedDataDF)//6、对数据进行转换,得到RDD的featuresval productFeatures = rescaledTfIDF.map {row => (row.getAs[Int]("productId"), row.getAs[SparseVector]("features").toArray)}.rdd.map {case (productId, features) => (productId, new DoubleMatrix(features))}//两两配对做笛卡尔积,计算余弦相似度val productRecsDF = productFeatures.cartesian(productFeatures).filter {case (a, b) => a._1 != b._1 }.map {case (a, b) =>val simScore = cosineSim(a._2, b._2) (a._1, (b._1, simScore))}.filter(_._2._2 > PRODUCT_SIMILAR_RATE) .groupByKey().map {case (productId, recs) =>val list = recs.toListProductRecs(productId, list.map(x => Recommendation(x._1, x._2)))}.toDF()storeDFInMongoDB(productRecsDF, CONTENT_PRODUCT_RECS)spark.stop()}/*** 存储信息到mongodb数据库** @param df* @param collectionName* @param mongoConfig*/def storeDFInMongoDB(df: DataFrame, collectionName: String)(implicit mongoConfig: MongoConfig): Unit = {df.write.option("uri", mongoConfig.uri).option("collection", collectionName).mode(SaveMode.Overwrite).format("com.mongodb.spark.sql").save()}/*** 计算两个向量集合的余弦相似度** @param product1 商品1的矩阵* @param product2 商品2的矩阵*/def cosineSim(product1: DoubleMatrix, product2: DoubleMatrix): Double = {product1.dot(product2) / (product1.norm2() * product2.norm2())}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌云构建漏洞容易引发潜在的供应链攻击

云安全公司Orca Security在谷歌云构建(Google Cloud Build)服务中发现了一个关键的设计漏洞,该漏洞会让攻击者的权限升级,使他们可以在未经授权的情况下访问谷歌构件注册表(Google Artifact Registry)代码库…

VoIP监控工具有什么作用

VoIP 监控工具利用思科的 IPSLA 技术生成合成流量并监控客户端体验的呼叫质量。与被动监控VoIP指标相反,IPSLA技术允许IT管理员主动并在潜在问题发生之前检测到它们,这使组织能够轻松遵守严格的SLA指标。 思科 IPSLA 技术在两台设备之间创建流量&#x…

这样创建客户帮助中心,效果超好!

创建一个有效的客户帮助中心是为了为客户提供优质的支持和服务。在这个数字化时代,客户期望能够快速找到所需的信息,并得到准确和及时的解答。本文将分享创建有效客户帮助中心的最佳实践,帮助您提供出色的客户体验并提升客户满意度。 1. 了解…

Python 字典 get()函数使用详解,字典获取值

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 get函数使用详解 1、设置默认返回值2、嵌套字典取值3、get() 和 dict[key] 的区别…

linux centos7 静默安装 oracle 11g,【亲测有效】,包含远程连接、提供安装包

Centos7 安装oracle11g 环境准备 操作系统 centos7 oracle版本 oracle11g 终端软件 MobaXterm 192.168.46.61 oracleMaster 安装包 网盘地址 一、安装前准备 1、关闭selinux [rootoracleMaster ~]# vim /etc/selinux/config修改 SELINUX 为 disabled # This file controls …

java导出pdf(纯代码实现)

java导出pdf 在项目开发中,产品的需求越来越奇葩啦,开始文件下载都是下载为excel的,做着做着需求竟然变了,要求能导出pdf。导出pdf倒也不是特别大的问题关键就是麻烦。 导出pdf我知道的一共有3中方法: 方法一&#xff…

STM32定时器中断的使用示例

STM32定时器中断的使用示例 前言硬件和软件cubemx使能定时器中断中断服务函数案例输出结果 前言 上一篇博客实现了定时器输出pwm,这篇接着上次的工程,在上次的工程上做简单的配置即可 硬件和软件 硬件使用的是stm32h750vbt6;软件用到了stm…

nginx+lua+redis环境搭建(文末赋上脚本)

目录 需求背景 环境搭建后nginx和redis版本 系统环境 搭建步骤 配置服务器DNS 安装ntpdate同步一下系统时间 安装网络工具、编译工具及依赖库 创建软件包下载目录、nginx和redis安装目录 下载配置安装lua解释器LuaJIT 下载nginx NDK(ngx_devel_kit&#xff09…

ceph安装部署

Ceph 简介 存储基础 单机存储设备 单机存储的问题 分布式存储的类型 分布式存储(软件定义的存储 SDS) Ceph 架构 Ceph 核心组件 ​编辑 Pool中数据保存方式支持两种类型 OSD 存储后端 Ceph 数据的存储过程 Ceph 集群部署 基于 ceph-deploy …

网络运维能转型到系统运维吗?

很多网工处于刚起步的初级阶段,各大公司有此专职,但重视或重要程度不高,可替代性强;小公司更多是由其它岗位来兼顾做这一块工作,没有专职,也不可能做得深入。 现在开始学习入门会有一些困难,不…

Hyperledger Fabric测试网络运行官方Java链码[简约版]

文章目录 启动测试网络使用peer CLI测试链码调用链码 启动测试网络 cd fabric-samples/test-networknetwork.sh的脚本语法是&#xff1a;network.sh <mode> [flag] ./network.sh up./network.sh createChannel在java源码路径下 chmod 744 gradlew vim gradlew :set ffu…

银河麒麟高级服务器操作系统V10安装mysql数据库

一、安装前 1.检查是否已经安装mysql rpm -qa | grep mysql2.将查询出的包卸载掉 rpm -e --nodeps 文件名3.将/usr/lib64/libLLVM-7.so删除 rm -rf /usr/lib64/libLLVM-7.so4.检查删除结果 rpm -qa | grep mysql5.搜索残余文件 whereis mysql6.删除残余文件 rm -rf /usr/b…

MYSQL表操作(DML,DDL)

建表并插入数据&#xff1a; mysql> create table worker(-> dept_id int(11) not null,-> emp_id int (11) not null,-> work_time date not null,-> salary float(8,2) not null,-> poli_face varchar(10) not null default 群众,-> name varchar(20) …

一种对不同类型齐格勒-尼科尔斯 P-I-D 控制器调谐算法研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

MySQL数据库 【增删改查】

目录 一、新增 指定列插入 一次插入多个数据 二、查询 1、全列查询 2、指定列查询 3、查询字段为表达式 4、查询的时候给列名/表达式 指定别名 5、查询时去重 6、排序查询 7、条件查询 8、模糊查询 9、空值查询 10、分页查询 三、修改 四、删除 SQL 最核心…

JS-26 认识防抖和节流函数;自定义防抖、节流函数;自定义深拷贝、事件总线函数

目录 1_防抖和节流1.1_认识防抖和节流函数1.2_认识防抖debounce函数1.3_防抖函数的案例1.4_认识节流throttle函数 2_Underscore实现防抖和节流2.1_Underscore实现防抖和节流2.2_自定义防抖函数2.3_自定义节流函数 3_自定义深拷贝函数4_自定义事件总线 1_防抖和节流 1.1_认识防…

【Netty】NIO基础(三大组件、文件编程)

文章目录 三大组件Channel & BufferSelector ByteBufferByteBuffer 正确使用姿势ByteBuffer 内部结构ByteBuffer 常见方法分配空间向 buffer 写入数据从 buffer 读取数据mark 和 reset 字符串与 ByteBuffer 互转Scattering ReadsGathering Writes粘包、半包分析 文件编程Fi…

vue 当新增样式无法生效的情况下如何处理

使用scoped属性时&#xff0c;会遇到样式问题。需要使用样式穿透解决 <style lang"scss" scoped> </style> 可以使用以下方法 &#xff1a;deep css 使用 >>> less 使用 /deep/ scss 使用 ::v-deep 代码写法如下: .a :deep(.b) { } .…

Mac的docker安装redis

Mac的docker安装redis 1、docker search redis NAME DESCRIPTION STARS OFFICIAL AUTOMATED redis Redis is an open source key-value store that… 12205 …

mysql、redis 、RabbitMQ只能本机访问,怎么改?

如果只能本机访问&#xff0c;怎么改? 一、mysql - 改my.ini 刷脚本 bind-address0.0.0.0 然后重启一下mysql服务 任务管理器-关掉mysql 搜索 计算机管理-重启mysql服务 然后 打开查询&#xff0c;并选择mysql数据&#xff0c;输入这个sql语句&#xff0c;点击运行 sele…