推荐系统评测方法和指标
目录
前提
假设研究的是是TopN推荐问题,即推荐的任务是预测用户会不会对物品进行评分(或其他行为),程序上表现为是否会产生一条‘用户-物品’记录。
离线评测方法(交叉验证)
将用户行为数据集均等分成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离线评测指标
召回率
召回率描述有多少比例的用户-物品记录包含在最终的推荐结果列表里。即推荐正确的数量与实际记录数之比。
xxxxxxxxxx # 计算召回率 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 Popluarity(train,test,N): item_popularity=dict() for user,item 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