推荐系统常用评价指标及其 Python 实现

Precision@k。适用于 Top-K 推荐任务。

P r e c i s i o n @ K = ∑ i = 1 N ∣ R ( i ) ∩ T ( i ) ∣ ∑ i = 1 N ∣ R ( i ) ∣ (1) Precision@K=\frac{\sum_{i=1}^{N}|R(i)\cap T(i)|}{\sum_{i=1}^{N}|R(i)|}\tag{1} Precision@K=i=1NR(i)i=1NR(i)T(i)(1)

N N N 表示用户数, i i i 表示用户 id, R ( i ) R(i) R(i) 表示对用户 i i i 的推荐列表, T ( i ) T(i) T(i) 表示用户 i i i 的真实访问的项目列表。

Recall@k。适用于 Top-K 推荐任务。

R e c a l l @ K = ∑ i = 1 N ∣ R ( i ) ∩ T ( i ) ∣ ∑ i = 1 N ∣ T ( i ) ∣ (2) Recall@K=\frac{\sum_{i=1}^{N}|R(i)\cap T(i)|}{\sum_{i=1}^{N}|T(i)|}\tag{2} Recall@K=i=1NT(i)i=1NR(i)T(i)(2)

N N N 表示用户数, i i i 表示用户 id, R ( i ) R(i) R(i) 表示对用户 i i i 的推荐列表, T ( i ) T(i) T(i) 表示用户 i i i 的真实访问的项目列表。

HR(Hit Ratio)@K。适用于 Top-K 推荐任务。

H R @ K = ∑ i = 1 N h r ( i ) N (3) HR@K=\frac{\sum_{i=1}^{N}hr(i)}{N}\tag{3} HR@K=Ni=1Nhr(i)(3)

