推荐系统:协同过滤基础

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

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

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

常用相似度指标

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

1、余弦相似度:用夹角的余弦值来度量相似的情况, 两个向量只要方向一致,无论程度强弱, 都可以视为’相似’;

2、皮尔逊相关系数Pearson:实际上也是一种余弦相似度, 不过先对向量做了中心化,是两个变量的变化趋势是否一致, 不适合计算布尔值向量之间的相关度

3、杰卡德相似度 Jaccard:两个集合的交集元素个数在并集中所占的比例, 非常适用于布尔向量表示

总结:余弦相似度适合用户评分数据(实数值), 杰卡德相似度适用于隐式反馈数据(0,1布尔值)(是否收藏,是否点击,是否加购物车)

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

 

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

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

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


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

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

User-Based CF

import pandas as pd
import numpy as np

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
# 计算用户间相似度
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

 

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

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

print("Top2相似用户:")
print(topN_users)
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("最终推荐结果:")
print(rs_results)

Top2相似用户:
{'User1': ['User3', 'User2'], 'User2': ['User1', 'User4'], 'User3': ['User1', 'User5'], 'User4': ['User2', 'User5'], 'User5': ['User3', 'User1']}
最终推荐结果:
{'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

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相似物品:")
print(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("最终推荐结果:")
print(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 D'],
 'Item B': ['Item E', 'Item C'],
 'Item C': ['Item A', 'Item B'],
 'Item D': ['Item E', 'Item A'],
 'Item E': ['Item B', 'Item D']}
最终推荐结果:
{'User1': {'Item B', 'Item E'},
 'User2': {'Item B', 'Item C'},
 'User3': {'Item D', 'Item B'},
 'User4': {'Item C', 'Item A'},
 'User5': {'Item D'}}

 ALS协同过滤

PySpark推荐模型之基于隐式反馈的矩阵分解ALS

Wide&Deep与Deep&Cross模型

posted @ 2022-02-15 00:17  Christbao  阅读(134)  评论(0编辑  收藏  举报