Hear大数据项目——推荐系统架构与数据模型设计

摘要

第1章项目体系架构设计

1.1 项目系统架构

项目以推荐系统建设领域知名的经过修改过的 MovieLens 数据集作为依托,以某科技公司电影网站真实业务数据架构为基础,构建了符合教学体系的一体化的电影推荐系统,包含了离线推荐与实时推荐体系,综合利用了协同过滤算法以及基于内容的推荐方法来提供混合推荐。提供了从前端应用、后台服务、算法设计实现、平台部署等多方位的闭环的业务实现。

用户可视化: 主要负责实现和用户的交互以及业务数据的展示,主体采用AngularJS2 进行实现, 部署在 tomcat服务上。

综合业务服务: 主要实现 JavaEE 层面整体的业务逻辑,通过 Spring 进行构建,对接业务需求。部署在 Tomcat 上。

【 数据存储部分】

业务数据库: 项目采用广泛应用的文档数据库 MongDB 作为主数据库, 主要负责平台业务逻辑数据的存储。

搜索服务器: 项目爱用 ElasticSearch 作为模糊检索服务器, 通过利用 ES 强大的匹配查询能力实现基于内容的推荐服务。

缓存数据库: 项目采用 Redis 作为缓存数据库, 主要用来支撑实时推荐系统部分对于数据的高速获取需求。

【离线推荐部分】

离线统计服务: 批处理统计性业务采用 Spark Core + Spark SQL 进行实现,实现对指标类数据的统计任务。

离线推荐服务: 离线推荐业务采用 Spark Core + Spark MLlib 进行实现, 采用ALS 算法进行实现。

工作调度服务: 对于离线推荐部分需要以一定的时间频率对算法进行调度, 采用 Azkaban 进行任务的调度。

【实时推荐部分】

日志采集服务: 通过利用 Flume-ng 对业务平台中用户对于电影的一次评分行为进行采集, 实时发送到 Kafka 集群。

消息缓冲服务: 项目采用 Kafka 作为流式数据的缓存组件, 接受来自 Flume 的数据采集请求。 并将数据推送到项目的实时推荐系统部分。

实时推荐服务: 项目采用 Spark Streaming 作为实时推荐系统, 通过接收 Kafka中缓存的数据, 通过设计的推荐算法实现对实时推荐的数据处理, 并将结构合并更新到 MongoDB 数据库。

1.2 项目数据流程

【系统初始化部分】

0. 通过 Spark SQL 将系统初始化数据加载到 MongoDB 和 ElasticSearch 中。

【离线推荐部分】

1. 通过 Azkaban 实现对于离线统计服务以离线推荐服务的调度,通过设定的运行时间完成对任务的触发执行。

2. 离线统计服务从 MongoDB 中加载数据,将【电影平均评分统计】、【电影评分个数统计】、【最近电影评分个数统计】三个统计算法进行运行实现,并将计算结果回写到 MongoDB 中;离线推荐服务从 MongoDB 中加载数据,通过 ALS 算法分别将【用
户推荐结果矩阵】、【影片相似度矩阵】回写到 MongoDB 中。

【实时推荐部分】

3. Flume 从综合业务服务的运行日志中读取日志更新,并将更新的日志实时推送到Kafka 中; Kafka 在收到这些日志之后,通过 kafkaStream 程序对获取的日志信息进行过滤处理,获取用户评分数据流【UID|MID|SCORE|TIMESTAMP】,并发送到另外一
个 Kafka 队列; Spark Streaming 监听 Kafka 队列, 实时获取 Kafka 过滤出来的用户评分数据流, 融合存储在 Redis 中的用户最近评分队列数据, 提交给实时推荐算法,完成对用户新的推荐结果计算;计算完成之后,将新的推荐结构和 MongDB 数据库
中的推荐结果进行合并。

【业务系统部分】

4. 推荐结果展示部分,从 MongoDB、 ElasticSearch 中将离线推荐结果、实时推荐结果、内容推荐结果进行混合,综合给出相对应的数据。

5. 电影信息查询服务通过对接 MongoDB 实现对电影信息的查询操作。

6. 电影评分部分, 获取用户通过 UI 给出的评分动作,后台服务进行数据库记录后,一方面将数据推动到 Redis 群中,另一方面,通过预设的日志框架输出到 Tomcat 中的日志中。