h r ( i ) = { 1 , R ( i ) ∩ T ( i ) ≠ ∅ 0 , R ( i ) ∩ T ( i ) = ∅ (4) hr(i)=\left\{\begin{array}{ll} 1 & , R(i) \cap T(i) \neq \varnothing \\ 0 & , R(i) \cap T(i)=\varnothing \end{array}\right.\tag{4} hr(i)={10,R(i)T(i)=,R(i)T(i)=(4)

N N N 表示用户数, i i i 表示用户 id, h r ( ⋅ ) hr(\cdot) hr() 表示命中函数, R ( i ) R(i) R(i) 表示对用户 i i i 的推荐列表, T ( i ) T(i) T(i) 表示用户 i i i 的真实访问的项目列表。

MRR(Mean Reciprocal Rank)@K。适用于 Top-K 推荐任务。

M R R @ K = 1 N ∑ i = 1 N 1 r a n k ( i ) (5) MRR@K=\frac{1}{N}\sum_{i=1}^{N}\frac{1}{rank(i)}\tag{5} MRR@K=N1i=1Nrank(i)1(5)

N N N 表示用户数, i i i 表示用户 id, r a n k ( i ) rank(i) rank(i) 表示对用户 i i i 的推荐中,第一个命中的项目在推荐列表中的次序,若没有命中 r a n k ( i ) → ∞ rank(i)\to\infty rank(i)

NDCG(Normalized Discounted Cumulative Gain)@K。适用于 Top-K 推荐任务。

C G @ K = ∑ i = 1 K r e l ( i ) (6) CG@K=\sum_{i=1}^{K}rel(i)\tag{6} CG@K=i=1Krel(i)(6)

r e l ( i ) = { 1 , r [ i ] = t [ i ] 0 , r [ i ] ≠ t [ i ] (7) rel(i)=\left\{\begin{array}{ll} 1 & , r[i] = t[i] \\ 0 & , r[i] \neq t[i] \end{array}\right.\tag{7} rel(i)={10,r[i]=t[i],r[i]=t[i](7)

D C G @ K = ∑ i = 1 K 2 r e l ( i ) − 1 l o g 2 ( i + 1 ) (8) DCG@K=\sum_{i=1}^{K}\frac{2^{rel(i)}-1}{log_{2}{(i+1)}}\tag{8} DCG@K=i=1Klog2(i+1)2rel(i)1(8)

I D C G @ K = ∑ i = 1 K 1 l o g 2 ( i + 1 ) (9) IDCG@K=\sum_{i=1}^{K}\frac{1}{log_{2}{(i+1)}}\tag{9} IDCG@K=i=1Klog2(i+1)1(9)

N D C G @ K = D C G @ K I D C G @ K (10) NDCG@K=\frac{DCG@K}{IDCG@K}\tag{10} NDCG@K=IDCG@KDCG@K(10)

NDCG@K 的计算对象是任一用户的推荐列表和其真实访问的项目列表。 r e l ( ⋅ ) rel(\cdot) rel() 表示相关函数,r 表示用户的推荐列表,t 表示用户真实访问的项目列表,IDCG (Idel Discounted Cumulative Gain)。

Python 实现

其中,Precision 是先求分子和分母之后再做除法,Recall 同样也是先计算分子和分母之后再做除法,HR 是求和命中数之后求均值,MRR 是计算排名的倒数和之后求均值,NDCG 是计算每个用户的真实列表和推荐列表的值然后求和再求均值。

def calc_precision_a(t, r):
    """
    The numerator of Precision
    t represent the true list for a user
    r represent the recommendation list for a user
    """
    return len([x for x in r if x in t])


def calc_precision_b(t, r):
	"""
	The denominator of Precision
    t represent the true list for a user
    r represent the recommendation list for a user
	"""
    return len(r)


def calc_recall_a(t, r):
    """
    The numerator of Precision
    t represent the true list for a user
    r represent the recommendation list for a user
    """
    return len([x for x in r if x in t])


def calc_recall_b(t, r):
	"""
	The denominator of Precision
	t represent the true list for a user
    r represent the recommendation list for a user
	"""
    return len(t)


def calc_hit(t, r):
    """
    calc the hit for a user
    t represent the true list for a user
    r represent the recommendation list for a user
    """
    for i in t:
        if i in r:
            return 1
    return 0


def calc_rank_reciprocal(t, r):
    for i in r:
        if i in t:
            return 1 / (t.index(i) + 1)
    return 0


def calc_ndcg(t, r):
    DCG, IDCG = [], []
    for i in range(min(len(t), len(r))):
        a = 1 if t[i] == r[i] else 0
        b = np.log2(i + 2)  # the index in the equation starts from 1, but in code it starts from 0.
        DCG.append(a / b)
        IDCG.append(1 / b)
    return np.sum(DCG) / np.sum(IDCG)


def evaluate(t, r):
    return calc_precision_a(t, r), calc_precision_b(t, r), calc_recall_a(t, r), calc_recall_b(t, r), calc_hit(t, r), calc_rank_reciprocal(t, r), calc_ndcg(t, r)


if __name__ == '__main__':
	Precision_a, Precision_b, Recall_a, Recall_b, HR, MRR, NDCG = [], [], [], [], [], [], []
    for u in range(1, num_users + 1):
        r = R[u]  # r
        t = T[u]  # t
        precision_a, precision_b, recall_a, recall_b, hr, mrr, ndcg = evaluate.evaluate(t, r)
        Precision_a.append(precision_a)
        Precision_b.append(precision_b)
        Recall_a.append(recall_a)
        Recall_b.append(recall_b)
        HR.append(hr)
        MRR.append(mrr)
        NDCG.append(ndcg)
    Precision = np.sum(Precision_a) / np.sum(Precision_b)
    Recall = np.sum(Recall_a) / np.sum(Recall_b)
    HR = np.mean(HR)
    MRR = np.mean(MRR)
    NDCG = np.mean(NDCG)
    print(f'Precision = {Precision}, Recall = {Recall}, HR = {HR}, MRR = {MRR}, NDCG = {NDCG}')
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值