首页 > 编程语言 >【JAVA】助力数字化营销:基于协同过滤算法实现个性化商品推荐

【JAVA】助力数字化营销:基于协同过滤算法实现个性化商品推荐

时间:2024-04-23 16:48:04浏览次数:38  
标签:数字化 JAVA 推荐 用户 算法 过滤 相似 物品 个性化


​周松杰:碧桂园服务后台开发gao级工程师,拥有8年开发经验。

1 前言
本文主要介绍基于协同过滤的推荐算法。在了解实践应用之前,我们先对推荐系统、Mahout学习框架以及算法进行简单介绍,然后再结合实践进行深入探讨。

第一部分概述了推荐系统的产生背景、作用和工作原理,并介绍了Mahout学习框架的算法。

第二部分则基于Mahout框架-协调过滤算法,实现个性化商品推荐。

**2 推荐系统、智能推荐算法 **
2.1 推荐系统--基本流程讲解
2.1.1 推荐系统的意义
用户角度:推荐系统解决在“信息过载”的情况下,用户如何高效地获得感兴趣的物品的问题。例如在淘/宝、京/东、亚/马/逊等。
公司角度:推荐系统解决了产品如何最大限度地吸引用户、留存用户、增加用户黏性,从而达到公司的营收目的。

2.1.2 简洁系统的推荐

如果每次都随机给用户推荐物品,则无法将平台/独特的优质物品展现出来。例如在凤凰会商城中,我们可以根据用户的收藏数、评论数、销量等数据对内容进行排序,按倒序依次推荐给用户。此外,还可以设置一个运营池和热点池,由运营人员在后台进行手动更新,确保实时热点展示。

根据以上想法,我们画一下推荐系统架构:

2.1.3 个性化(千人千面)推荐系统
基于以上的推荐系统,除了随机策略外,不同用户看到的商品是一致的,但每个用户感兴趣的物品不同。因此,推荐系统需要根据不同用户进行个性化推荐。为了解决这个问题,可以采用不同的推荐算法。常用的推荐算法分为以下三种:

从图中可以看出,协同过滤分为ItemCF(基于物品的协同过滤)和UserCF(基于用户的协同过滤),也是本文要讲的内容。基于Mahout一个分布式机器学习算法框架来实现协同过滤推荐。

2.2 Mahout-Collaborative Filtering(CF)
2.2.1 Mahout简介
Mahout是一个分布式机器学习算法的集合和数据挖掘工具,它集成了包括聚类、分类、推荐过滤和频繁子项挖掘等算法。本文提到Mahout,是因为它提供了丰富的算法实现,有兴趣的同学可以进行深入研究。

从上图可以看出,Mahout的定位是基于原数据生成推荐商品数据。

2.2.2 什么是协同过滤
协同过滤的基本概念是将推荐方式变成自动化流程。它主要基于属性或兴趣相近的用户经验和建议,提供个性化推荐。通过协同过滤,可以收集具有类似偏好或属性的用户,并将其意见提供给同一集群中的其他用户作为参考,以满足人们在做决策时参考他人意见的心态。

2.2.3 ItemCF(基于商品的协同过滤)
算法思想:基于用户对物品的偏好找到相似物品,然后根据用户历史偏好,推荐相似物品。

计算方法:将所有用户对某个物品的偏好作为一个向量,利用这些向量计算物品之间的相似度。得到相似物品后,根据用户历史偏好预测当前用户还未涉及的物品偏好,最终计算出一个排序的物品列表作为推荐。

判断两个物品是否相似以及相似度为多少是协同过滤算法的难点。对于物品来说,相似度计算往往与业务本身有关。在这里,我们使用最通用的计算规则:如果喜欢两个物品的用户重合度越高,则证明物品越相似。


为了便于观看,我们把上图转成矩阵形式,用户作为矩阵行坐标,物品作为列坐标。

假设两物品A和B,判断相似度则通过用户的重合度比例进行计算,如上图协同过滤矩阵所示,要判断「苹果」与「橙子」的相似程度。

利用向量中余弦相似度进行计算,公式为:

向量点积:

向量的长度:

向量的夹角:

