推荐系统3—协同过滤算法实验设计

实验设计

        协同过滤算法的离线实验一般如下设计。首先,将用户行为数据集按照均匀分布随机分成M份,挑选一份作为测试集,将剩下的M-1份作为训练集。然后在训练集上建立用户兴趣模型,并在测试集上对用户行为进行预测,统计出相应的评测指标。为了保证评测指标并不是过拟合的结果,需要进行M次实验,并且每次都使用不同的测试集。然后将M次实验测出的评测指标的平均值作为最终的评测指标。

def SplitData(data, M, k, seed):
	test = []
	train = []
	random.seed(seed)
	for user, item in data:
		if random.randint(0,M) == k:
			test.append([user,item])
		else:
			train.append([user,item])
	return train, test

        这里,每次实验选取不同的k(0≤k≤M-1)和相同的随机数种子seed,进行M次实验就可以得到M个不同的训练集和测试集,然后分别进行实验,用M次实验的平均值作为最后的评测指标。这样做主要是防止某次实验的结果是过拟合的结果(over fitting),但如果数据集够大,模型够简单,为了快速通过离线实验初步地选择算法,也可以只进行一次实验。

评测指标

        对用户u推荐N个物品(记为R(u)),令用户u在测试集上喜欢的物品集合为T(u),然后可以通过准确率/召回率评测推荐算法的精度:

  

        召回率描述有多少比例的用户—物品评分记录包含在最终的推荐列表中,而准确率描述最终的推荐列表中有多少比例是发生过的用户—物品评分记录。

def Recall(train, test, N):
	hit = 0
	all = 0
	for user in train.keys():
		tu = test[user]
		rank = GetRecommendation(user, N)
		for item, pui in rank:
			if item in tu:
				hit += 1
		all += len(tu)
	return hit / (all * 1.0)
def Precision(train, test, N):
	hit = 0
	all = 0
	for user in train.keys():
		tu = test[user]
		rank = GetRecommendation(user, N)
		for item, pui in rank:
			if item in tu:
				hit += 1
		all += N
	return hit / (all * 1.0)

        除了评测推荐算法的精度,还计算了算法的覆盖率,覆盖率反映了推荐算法发掘长尾的能力,覆盖率越高,说明推荐算法越能够将长尾中的物品推荐给用户。这里,我们采用最简单的覆盖率定义:


        该覆盖率表示最终的推荐列表中包含多大比例的物品。如果所有的物品都被推荐给至少一个用户,那么覆盖率就是100%。如下代码可以用来计算推荐算法的覆盖率:

def Coverage(train, test, N):
	recommend_items = set()
	all_items = set()
	for user in train.keys():
		for item in train[user].keys():
			all_items.add(item)
		rank = GetRecommendation(user, N)
		for item, pui in rank:
			recommend_items.add(item)
	return len(recommend_items) / (len(all_items) * 1.0)

        最后,我们还需要评测推荐的新颖度,这里用推荐列表中物品的平均流行度度量推荐结果的新颖度。如果推荐出的物品都很热门,说明推荐的新颖度较低,否则说明推荐结果比较新颖。这里,在计算平均流行度时对每个物品的流行度取对数,这是因为物品的流行度分布满足长尾分布,在取对数后,流行度的平均值更加稳定。

def Popularity(train, test, N):
	item_popularity = dict()
	for user, items in train.items():
		for item in items.keys()
			if item not in item_popularity:
				item_popularity[item] = 0
			item_popularity[item] += 1
	ret = 0
	n = 0
	for user in train.keys():
		rank = GetRecommendation(user, N)
		for item, pui in rank:
			ret += math.log(1 + item_popularity[item])
			n += 1
	ret /= n * 1.0
	return ret

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值