基于Spark3的个性化推荐系统——理论知识

本博客整理自慕课网实战《基于Spark2.x的个性化推荐系统》

目录

  • 一.推荐系统的生态介绍
    • 1.生态概述
    • 2.常见问题
    • 3.效果评测
  • 二.协同过滤推荐算法原理
    • 1.基于用户的协同过滤
    • 2.基于物品的协同过滤
    • 3.基于模型的协同过滤
    • 4.缺失值填充
  • 三.ALS算法原理

一.推荐系统的生态介绍

基于Spark3的个性化推荐系统——理论知识_第1张图片

1.生态概述

数据
基于Spark3的个性化推荐系统——理论知识_第2张图片
算法

  • 基于关联的推荐算法:如购买鞋子的顾客,会有10%的顾客会买袜子。有Apriori算法和FP-Growth算法。
  • 基于内容的推荐算法:打标签(效率不高),文本相似度(TF-IDF算法),分类算法(KNN,决策树,朴素贝叶斯)。
  • 基于协同过滤的推荐算法
    • 基于用户的协同过滤:兴趣相近的用户会对同样的物品感兴趣。
    • 基于物品的协同过滤:推荐给用户内容相似的物品。

基于Spark3的个性化推荐系统——理论知识_第3张图片

  • 基于模型的推荐算法:深度学习(属于机器学习的范畴)。
  • 基于混合的推荐算法:将以上的各种推荐算法加权或者分层,用户能得到更全面的推荐。

领域知识

基于Spark3的个性化推荐系统——理论知识_第4张图片
UI
基于Spark3的个性化推荐系统——理论知识_第5张图片

2.常见问题

冷启动

  • 用户冷启动(一个新用户怎么推荐?)
    • 根据用户注册信息(邮箱类别,电话类别)
    • 推荐热门的排行榜(比较常用)
    • 基于深度学习语义分析(分析用户名来判断男女)
    • 引导用户将自己的爱好表达出来(注册账号时让用户勾选自己的爱好)
    • 利用用户在社交媒体的信息(QQ登录)
  • 物品冷启动(一个新物品怎么推荐?)
    • 文本分析(分析标题等文本信息)
    • 主题模型(预先训练一个模型,然后对新物品进行分类处理)
    • 给物品打标签(自己手动写)
    • 推荐排行榜单

数据稀疏

主要在协同过滤算法中,兴趣相近的用户会对同样的物品感兴趣。会构建用户-物品矩阵,但这个矩阵是稀疏矩阵。

  • 降维(奇异值分解)
  • 对感兴趣的相似物品也感兴趣(数据填充)
  • 基于深度学习的语义理解模型(基于物品本身的信息)

不断变化的用户喜好

  • 对用户行为的存储有实时性
  • 算法要考虑到近期行为和长期行为
  • 不断挖掘用户的新爱好(扩大推荐结果多样性)

3.效果评测

模型离线实验
在训练集上训练和在测试集上预测,评测预测的效果。

预测准确度:RMSE,MAE

TopN推荐:个性化推荐列表,预测准确度:准确率 / 召回率。
基于Spark3的个性化推荐系统——理论知识_第6张图片
覆盖率:是不是能够将所有物品都推荐给用户,而不是只推送热门的商品。

多样性,新颖性,惊喜度,信任度,实时性,健壮性。

A/B Test在线实验
基于Spark3的个性化推荐系统——理论知识_第7张图片

用户调研

二.协同过滤推荐算法原理

1.基于用户的协同过滤

基于用户的协同过滤有以下几个缺点:
1. 如果用户量很大,计算量就很大
2. 用户-物品打分矩阵是一个非常非常非常稀疏的矩阵,会面临大量的null值
很难得到两个用户的相似性
3. 会将整个用户-物品打分矩阵都载入到内存,而往往这个用户-物品打分矩阵是一个非常大的矩阵

所以通常不太建议使用基于用户的协同过滤。

基于Spark3的个性化推荐系统——理论知识_第8张图片
通过余弦相似度计算用户的相似度
余弦相似度的公式 : (A * B) / (|A| * |B|)

  • |A|和|B|的求解(对于用户1和用户2):
    2 2 + 3. 2 2 + 0 2 2 = 3.77 \sqrt[2]{2^2+3.2^2+0^2} = 3.77 222+3.22+02 =3.77
    0 2 + 1. 1 2 + 0 2 2 = 1.1 \sqrt[2]{0^2+1.1^2+0^2} = 1.1 202+1.12+02 =1.1
