推荐系统评测方法和指标
目录
前提
假设研究的是是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