将喜欢权重设置为1,不喜欢权重设置为-1,则「苹果」向量为 (1, 1, 1, 1),「橙子」向量为 (1, 1, -1, 1)。

两者向量点积:1 * 1 + 1 * 1 + 1 * -1 + 1 * 1 = 2

「苹果」向量长度:2

「橙子」向量长度:2

利用余弦相似度计算得出:

通过此方法以此类推可以将所有物品的相似度计算出来。

然而根据业务需求,「用户」对「商品」行为有喜欢、评论、收藏及购买等多种类型。每种用户行为都有不同的权重,例如喜欢是1,评论是2,收藏是4,购买是9(当前凤/凰会商/城就是使用该种业务规则计算),将上图换成对应的行为类型则为:

然后根据前面提到的公式进行套娃,则可以得出商品的相似度。在相似度计算上,任何合理的“向量相似度计算”都可以作为协同过滤的判断依据,根据自身业务进行算法迭代。

2.2.4 UserCF(基于用户的协同过滤)
基本思想:基于用户对物品的偏好找到邻居用户(相似用户),然后将邻居用户喜欢的东西推荐给当前用户。

计算方法:将一个用户对所有物品的偏好作为一个向量,计算用户之间的相似度。找到邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户未涉及的物品,计算得到一个排序的物品列表作为推荐。相似度即为两个向量之间的距离,距离越小相似度越大。

判断两个用户是否相似以及相似度为多少也是协同过滤算法的难点。最常用的两种判断方式如下:

用户购买商品有很大重合度。

用户浏览商品有很大重合度。

在ItemCF我们已经说过,任何合理的判断方法都可以作为相似度计算规则,下面我们以 “用户喜欢的物品有很大重合度” 来作为相似度计算规则。


与ItemCF类似,我们也将有向图转变成矩阵,继续沿用ItemCF矩阵。

ItemCF是以商品的维度进行得出向量,最后通过余弦相似得出商品相似度。UserCF则以用户的维度进行得出向量,最后通过余弦相似得出商品相似度。

2.2.5 CF推荐工程化
1、离线计算

建立「用户」到「商品」的索引,记录每个用户行为跟「商品」的列表,我们俗称为LastN。给定一个「用户ID」,能够快速查询到该用户最近互动过的N个「商品」列表。

建立「商品」到「商品」的索引,利用相似度计算规则,离线计算出每个「商品」最相似的「商品」列表。给定一个「商品ID」,能够快速查询到最相似的TopK「商品」。

2、在线召回

根据当前「用户ID」,通过「用户」到「商品」索引查询用户行为-「商品」列表,再通过「商品」到「商品」索引,拿到最相似TopK「商品」集合。

以ItemCF为例:

3、其他召回方式

例如,根据地址位置进行推荐或者结合系统标签用户的形式进行推荐等等。

很多人估计想吐槽,说了这么多,又是算法计算,又要考虑各种维度才能得出相应的相似度来进行推荐,太麻烦了。别急,Mahout即将登场。

4、ItemCF、UserCF如何选择

(1)基于用户的协同过滤

基于用户的协同过滤适用于物品数量多、时效性强的场景,但在其他情况下计算速度较慢。推荐结果个性化程度较弱,但具有广泛的适用性和较高的惊喜度。

(2)基于物品的协同过滤

应用最广泛,尤其以电商行业为典型。

适于用户多、物品少的场景,否则计算速度慢。

在物品冷启动、数据稀疏时效果不佳。

推荐精度高,更具个性化。

倾向于推荐同类商品,推荐的多样性不足,形成信息闭环。

对于稀疏数据集(例如delicious书签、小众群体收藏等),基于物品的过滤方法通常要优于基于用户的过滤方法。而对于密集数据集而言,两种方法的效果几乎是一样的。

——摘自《集体智慧编程》

2.2.6 Mahout推荐算法以及引擎
注意:以下只列本文涉及到的算法,更多算法有兴趣的可自行Google。

点击查看代码

