一、推荐系统简介

python编程快速上手(持续更新中…)

推荐系统基础


1.推荐系统概念

信息过滤系统,解决信息过载用户需求不明确问题

  • 利用一定规则将信息排序,展示给需求不明确的用户

推荐和搜索区别

  • 推荐:个性化较强,用户被动接收信息,希望提供持续服务
  • 搜索:个性化强,用户主动搜索,快速满足用户需求

推荐和web项目区别

  • Web:构建稳定的信息流通通道 明确预期
  • 推荐:信息过滤系统 概率问题

2.推荐系统设计

2.1推荐系统要素

  • UI和UE(前端页面)
  • 数据(Lambda架构)
  • 业务知识
  • 算法

2.2推荐系统架构

在这里插入图片描述

2.3Lambda架构介绍

离线计算实时计算共同提供服务的问题

离线计算优缺点

  • 优点:处理数据量可以很大,比如pb级别
  • 缺点:速度比较慢,分钟级别的延迟

实时计算

  • 优点:响应比较快,来一条处理一条ms级别
  • 缺点:处理数据量小一些

离线数据计算框架

  • hadoop
  • spark core,spark sql
  • hive

实时数据计算框架

  • spark Streaming
  • storm
  • fink

消息中间件

  • flume 日志采集系统
  • kafka 消息队列

存储相关

  • hbase nosql
  • hive sql操作hdfs数据

2.4Lambda架构图

在这里插入图片描述

2.5推荐算法架构

召回(海选) -> 排序(精选) -> 策略调整
在这里插入图片描述

3 推荐算法

3.1推荐模型构建过程

数据收集

  • 显示数据:评分、评论
  • 隐性数据:点击

特征工程

  • 协同过滤:用户-物品评分矩阵
  • 基于内容:分词tf-idf

训练模型

  • KNN
  • 矩阵分析

评估、模型上线

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

CF思想:物以类聚,人以群分
做系统过滤首先特征工程把物品的评分矩阵创建出来

User-Based CF

  • 1.给用户A找最相似的N个用户
  • 2.N个用户消费过哪些物品
  • 3.N个用户消费过的物品 - A用户消费过物品

Item-Based CF

  • 1.给物品a找最相似的N个物品
  • 2.A用户消费记录找这些物品相似物品
  • 3.从这些相似物品先去重-A用户消费过物品

3.3 相似度计算(Similarity Calculation)

余弦相似度、皮尔逊相关系数

  • 向量的夹角余弦值
  • 皮尔逊会对向量的每一个分量做中心化
  • 余弦只考虑方向 不考虑向量长度
  • 如果评分数据是连续的数据值比较适合余弦、皮尔逊计算相似度

杰卡德相似度

  • 交集/并集
  • 计算评分0/1布尔类型相似度

3.4 协同过滤推荐算法(推荐用户商品):

1.是否购买推荐用户商品

A.根据用户是否购买商品推荐商品构建数据集

users = ["User1", "User2", "User3", "User4", "User5"]
items = ["Item A", "Item B", "Item C", "Item D", "Item E"]
# 构建数据集
datasets = [
    ["buy",None,"buy","buy",None],
    ["buy",None,None,"buy","buy"],
    ["buy",None,"buy",None,None],
    [None,"buy",None,"buy","buy"],
    ["buy","buy","buy",None,"buy"],
]

B.计算时我们数据通常都需要对数据进行处理,或者编码,目的是为了便于我们对数据进行运算处理,比如这里是比较简单的情形,我们用1、0分别来表示用户的是否购买过该物品,则我们的数据集其实应该是这样的:

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],
]
import pandas as pd

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

结果:

       Item A  Item B  Item C  Item D  Item E
User1       1       0       1       1       0
User2       1       0       0       1       1
User3       1       0       1       0       0
User4       0       1       0       1       1
User5       1       1       1       0       1

C.有了数据集,接下来我们就可以进行相似度的计算,不过对于相似度的计算其实是有很多专门的相似度计算方法的,比如余弦相似度、皮尔逊相关系数、杰卡德相似度等等。这里我们选择使用杰卡德相似系数[0,1]

