一.实现步骤

  1. 创建数据集
  2. 计算用户相似度,使用jaccard 计算相似度
  3. 获取相似用户
  4. 获取相似用户相关物品
  5. 过滤物品

二.代码实现

1.准备数据

import pandas as pd
users = ['User1', 'User2', 'User3', 'User14', 'User5', ]
items = ['ItemA', 'ItemB', 'ItemC', 'ItemD', 'ItemE']
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)

2.计算用户相似度

使用sklearn 的 pairwise_distances 计算用户相似度

# sklearn 不能直接计算相似度,只能计算距离,使用1- 距离 就得到相似度
user_similar = 1 - pairwise_distances(df.values, metric='jaccard')
user_similar = pd.DataFrame(user_similar, columns=users, index=users)

3.获取相似的用户

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

4. 获取相似用户相关物品并过滤物品

rs_results = {}
# 对相似用户集合循环
for user, sim_users in topN_users.items():
    res_result = set()
    # 获取每个用户的集合
    for sim_user in sim_users:
        # 获取每个相似用户对应的物品的index
        res_result = res_result.union(set(df.loc[sim_user].replace(0, np.nan).dropna().index))
    # 过滤掉推荐用户已经看过的物品
    res_result -= set(df.loc[user].replace(0, np.nan).dropna().index)
    rs_results[user] = res_result 

结果

{'User1': {'ItemE'}, 
'User2':  {'ItemC', 'ItemB'}, 
'User3':  {'ItemE', 'ItemB', 'ItemD'}, 
'User14': {'ItemA', 'ItemC'},
 'User5': {'ItemD'}}

完整代码

import pandas as pd
from sklearn.metrics import jaccard_score
from sklearn.metrics.pairwise import pairwise_distances
import numpy as np
users = ['User1', 'User2', 'User3', 'User14', 'User5', ]
items = ['ItemA', 'ItemB', 'ItemC', 'ItemD', 'ItemE']
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)
# score = jaccard_score(df['ItemA'], df['ItemB'])
# print(score)
print(df)
user_similar = 1 - pairwise_distances(df.values, metric='jaccard')
user_similar = pd.DataFrame(user_similar, columns=users, index=users)

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(topN_users)

rs_results = {}
for user, sim_users in topN_users.items():
    res_result = set()
    for sim_user in sim_users:
        res_result = res_result.union(set(df.loc[sim_user].replace(0, np.nan).dropna().index))
    res_result -= set(df.loc[user].replace(0, np.nan).dropna().index)
    rs_results[user] = res_result
print(rs_results)

捕风
47 声望16 粉丝