1.处理数据集:将用户行为数据集按照均匀分布随机分成M份,挑选一份作为测试集,剩下的M-1份作为训练集
import random
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 test,train
2.评测指标
①准确率和召回率
对用户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)
②覆盖率覆盖率反应了推荐算法发掘长尾的能力,覆盖率越高,说明推荐算法越能将长尾中的物品推荐给用户,覆盖率定义为:
其中I表示所有物品的集合,覆盖率表示最终的推荐列表中包含多大比例的物品,如果所有用户都被推荐给至少一个用户,则覆盖率为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():
ret+=math.log(1+item_popularity[item])
n+=1
ret/=n*1.0
return ret
在计算平均流行度时对每个物品发流行度取对数,这是因为武平的流行度分布满足长尾分布,在取对数后,流行度的平均值更加稳定。