# 直接计算某两项的杰卡德相似系数
# 计算Item A 和Item B的相似度
print(jaccard_score(df["Item A"], df["Item B"]))

结果:

0.2
# 计算所有的数据两两的杰卡德相似系数
# 计算用户间相似度
user_similar = 1 - pairwise_distances(df.values, metric="jaccard")
user_similar = pd.DataFrame(user_similar, columns=users, index=users)
print("用户之间的两两相似度:")
print(user_similar)

结果:

用户之间的两两相似度:
          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

D.有了两两的相似度,接下来就可以筛选TOP-N相似结果,并进行推荐了

# User-Based CF
topN_users = {}
# 遍历每一行数据
for i in user_similar.index:
    # 取出每一列数据,并删除自身,然后排序数据
    _df = user_similar.loc[i].drop([i])
    #sort_values 排序 按照相似度降序排列
    _df_sorted = _df.sort_values(ascending=False)
    # 从排序之后的结果中切片 取出前两条(相似度最高的两个)
    top2 = list(_df_sorted.index[:2])
    topN_users[i] = top2

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

结果:

{'User1': ['User3', 'User2'],
 'User2': ['User1', 'User4'],
 'User3': ['User1', 'User5'],
 'User4': ['User2', 'User5'],
 'User5': ['User3', 'User1']}
# 准备空白dict用来保存推荐结果
rs_results = {}
#遍历所有的最相似用户
for user, sim_users in topN_users.items():
    rs_result = set()    # 存储推荐结果
    for sim_user in sim_users:
        # 构建初始的推荐结果
#         print('sim_user:', sim_user)
#         print('df:', sim_user)
        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': {'Item E'},
 'User2': {'Item B', 'Item C'},
 'User3': {'Item D', 'Item B', 'Item E'},
 'User4': {'Item C', 'Item A'},
 'User5': {'Item D'}}
2.预测用户1对物品E的评分

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

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

稠密评分矩阵

A.构建数据集:注意这里构建评分数据时,对于缺失的部分我们需要保留为None,如果设置为0那么会被当作评分值为0去对待

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

B.计算相似度:对于评分数据这里我们采用皮尔逊相关系数[-1,1]来计算,-1表示强负相关,+1表示强正相关
pandas中corr方法可直接用于计算皮尔逊相关系数

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

print("用户之间的两两相似度:")# 直接计算皮尔逊相关系数# 默认是按列进行计算,因此如果计算用户间的相似度,当前需要进行转置
user_similar = df.T.corr()
print(user_similar.round(4))

print("物品之间的两两相似度:")
item_similar = df.corr()
print(item_similar.round(4))

运行结果:

用户之间的两两相似度:
        User1   User2   User3   User4   User5
User1  1.0000  0.8528  0.7071  0.0000 -0.7921
User2  0.8528  1.0000  0.4677  0.4900 -0.9001
User3  0.7071  0.4677  1.0000 -0.1612 -0.4666
User4  0.0000  0.4900 -0.1612  1.0000 -0.6415
User5 -0.7921 -0.9001 -0.4666 -0.6415  1.0000
物品之间的两两相似度:
        Item A  Item B  Item C  Item D  Item E
Item A  1.0000 -0.4767 -0.1231  0.5322  0.9695
Item B -0.4767  1.0000  0.6455 -0.3101 -0.4781
Item C -0.1231  0.6455  1.0000 -0.7206 -0.4276
Item D  0.5322 -0.3101 -0.7206  1.0000  0.5817
Item E  0.9695 -0.4781 -0.4276  0.5817  1.0000

可以看到与用户1最相似的是用户2和用户3;与物品A最相似的物品分别是物品E和物品D。

注意:我们在预测评分时,往往是通过与其有正相关的用户或物品进行预测,如果不存在正相关的情况,那么将无法做出预测。这一点尤其是在稀疏评分矩阵中尤为常见,因为稀疏评分矩阵中很难得出正相关系数。

评分预测:
在这里插入图片描述

3.使用不同相似度计算方式实现协同过滤总结

在这里插入图片描述

4.协同过滤,基于模型的算法

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

在这里插入图片描述

3.5.推荐系统的冷启动

在这里插入图片描述

3.6.基于内容的推荐

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

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值