其他分享
首页 > 其他分享> > 推荐系统基础总结

推荐系统基础总结

作者:互联网

推荐系统基础总结

文章目录

推荐系统简介

个性化推荐(推荐系统)经历了多年的发展,已经成为互联网产品的标配,也是AI成功落地的分支之一,在电商(淘宝/京东)、资讯(今日头条/微博)、音乐(网易云音乐/QQ音乐)、短视频(抖音/快手)等热门应用中,推荐系统都是核心组件之一。

推荐系统产生背景

什么是推荐系统

推荐系统VS搜索引擎

搜索推荐
行为方式 主动 被动
意图 明确 模糊
个性化
流量分布 马太效应 长尾效应
目标 快速满足 持续服务
评估指标 简明 复杂

推荐系统的作用

推荐系统的工作原理

推荐系统和Web项目的区别

推荐系统设计

推荐系统要素

推荐系统架构

大数据Lambda架构

推荐算法架构

在这里插入图片描述

推荐算法

推荐模型构建流程

Data(数据)->Features(特征)->ML Algorithm(机器学习算法)->Prediction Output(预测输出)

数据清洗/数据处理

在这里插入图片描述

数据来源–Data(数据)
特征工程–Features(特征)

在这里插入图片描述

在这里插入图片描述

选择合适的算法–ML Algorithm(机器学习算法)

在这里插入图片描述

产生推荐结果–Prediction Output(预测输出)

在这里插入图片描述

最经典的推荐算法:协同过滤推荐算法(Collaborative Filtering)

算法思想:物以类聚,人以群分

基本的协同过滤推荐算法基于以下假设:

实现协同过滤推荐有以下几个步骤:

  1. 找出最相似的人或物品:TOP-N相似的人或物品

    通过计算两两的相似度来进行排序,即可找出TOP-N相似的人或物品

  2. 根据相似的人或物品产生推荐结果

    利用TOP-N结果生成初始推荐结果,然后过滤掉用户已经有过记录的物品或明确表示不感兴趣的物品

以下是一个简单的示例,数据集相当于一个用户对物品的购买记录表:打勾表示用户对物品的有购买记录

User-Based CF

在这里插入图片描述

Item-Based CF

在这里插入图片描述

通过前面两个demo,相信大家应该已经对协同过滤推荐算法的设计与实现有了比较清晰的认识。

相似度计算(Similarity Calculation)

在这里插入图片描述

相似度的计算方法

在这里插入图片描述

​ 欧氏距离的值是一个非负数, 最大值正无穷, 通常计算相似度的结果希望是[-1,1]或[0,1]之间,一般可以使用

​ 如下转化公式:在这里插入图片描述

杰卡德相似度&余弦相似度&皮尔逊相关系数

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

协同过滤推荐算法代码实现

User-Based CF
import pandas as pd
import numpy as np
from pprint import pprint
from sklearn.metrics.pairwise import pairwise_distances

users = ["User1", "User2", "User3", "User4", "User5"]
items = ["Item A", "Item B", "Item C", "Item D", "Item E"]
# 用户购买记录数据集
datasets = [
    [1, 0, 1, 1, 0],
    [1, 0, 0, 1, 1],
    [1, 0, 1, 0, 0],
    [0, 1, 0, 1, 1],
    [1, 1, 1, 0, 1],
]

df = pd.DataFrame(datasets, columns=items, index=users)
# pprint(df)
# 计算用户间相似度
user_similar = 1 - pairwise_distances(df.values, metric="jaccard")
user_similar = pd.DataFrame(user_similar, columns=users, index=users)
print("用户之间的两两相似度:")
pprint(user_similar)

# 为每一个用户找到最相似的两个用户
topN_users = {}
# 遍历每一行数据
for i in user_similar:
    # 取出每一列数据,并删除自身,然后按照相似度排序数据
    _df = user_similar.loc[i].drop(labels=i)
    _df_sored = _df.sort_values(ascending=False)
    top2 = list(_df_sored.index[:2])
    topN_users[i] = top2

print("Top2相似用户:")
pprint(topN_users)

# 根据TOPN的相似用户,构建推荐结果
rs_results = {}
# 存储推荐结果
for user, sim_users in topN_users.items():
    rs_result = set()  # 为每一个用户保存推荐结果
    for sim_user in sim_users:
        # 构建初始的推荐结果
        rs_result = rs_result.union(set(df.loc[sim_user].replace(0, np.nan).dropna().index))
    # 过滤掉已经购买过的物品
    rs_result -= set(df.loc[user].replace(0, np.nan).dropna().index)
    rs_results[user] = rs_result

print("最终推荐结果:")
pprint(rs_results)