7. 项目通过 ElasticSearch 实现对电影的模糊检索。

8. 电影标签部分, 项目提供用户对电影打标签服务。

1.3 数据模型

1. Movie【电影数据表】

2. Rating【用户评分表】

3. Tag【电影标签表】

4. User【用户表】

5. RateMoreMoviesRecently【最近电影评分个数统计表】

6. RateMoreMovies【电影评分个数统计表】

7. AverageMoviesScore【电影平均评分表】

8. MovieRecs【电影相似性矩阵】

9. UserRecs【用户电影推荐矩阵】

10. StreamRecs【用户实时电影推荐矩阵】

11. GenresTopMovies【电影类别 TOP10】

第 2 章 工具环境搭建

我们的项目中用到了多种工具进行数据的存储、计算、采集和传输,本章主要简单介绍设计的工具环境搭建。
如果机器的配置不足, 推荐只采用一台虚拟机进行配置,而非完全分布式,将该虚拟机 CPU 的内存设置的尽可能大,推荐为 CPU > 4、 MEM > 4GB。
2.1 MongoDB(单节点)环境配置
2.2 Redis(单节点)环境配置
2.3 ElasticSearch(单节点)环境配置
2.4 Azkaban(单节点)环境配置
2.5 Spark(单节点)环境配置
2.6 Zookeeper(单节点)环境配置
2.7 Flume-ng(单节点)环境配置
2.8 Kafka(单节点)环境配置

1安装MongoDB在centos7  centos7下安装mongodb_chenlongjs的博客-CSDN博客_centos7 mongodb

进入到MongoDB的bin 目录下 命令:./mongod --config /usr/mongodb/mongodb441/mongodb.conf1

 

2安装redis https://www.cnblogs.com/heqiuyong/p/10463334.html 

 3安装ElasticSearch Linux centos7 安装ElasticSearch 7.0_weixin_34218579的博客-CSDN博客