//DataModel支持数据库以及文件作为数据源
org.apache.mahout.cf.taste.impl.model.file.FileDataModel  基于文件的数据接口内,内部使用GenericDataModel 保存实际的用户评价数据,增加了压缩文件(.zip .gz)等文件类型的支持,支持动态更新(更新文件文件名必须保存为一定的格式 例如 foo.txt.gz 后续更新文件必须为foo.1.txt.gz)查了以下代码 好像是自定义时间间隔后可以更新,但是好像是全部更新(以后看代码)
org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel  基于数据库的数据接口 
//UserSimilarity 和 ItemSimilarity 相似度算法实现
CityBlockSimilarity :基于曼哈顿距离相似度
LogLikelihoodSimilarity :基于对数似然比的相似度
                          原理:重叠的个数,不重叠的个数,都没有的个数
                          范围:具体可去百度文库中查找论文《Accurate Methods for the Statistics of Surprise and Coincidence》
                          说明:处理无打分的偏好数据,比Tanimoto系数的计算方法更为智能。
//UserNeighborhood 主要实现
NearestNUserNeighborhood:对每个用户取固定数量N个最近邻居
ThresholdUserNeighborhood:对每个用户基于一定的限制,取落在相似度限制以内的所有用户为邻居

3 商品推荐的实现
3.1 凤凰会商城引入智能推荐的背景前言
3.1.1 需求背景
为更好地了解用户需求,提高转化率、用户停留时间、浏览量和时长等指标,实现精准投放。

原业务流程:

通过运营后台推荐,每天/月/年的商品曝光量最多十几个(推荐策略不变的情况下),所有用户看到的商品都是一样。

新业务流程:

结合后台运营推荐策略、算法策略、销量策略进行推荐。

3.2 Mahout结合实际落地应用流程
3.2.1 数据生命周期

数据完整得生命周期如上图所示,分为以下几个步骤:

数据源:用户的行为日志以及其他行为(如购买行为等,根据业务需要而定)。

数据采集:从客户端采集用户的行为日志。

数据存储:日志文件或DB方式存储。

数据计算:基于用户的行为数据进行生成推荐数据。

数据应用。

注:第4点中的推荐数据生成是基于CachingItemSimilarity商品相似,EuclideanDistanceSimilarity基于欧几里德距离计算相似度的算法进行ItemCF协同过滤。

系统用户行为采集

推荐模型训练流程

3.2.2 实践案例
Mahout推荐引擎提高效率的使用建议:

点击查看代码
ReloadFromJDBCDataModel (这个很重要,占整体耗时一半左右) 包装DataModel的数据集

CachingUserSimilarity或者CachingItemSimilarity包装用户相似度或者物品相似度  
//以cache方式保存相似度计算结果防止每次请求是重复计算
//内部使用 Cache<LongPair,Double> similarityCache保存相似度
//如基于用户推荐,则使用该类包装相似结果集合
CachingUserNeighborh

效果展示:

假设商品推荐位最大为12个,根据以下逻辑优先级进行补位:推荐置顶 > 算法推荐 > 销量。

后台推荐置顶配置:

图示:某个用户所处同一个项目下推荐的商品:

结果期望:基于浏览记录,推荐同类商品。

关闭算法推荐后效果对比:

业务效果:



可以看出,自上线后,随着开放的试点项目越多,通过推荐商品栏目转化订单量,从每月十来单增长到目前的峰值几百单,增长了近二十倍(数据统计截至2023.12.11 0点)。

成交用户数方面,在去重的情况下,6月份前成交人数是几千人,而在后半年(截至12月份),成交人数已经达到了几万人。

4 总结

  1. Mahout是基于Hadoop的机器学习和数据挖掘的一个分布式框架,是一个强大的算法库,具有极高的可扩展性以及易用性。此外,Mahout还提供了一些预处理和特征提取的方法,帮助用户快速构建机器学习模型,它还支持多种编程语言,如Java、Python等,方便不同背景的用户使用。

  2. 本文没有讨论混合方法。在许多情况下,结合协同过滤和基于内容的方法可以达到最优的结果,因此在许多大型推荐系统中使用。混合方法的组合主要有两种形式:一是可以独立训练两个模型(一个协同过滤模型和一个基于内容的模型),二是直接构建一个统一这两种方法的单一模型(通常是神经网络)。

  3. 可尝试使用向量数据库将商品数据向量化后,获得商品之间的相似性,结合用户画像行为进行推荐。

  4. 可以结合用户标签画像提高精准颗粒度。

  5. 针对提高推荐数据实时性,可采取缩短数据清洗周期(离线)、分布式(提高并发处理能力)或Canal监控,Flink及队列等方式来消费用户行为,从而提高用户体验。

  6. 推荐方法的核心是基于历史数据,所以还需要考虑新物品和新用户存在的“冷启动”问题。