# 用户之间的两两相似度:
#           User1  User2     User3  User4  User5
# User1  1.000000   0.50  0.666667    0.2    0.4
# User2  0.500000   1.00  0.250000    0.5    0.4
# User3  0.666667   0.25  1.000000    0.0    0.5
# User4  0.200000   0.50  0.000000    1.0    0.4
# User5  0.400000   0.40  0.500000    0.4    1.0
# Top2相似用户:
# {'User1': ['User3', 'User2'],
#  'User2': ['User4', 'User1'],
#  'User3': ['User1', 'User5'],
#  'User4': ['User2', 'User5'],
#  'User5': ['User3', 'User4']}
# 最终推荐结果:
# {'User1': {'Item E'},
#  'User2': {'Item B', 'Item C'},
#  'User3': {'Item D', 'Item B', 'Item E'},
#  'User4': {'Item A', 'Item C'},
#  'User5': {'Item D'}}
Item-Based CF
import pandas as pd
import numpy as np
from pprint import pprint

users = ["User1", "User2", "User3", "User4", "User5"]
items = ["Item A", "Item B", "Item C", "Item D", "Item E"]
# 用户购买记录数据集
datasets = [
    [1, 0, 1, 1, 0],
    [1, 0, 0, 1, 1],
    [1, 0, 1, 0, 0],
    [0, 1, 0, 1, 1],
    [1, 1, 1, 0, 1],
]

df = pd.DataFrame(datasets, columns=items, index=users)

# 计算所有的数据两两的杰卡德相似系数
from sklearn.metrics.pairwise import pairwise_distances

# 计算物品间相似度
item_similar = 1 - pairwise_distances(df.T.values, metric="jaccard")
item_similar = pd.DataFrame(item_similar, columns=items, index=items)
print("物品之间的两两相似度:")
print(item_similar)

topN_items = {}
# 遍历每一行数据
for i in item_similar.index:
    # 取出每一列数据,并删除自身,然后排序数据
    _df = item_similar.loc[i].drop([i])
    _df_sorted = _df.sort_values(ascending=False)

    top2 = list(_df_sorted.index[:2])
    topN_items[i] = top2

print("Top2相似物品:")
pprint(topN_items)

rs_results = {}
# 构建推荐结果
for user in df.index:  # 遍历所有用户
    rs_result = set()
    for item in df.loc[user].replace(0, np.nan).dropna().index:  # 取出每个用户当前已购物品列表
        # 根据每个物品找出最相似的TOP-N物品,构建初始推荐结果
        rs_result = rs_result.union(topN_items[item])
    # 过滤掉用户已购的物品
    rs_result -= set(df.loc[user].replace(0, np.nan).dropna().index)
    # 添加到结果中
    rs_results[user] = rs_result

print("最终推荐结果:")
pprint(rs_results)

# 物品之间的两两相似度:
#         Item A    Item B  Item C  Item D    Item E
# Item A    1.00  0.200000    0.75    0.40  0.400000
# Item B    0.20  1.000000    0.25    0.25  0.666667
# Item C    0.75  0.250000    1.00    0.20  0.200000
# Item D    0.40  0.250000    0.20    1.00  0.500000
# Item E    0.40  0.666667    0.20    0.50  1.000000
# Top2相似物品:
# {'Item A': ['Item C', 'Item E'],
#  'Item B': ['Item E', 'Item D'],
#  'Item C': ['Item A', 'Item B'],
#  'Item D': ['Item E', 'Item A'],
#  'Item E': ['Item B', 'Item D']}
# 最终推荐结果:
# {'User1': {'Item E', 'Item B'},
#  'User2': {'Item B', 'Item C'},
#  'User3': {'Item E', 'Item B'},
#  'User4': {'Item A'},
#  'User5': {'Item D'}}
 
关于协同过滤推荐算法使用的数据集

在前面的demo中,我们只是使用用户对物品的一个购买记录,类似也可以是比如浏览点击记录、收听记录等等。这样数据我们预测的结果其实相当于是在预测用户是否对某物品感兴趣,对于喜好程度不能很好的预测。

因此在协同过滤推荐算法中其实会更多的利用用户对物品的“评分”数据来进行预测,通过评分数据集,我们可以预测用户对于他没有评分过的物品的评分。其实现原理和思想和都是一样的,只是使用的数据集是用户-物品的评分数据。

关于用户-物品评分矩阵

用户-物品的评分矩阵,根据评分矩阵的稀疏程度会有不同的解决方案

这里先介绍稠密评分矩阵的处理,稀疏矩阵的处理相对会复杂一些,我们到后面再来介绍。

使用协同过滤推荐算法对用户进行评分预测

评分预测

User-Based CF 评分预测:使用用户间的相似度进行预测

关于评分预测的方法也有比较多的方案,下面介绍一种效果比较好的方案,该方案考虑了用户本身的评分评分以及近邻用户的加权平均相似度打分来进行预测:
p r e d ( u , i ) = r ^ u i = ∑ v ∈ U s i m ( u , v ) ∗ r v i ∑ v ∈ U ∣ s i m ( u , v ) ∣ pred(u,i)=\hat{r}_{ui}=\cfrac{\sum_{v\in U}sim(u,v)*r_{vi}}{\sum_{v\in U}|sim(u,v)|} pred(u,i)=r^ui​=∑v∈U​∣sim(u,v)∣∑v∈U​sim(u,v)∗rvi​​
我们要预测用户1对物品E的评分,那么可以根据与用户1最近邻的用户2和用户3进行预测,计算如下:


p r e d ( u 1 , i 5 ) = 0.85 ∗ 3 + 0.71 ∗ 5 0.85 + 0.71 = 3.91 pred(u_1, i_5) =\cfrac{0.85*3+0.71*5}{0.85+0.71} = 3.91 pred(u1​,i5​)=0.85+0.710.85∗3+0.71∗5​=3.91
最终预测出用户1对物品5的评分为3.91

Item-Based CF 评分预测:使用物品间的相似度进行预测

这里利用物品相似度预测的计算同上,同样考虑了用户自身的平均打分因素,结合预测物品与相似物品的加权平均相似度打分进行来进行预测
p r e d ( u , i ) = r ^ u i = ∑ j ∈ I r a t e d s i m ( i , j ) ∗ r u j ∑ j ∈ I r a t e d s i m ( i , j ) pred(u,i)=\hat{r}_{ui}=\cfrac{\sum_{j\in I_{rated}}sim(i,j)*r_{uj}}{\sum_{j\in I_{rated}}sim(i,j)} pred(u,i)=r^ui​=∑j∈Irated​​sim(i,j)∑j∈Irated​​sim(i,j)∗ruj​​
我们要预测用户1对物品E的评分,那么可以根据与物品E最近邻的物品A和物品D进行预测,计算如下:
p r e d ( u 1 , i 5 ) = 0.97 ∗ 5 + 0.58 ∗ 4 0.97 + 0.58 = 4.63 pred(u_1, i_5) = \cfrac {0.97*5+0.58*4}{0.97+0.58} = 4.63 pred(u1​,i5​)=0.97+0.580.97∗5+0.58∗4​=4.63
对比可见,User-Based CF预测评分和Item-Based CF的评分结果也是存在差异的,因为严格意义上他们其实应当属于两种不同的推荐算法,各自在不同的领域不同场景下,都会比另一种的效果更佳,但具体哪一种更佳,必须经过合理的效果评估,因此在实现推荐系统时这两种算法往往都是需要去实现的,然后对产生的推荐效果进行评估分析选出更优方案。

基于模型的方法

基于图的模型

在这里插入图片描述

基于矩阵分解的模型

推荐系统评估

在这里插入图片描述

推荐系统的冷启动问题

推荐系统冷启动概念

用户冷启动

在这里插入图片描述

在这里插入图片描述

物品冷启动

在这里插入图片描述

系统冷启动

基于内容的推荐

基于内容的推荐 基于物品的协同过滤 区别

案例–基于协同过滤的电影推荐

前面我们已经基本掌握了协同过滤推荐算法,以及其中两种最基本的实现方案:User-Based CF和Item-Based CF,下面我们将利用真是的数据来进行实战演练。

案例需求

演示效果

分析案例

数据集下载

MovieLens Latest Datasets Small

建议下载ml-latest-small.zip,数据量小,便于我们单机使用和运行

目标:根据ml-latest-small/ratings.csv(用户-电影评分数据),分别实现User-Based CF和Item-Based CF,并进行电影评分的预测,然后为用户实现电影推荐

数据集加载

相似度计算

注意

以上实现,仅用于实验阶段,因为工业上、或生产环境中,数据量是远超过我们本例中使用的数据量的,而pandas是无法支撑起大批量数据的运算的,因此工业上通常会使用spark、mapReduce等分布式计算框架来实现,我们后面的课程中也是建立在此基础上进行实践的。

但是正如前面所说,推荐算法的思想和理念都是统一的,不论使用什么平台工具、有多大的数据体量,其背后的实现原理都是不变的。

所以在本节,大家要深刻去学习的是推荐算法的业务流程,以及在具体的业务场景中,如本例的电影推荐,如何实现出推荐算法,并产生推荐结果。

User-Based CF 预测评分实现

评分预测公式:
p r e d ( u , i ) = r ^ u i = ∑ v ∈ U s i m ( u , v ) ∗ r v i ∑ v ∈ U ∣ s i m ( u , v ) ∣ pred(u,i)=\hat{r}_{ui}=\cfrac{\sum_{v\in U}sim(u,v)*r_{vi}}{\sum_{v\in U}|sim(u,v)|} pred(u,i)=r^ui​=∑v∈U​∣sim(u,v)∣∑v∈U​sim(u,v)∗rvi​​
算法实现

Item-Based CF 预测评分实现

评分预测公式:
p r e d ( u , i ) = r ^ u i = ∑ j ∈ I r a t e d s i m ( i , j ) ∗ r u j ∑ j ∈ I r a t e d s i m ( i , j ) pred(u,i)=\hat{r}_{ui}=\cfrac{\sum_{j\in I_{rated}}sim(i,j)*r_{uj}}{\sum_{j\in I_{rated}}sim(i,j)} pred(u,i)=r^ui​=∑j∈Irated​​sim(i,j)∑j∈Irated​​sim(i,j)∗ruj​​
算法实现

标签:总结,ratings,评分,推荐,系统,用户,Item,物品,similar
来源: https://blog.csdn.net/qq_27396609/article/details/111831326