一.实现步骤
- 创建数据集
- 计算用户相似度,使用jaccard 计算相似度
- 获取相似用户
- 获取相似用户相关物品
- 过滤物品
二.代码实现
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)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。