标签:数字化,JAVA,推荐,用户,算法,过滤,相似,物品,个性化
From: https://www.cnblogs.com/bkyfw/p/18153181

相关文章

  • Java面试题:请谈谈Java中的volatile关键字?
    在Java中,volatile关键字是一种特殊的修饰符,用于确保多线程环境下的变量可见性和顺序性。当一个变量被声明为volatile时,它可以确保以下两点:内存可见性:当一个线程修改了一个volatile变量的值,其他线程会立即看到这个改变。这是因为volatile关键字会禁止CPU缓存和编译器优化,从而确......
  • JTCR-java.util 更多实用类-18
    BitSetBitSet类是用于存放二进制位值的布尔数组,数组大小按需增加。构造器为BitSet();//指定初始化数组大小BitSet(intsize);publicclassBitSetDemo{//bit1的值//{0,2,4,6,8,10,12,14}//bit2的值//{1,2,3,4,6,7,8,9,11,12,......
  • JTCR-java.util 集合框架-17
    JDK9开始,java.util包作为java.base模块的一部分。概述集合框架的设计目标高性能。不同类型的集合使用方式相似,有很好的互操作性。容易扩展或适配集合。Iterator接口提供了访问集合中元素通用、标准化的方式。任意集合类都可以使用Iterator提供的方法访问元素。JDK......
  • Java 之 final 详解
    一.前言二.final的基础使用2.1.修饰类2.2.修饰方法2.2.1.private方法是隐式的final2.2.2.final方法可以被重载2.3.修饰参数2.4.修饰变量2.4.1.staticfinal2.4.2.blankfinal2.4.3.所有final修饰的字段都是编译期常量吗?三.final域重排序规则3.1.f......
  • JTCR-探索 java.lang-16
    原始类型包装器为了在必须使用类类型的地方使用原始类型,每个原始类型都有一个包装器,该包装器将原始类型封装成类类型。抽象类Number作为所有数值类型包装类的父类,定义了返回不同类型值的抽象方法。它的子类有Byte、Short、Integer、Long、Float和Double。这些抽象方法形式......
  • HIVE使用java生成自定义(UDF)函数,并在hive命令中使用
      创建一个maven项目(不要用springboot)  引入依赖<!--添加hive依赖--><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>3.1.1</versio......
  • JavaScript注释:单行注释和多行注释详解
    为了提高代码的可读性,JS与CSS一样,也提供了注释功能。JS中的注释主要有两种,分别是单行注释和多行注释。在编程的世界里,注释是那些默默无闻的英雄,它们静静地站在代码的背后,为后来的维护者、为未来的自己,甚至是为那些偶然间翻阅你代码的开发者提供着不可或缺的信息。今天,我们就来深......
  • Cassandra节点重启失败 java.lang.RuntimeException: A node with address *** alread
    问题杀死一个节点后重启报节点已存在:java.lang.RuntimeException:Anodewithaddress***alreadyexists,cancellingjoin.Usecassandra.replace_addressifyouwanttoreplacethisnode.解决方法到另一个节点Cassandra的bin目录./nodetoolstatus查看需要重启......
  • fastjson导致的程序崩溃:A fatal error has been detected by the Java Runtime Enviro
    ##AfatalerrorhasbeendetectedbytheJavaRuntimeEnvironment:##EXCEPTION_ACCESS_VIOLATION(0xc0000005)atpc=0x000001da4d3ab6b3,pid=15996,tid=0x0000000000006478##JREversion:Java(TM)SERuntimeEnvironment(8.0_361)(build1.8.0_361-b09)......
  • Java中的static关键字解析
    一.static关键字的用途二.static关键字的误区三.常见的笔试面试题一.static关键字的用途在《Java编程思想》P86页有这样一段话:“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,......