先赋予权限给这个xjl 进入到/usr 的目录下 chown -R xjl elasticsearch/* 然后su xjl 在进入bin 在输入./elasticsearch

4安装Flume CentOS 7.0安装flume_iccool-cc的博客-CSDN博客_centos安装flume

 5安装zookeeper和kafkacentos安装kafka - sky_cheng - 博客园

在安装的过程中的使用的zookeeper一定要是的后缀带有bin的文件才能不出错。

6安装单机版本的sparklinux CentOS7 安装spark - shaomine - 博客园

第 3 章 创建项目构建

3.1项目的创建

我们的项目主体用 Scala 编写,采用 IDEA 作为开发环境进行项目编写,采用maven 作为项目构建和管理工具。

3.2数据的加载

第4 章 离线推荐服务建设

4.1 离线推荐服务

离线推荐服务是综合用户所有的历史数据, 利用设定的离线统计算法和离线推荐算法周期性的进行结果统计与保存, 计算的结果在一定时间周期内是固定不变的,变更的频率取决于算法调度的频率。离线推荐服务主要计算一些可以预先进行统计和计算的指标, 为实时计算和前端业务相应提供数据支撑。离线推荐服务主要分为统计性算法、 基于 ALS 的协同过滤推荐算法以及基于ElasticSearch 的内容推荐算法。

4.2 离线统计服务

1 历史热门电影统计:根据所有历史评分数据, 计算历史评分次数最多的电影。
实现思路:通过 Spark SQL 读取评分数据集,统计所有评分中评分数最多的电影,然后按照从大到小排序,将最终结果写入 MongoDB 的 RateMoreMovies 数据集中。

 2 最近热门电影统计:根据评分,按月为单位计算最近时间的月份里面评分数最多的电影集合。
实现思路:通过 Spark SQL 读取评分数据集, 通过 UDF 函数将评分的数据时间修改为月,然 后 统 计 每 月 电 影 的 评 分 数  统 计 完 成 之 后 将 数 据 写 入 到 MongoDB 的RateMoreRecentlyMovies 数据集中。

3  电影平均得分统计:根据历史数据中所有用户对电影的评分,周期性的计算每个电影的平均得分。
实现思路:通过 Spark SQL 读取保存在 MongDB 中的 Rating 数据集,通过执行以下 SQL 语句实现对于电影的平均分统计:

4 每个类别优质电影统计:根据提供的所有电影类别, 分别计算每种类型的电影集合中评分最高的 10 个电影。
实现思路:在计算完整个电影的平均得分之后,将影片集合与电影类型做笛卡尔积,然后过滤掉电影类型不符合的条目,将 DataFrame 输出到 MongoDB 的 GenresTopMovies集合中。

4.3 基于隐语义模型的协同过滤推荐

项目采用 ALS 作为协同过滤算法 分别根据 MongoDB 中用户评分表和电影数据集计算用户电影推荐矩阵以及电影相似度矩阵。

1 用户电影推荐矩阵通过 ALS 训练出来的 Model 来计算所有当前用户电影的推荐矩阵,主要思路如下:
        1. UserId 和 MovieID 做笛卡尔积,产生( uid, mid)的元组
        2. 通过模型预测( uid, mid)的元组。
        3. 将预测结果通过预测分值进行排序。
        4. 返回分值最大的 K 个电影, 作为当前用户的推荐。
最后生成的数据结构如下:将数据保存到 MongoDB 的 UserRecs 表中

2 电影相似度矩阵通过 ALS 计算电影见相似度矩阵, 该矩阵用于查询当前电影的相似电影并为实时推荐系统服务。离线计算的 ALS 算法,算法最终会为用户、电影分别生成最终的特征矩阵,分别是表示用户特征矩阵的 U(m x k)矩阵,每个用户由 k 个特征描述;表示物品特征矩阵的 V(n x k)矩阵,每个物品也由 k 个特征描述。V(n x k)表示物品特征矩阵,每一行是一个 k 维向量,虽然我们并不知道每一个维度的特征意义是什么,但是 k 个维度的数学向量表示了该行对应电影的特征。

数据集中任意两个电影间相似度都可以由公式计算得到,电影与电影之间的相似度在一段时间内基本是固定值。最后生成的数据保存到 MongoDB 的 MovieRecs表中。

3 模型评估和参数选取
在上述模型训练的过程中,我们直接给定了隐语义模型的 rank,iterations,lambda三个参数。对于我们的模型,这并不一定是最优的参数选取,所以我们需要对模型进行评估。通常的做法是计算均方根误差( RMSE),考察预测评分与实际评分之间的误差

第 5 章 实时推荐服务建设

5.1 实时推荐服务

实时计算与离线计算应用于推荐系统上最大的不同在于实时计算推荐结果应该反映最近一段时间用户近期的偏好,而离线计算推荐结果则是根据用户从第一次评分起的所有评分记录来计算用户总体的偏好。用户对物品的偏好随着时间的推移总是会改变的。比如一个用户 u 在某时刻对电影 p 给予了极高的评分,那么在近期一段时候, u 极有可能很喜欢与电影 p 类似的其他电影;而如果用户 u 在某时刻对电影 q 给予了极低的评分,那么在近期一段时候, u 极有可能不喜欢与电影 q 类似的其他电影。所以对于实时推荐,当用户对一个电影进行了评价后,用户会希望推荐结果基于最近这几次评分进行一定的更新,使得推荐结果匹配用户近期的偏好,满足用户近期的口味。如果实时推荐继续采用离线推荐中的 ALS 算法,由于算法运行时间巨大,不具有实时得到新的推荐结果的能力;并且由于算法本身的使用的是评分表,用户本次评分后只更新了总评分表中的一项,使得算法运行后的推荐结果与用户本次评分之前的推荐结果基本没有多少差别,从而给用户一种推荐结果一直没变化的感觉,很影响用户体验。另外,在实时推荐中由于时间性能上要满足实时或者准实时的要求,所以算法的计算量不能太大,避免复杂、过多的计算造成用户体验的下降。鉴于此,推荐精度往往不会很高。实时推荐系统更关心推荐结果的动态变化能力,只要更新推荐结果的理由合理即可,至于推荐的精度要求则可以适当放宽。所以对于实时推荐算法,主要有两点需求:
( 1)用户本次评分后、或最近几个评分后系统可以明显的更新推荐结果;
( 2)计算量不大,满足响应时间上的实时或者准实时要求;

5.2 实时推荐算法设计

当用户 u 对电影 p 进行了评分,将触发一次对 u 的推荐结果的更新。由于用户 u 对电影 p 评分,对于用户 u 来说,他与 p 最相似的电影们之间的推荐强度将发生变化,所以选取与电影 p 最相似的 K 个电影作为候选电影。每个候选电影按照“推荐优先级”这一权重作为衡量这个电影被推荐给用户 u的优先级。这些电影将根据用户 u 最近的若干评分计算出各自对用户 u 的推荐优先级,然后与上次对用户 u 的实时推荐结果的进行基于推荐优先级的合并、替换得到更新后的推荐结果。
具体来说:首先,获取用户 u 按时间顺序最近的 K 个评分,记为 RK;获取电影 p 的最相似的 K 个电影集合,记为 S;然后,对于每个电影 q S ,计算其推荐优先级 , 计算公式如下:

公式的意义如下:首先对于每个候选电影 q,从 u 最近的 K 个评分中,找出与 q 相似度较高>=0.6)的 u 已评分电影们,对于这些电影们中的每个电影 r,将 r 与 q 的相似度乘以用户 u 对 r 的评分,将这些乘积计算平均数,作为用户 u 对电影 q 的评分预测

然后,将 u 最近的 K 个评分中与电影 q 相似的、且本身评分较高( >=3)的电影个数记为 incount,计算 lgmax{incount,1}作为电影 q 的“增强因子”,意义在于电影 q 与 u 的最近 K 个评分中的 n 个高评分(>=3)电影相似,则电影 q 的优先级被增加 lgmax{incount,1}。如果电影 q 与 u 的最近 K 个评分中相似的高评分电影越多,也就是说 n 越大,则电影 q 更应该被推荐,所以推荐优先级被增强的幅度较大;如果电影 q 与 u 的最近 K 个评分中相似的高评分电影越少,也就是n 越小,则推荐优先级被增强的幅度较小;而后,将 u 最近的 K 个评分中与电影 q 相似的、且本身评分较低( <3)的电影个数记为 recount,计算 lgmax{recount,1}作为电影 q 的“削弱因子”,意义在于电影 q 与 u 的最近 K 个评分中的 n 个低评分(<3)电影相似,则电影 q 的优先级被削减 lgmax{incount,1}。如果电影 q 与 u 的最近 K 个评分中相似的低评分电影越多,也就是说 n 越大,则电影 q 更不应该被推荐,所以推荐优先级被减弱的幅度较大;如果电影 q 与 u 的最近 K 个评分中相似的低评分电影越少,也就是 n 越小,则推荐优先级被减弱的幅度较小;最后,将增强因子增加到上述的预测评分中,并减去削弱因子,得到最终的 q 电影对于 u 的推荐优先级。在计算完每个候选电影 q 的 后,将生成一组<电影 q 的ID, q 的推荐优先级>的列表 updatedList:

5.3 实时推荐算法的实现

实时推荐算法的前提:

1. 在 Redis 集群中存储了每一个用户最近对电影的 K 次评分。实时算法可以快速获取。

2. 离线推荐算法已经将电影相似度矩阵提前计算到了 MongoDB 中。

3. Kafka 已经获取到了用户实时的评分数据。

算法过程如下:实时推荐算法输入为一个评分<userId, movieId, rate, timestamp>,而执行的核心内容包括:获取 userId 最近 K 次评分、获取 movieId 最相似 K 个电影、计算候选电影的推荐优先级、更新对 userId 的实时推荐结果。
1 获取用户的 K 次最近评分:业务服务器在接收用户评分的时候, 默认会将该评分情况以 userId, movieId, rate,timestamp 的格式插入到 Redis 中该用户对应的队列当中,在实时算法中,只需要通过 Redis 客户端获取相对应的队列内容即可。
2 获取当前电影最相似的 K 个电影:在 离线算 法中 , 已经预 先将电 影的 相似度矩 阵进行 了计 算 , 所以 每个电 影movieId 的最相似的 K 个电影很容易获取: 从 MongoDB 中读取 MovieRecs 数据,从 movieId 在 simHash 对应的子哈希表中获取相似度前 K 大的那些电影。输出是数 据 类 型 为 Array[Int]的 数 组 , 表 示 与 movieId 最 相 似 的 电 影 集 合 , 并 命 名 为candidateMovies 以作为候选电影集合。

4 更新实时推荐结果:

当计算出候选电影的推荐优先级的数组 updatedRecommends<movieId, E>后,这个数组将被发送到 Web 后台服务器,与后台服务器上 userId 的上次实时推荐结果recentRecommends<movieId, E>进行合并、替换并选出优先级 E 前 K 大的电影作为本次新的实时推荐。具体而言:a.合并:将 updatedRecommends 与 recentRecommends 并集合成为一个新的<movieId, E>数组;
b.替换(去重):当 updatedRecommends 与 recentRecommends 有重复的电影movieId 时, recentRecommends 中 movieId 的推荐优先级由于是上次实时推荐的结果,于是将作废,替换成代表了更新后的 updatedRecommends 的 movieId 的推荐优级;
c.选取 TopK:在合并、替换后的<movieId, E>数组上,根据每个 movie 的推荐优先级,选择出前 K 大的电影,作为本次实时推荐的最终结果。

第 6 章 系统冷启动问题

整个推荐系统更多的是依赖于用于的偏好信息进行电影的推荐, 那么就会存在一个问题, 对于新注册的用户是没有任何偏好信息记录的, 那这个时候推荐就会出现问题, 导致没有任何推荐的项目出现。处理这个问题一般是通过当用户首次登陆时, 为用户提供交互式的窗口来获取用户对于物品的偏好。在本项目中, 当用户第一次登陆的时候, 系统会询问用户对于影片类别的偏好。
当获取用户的偏好之后,对应于需要通过用户偏好信息获取的推荐结果,则更改为通过对影片的类型的偏好的推荐。

第 7 章 基于内容的推荐服务

7.1 基于内容的推荐服务

原始数据中的 tag 文件,是用户给电影打上的标签,这部分内容想要直接转成评分并不容易,不过我们可以将标签内容进行提取, 得到电影的内容特征向量,进而可以通过求取相似度矩阵。这部分可以与实时推荐系统直接对接,计算出与用户当前评分电影的相似电影,实现基于内容的实时推荐。为了避免热门标签对特征提取的影响,我们还可以通过 TF-IDF 算法对标签的权重进行调整,从而尽可能地接近用户偏好。

然后通过电影特征向量进而求出相似度矩阵,就可以为实时推荐提供基础,得到用户推荐列表了。 可以看出,基于内容和基于隐语义模型,目的都是为了提取出物品的特征向量,从而可以计算出相似度矩阵。而我们的实时推荐系统算法正是基于相似度来定义的。

  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
如今大数据已经成了各大互联网公司工作的重点方向,而推荐系统可以说就是大数据最好的落地应用之一,已经为企业带来了可观的用户流量和销售额。特别是对于电商,好的推荐系统可以大大提升电商企业的销售业绩。国内外的知名电商,如亚马逊、淘宝、京东等公司,都在推荐系统领域投入了大量研发力量,也在大量招收相关的专业人才。打造的电商推荐系统项目,就是以经过修改的中文亚马逊电商数据集作为依托,并以某电商网站真实的业务架构作为基础来实现的,其中包含了离线推荐与实时推荐体系,综合利用了协同过滤算法以及基于内容的推荐方法来提供混合推荐。具体实现的模块主要有:基于统计的离线推荐、基于隐语义模型的离线推荐、基于自定义模型的实时推荐,以及基于内容的、和基于Item-CF的离线相似推荐。整个项目具有很强的实操性和综合性,对已有的大数据和机器学习相关知识是一个系统性的梳理和整合,通过学习,同学们可以深入了解推荐系统在电商企业中的实际应用,可以为有志于增加大数据项目经验的开发人员、特别是对电商业务领域感兴趣的求职人员,提供更好的学习平台。适合人群:1.有一定的 Java、Scala 基础,希望了解大数据应用方向的编程人员2.有 Java、Scala 开发经验,了解大数据相关知识,希望增加项目经验的开发人员3.有电商领域开发经验,希望拓展电商业务场景、丰富经验的开发人员4.有较好的数学基础,希望学br习机器学习和推荐系统相关算法的求职人员

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庄小焱

我将坚持分享更多知识

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值