val dfScoreMod = df.rdd.map(x=>(x(0).toString,x(2).toString))
 .groupByKey() //按照用户id进行分组
 .mapValues(score=>math.sqrt(
   score.toArray.map(
     itemScore=>math.pow(itemScore.toDouble,2)
   ).reduce(_+_) 
   // ((物品a的打分)**2 + (物品b的打分)**2 .. (物品n的打分)**2))** 1/2
 ))
 .toDF("userId","mod")
  • 不同用户对同一个物品的score情况表:
//这里目的是把两两用户都放到了同一张表里
val _df = df.join(_dfTmp,df("itemId") === _dfTmp("itemId"))
  .where(
    df("userId") =!= _dfTmp("_userId")
  )
  .select(
    df("itemId"),
    df("userId"),
    _dfTmp("_userId"),
    df("score"),
    _dfTmp("_score")
  )
  • A * B的求解(用户1和2的维度乘积 ):
    2 × 0 + 3.2 × 1.1 + 0 × 0 = 3.52 2\times 0 + 3.2\times1.1+0\times0 = 3.52 2×0+3.2×1.1+0×0=3.52
itemId   userId    _userId     score    _score
1        1         2           2        0
2        1         2           3.2      1.1
3        1         2           0        0

//  两两向量的维度乘积并加总
import org.apache.spark.sql.functions._
val df_mol = _df.select(
  col("userId"),
  col("_userId"),
  (col("score") * col("_score"))
    .as("score_mol") //用户a和用户b对各自对同一个物品打分的乘积
).groupBy(col("userId"),col("_userId"))
.agg(sum("score_mol"))  //加总
.withColumnRenamed(
  "sum(score_mol)",
  "mol"
)
  • 用户1和2的相似度:
    3.52 / ( 3.77 × 1.1 ) = 0.84 3.52 / (3.77\times 1.1) = 0.84 3.52/(3.77×1.1)=0.84
// 分子 / 分母
val cos_sim = sim.select(
  col("userId"),
  col("_userId"),
  (col("mol") /
    (col("mod") * col("_mod")))
    .as("cos_sim")
)

2.基于物品的协同过滤

算法步骤:

  • 计算用户物品打分矩阵
    基于Spark3的个性化推荐系统——理论知识_第9张图片
    上方是原始表,通过将 itemId 这一列转成行,变成 用户-物品 的矩阵。

  • 计算物品相似度矩阵(两个物品同时被买的次数越多,相似度越高)
    基于Spark3的个性化推荐系统——理论知识_第10张图片

  • 用户物品打分矩阵 * 物品相似度矩阵 = 推荐列表

基于Spark3的个性化推荐系统——理论知识_第11张图片
原始表转化为 用户-物品 的矩阵:

val userItemTmp = userItemData.groupBy(col("userId"))
 .pivot(col("itemId"))
 .sum("vote")

物品相似度矩阵:

val rddTmp = userItemData.rdd.filter(x=>x.getFloat(2) > 0)
  .map(x=>{
    (x.getString(0),x.getString(1))
  })

3.基于模型的协同过滤

基于Spark3的个性化推荐系统——理论知识_第12张图片SVD分解(分成3个矩阵):
基于Spark3的个性化推荐系统——理论知识_第13张图片
U和V都是正交矩阵,中间的是奇异值的对角矩阵。

作用:

  • 数据降维,解决数据稀疏(SVD的前提是基于稠密矩阵的,所以稀疏矩阵先进行缺值填充,再进行SVD分解)
  • 减少特征空间,去除数据噪声。

PMF分解(分成2个矩阵):
基于Spark3的个性化推荐系统——理论知识_第14张图片

4.缺失值填充

固定值,均值,中位数,众数填充。

import org.apache.spark.ml.feature.Imputer

val imputer = new Imputer()
 .setInputCols(Array("rating"))
 .setOutputCols(Array("out_rating"))
 .setMissingValue(Float.NaN)
 .setStrategy("mean")

三.ALS算法原理

特征值分解只适用于方阵。

奇异值分解适用于其他矩阵,但是计算复杂度高。

ALS算法是PMF算法在数值计算方面的应用。

基于Spark3的个性化推荐系统——理论知识_第15张图片
误差 = 观察的评分矩阵 - 预测的评分矩阵

问题就转化成了求最优解。

在这里插入图片描述
使误差最小,加入了正则项,避免过拟合。

在迭代过程中,交替优化U和V,最小交替二乘法。

ALS算法的缺点:

  • 离线算法
  • 不能解决冷启动

你可能感兴趣的:(#,推荐系统,推荐系统,算法,协同过滤,机器学习)