1. 加载数据
- 从
test_user_items.json加载测试集数据,其中包含每个用户在测试集上交互的物品。 - 从
train_user_items.json加载训练集数据,其中包含每个用户在训练集上交互的物品。 - 从
user_simscore.json加载用户之间的相似度分数。
2. 获取推荐物品
- 定义函数
get_items_by_sim_user(ui, top_n=10),为用户ui生成推荐物品。- 获取与用户
ui最相似的用户及其相似度分数。 - 获取用户
ui已经交互过的物品,避免推荐已知的物品。 - 计算相似用户交互过的物品的推荐分数,公式为: 推荐分数=相似度×评分
- 对推荐分数进行排序,返回分数最高的
top_n个物品。
- 获取与用户
3. 计算召回率
- 对每个用户,获取其在测试集上的物品集合
test_items。 - 获取推荐系统为该用户推荐的物品集合
recall_items。 - 计算推荐物品与测试集物品的交集大小,并除以测试集物品的总数,得到该用户的召回率。
- 对所有用户的召回率求平均,得到整个推荐系统的召回率。
4. 实现逻辑
import json
from collections import defaultdict
with open('test_user_items.json', 'r') as f:
test_user_items = json.load(f)
with open('train_user_items.json', 'r') as f:
train_user_items = json.load(f)
with open('user_simscore.json', 'r') as f:
user_simscore = json.load(f)
def get_items_by_sim_user(ui, top_n=10):
# 获取用户相似用户
ux_simscores = user_simscore.get(ui, [])
# 获取用户历史交互过的商品,已交互过的商品不再推荐,作为过滤使用
ui_items = train_user_items.get(ui, [])
ui_items = set(map(lambda x : x[0], ui_items))
item_score = defaultdict(float)
# 遍历相似用户以及相似用户交互过的商品
for uj, sim_score in ux_simscores:
# 相似用户交互过的商品作为推荐商品
uj_items = train_user_items.get(uj, [])
# 计算推荐分数
for item, rate, _ in uj_items:
if item in ui_items:
continue
item_score[item] += rate * sim_score
if not item_score:
return None
item_score = sorted(item_score.items(), key=lambda x: x[1], reverse=True)
return set(item[0] for item in item_score[:top_n])
all_users = set(test_user_items.keys())
total_recall = 0.0
for user in all_users:
test_items = test_user_items.get(user, None)
if not test_items:
continue # 跳过测试集中没有物品的用户
test_items = set(map(lambda x : x[0], test_items))
recall_items = get_items_by_sim_user(user, top_n=100)
if not recall_items:
continue
recall_count = len(recall_items & test_items)
total_recall += recall_count / len(test_items)
average_recall = total_recall / len(all_users)
print(f"Average Recall: {average_recall}")
最终召回率为0.28802590474991013