AP(Average Precision)
平均准确率AP,假使当我们使用google搜索某个关键词,返回了10个结果。当然最好的情况是这10个结果都是我们想要的相关信息。但是假如只有部分是相关的,比如5个,那么这5个结果如果被显示的比较靠前也是一个相对不错的结果。但是如果这个5个相关信息从第6个返回结果才开始出现,那么这种情况便是比较差的。这便是AP所反映的指标,与recall的概念有些类似,不过是“顺序敏感的recall。
其中,表示ground-truth的结果, 表示物品在推荐列表中的位置, 表示物品在推荐列表中排在物品之前。
def AP(ranked_list, ground_truth):
"""Compute the average precision (AP) of a list of ranked items
"""
hits = 0
sum_precs = 0
for n in range(len(ranked_list)):
if ranked_list[n] in ground_truth:
hits += 1
sum_precs += hits / (n + 1.0)
if hits > 0:
return sum_precs / len(ground_truth)
else:
return 0
MAP(Mean Average Precision)
MAP表示所有用户的AP再取均值,计算公式如下:
def MAP(ranked_list_s, ground_truth_s):
sum_ap = 0
for i in range(len(ranked_list_s)):
sum_ap += AP(ranked_list_s[i], ground_truth_s[i])
return sum_ap / len(ranked_list_s)
AUC(Area Under Curve)
ROC(Receiver operating characteristic)
ROC曲线的横轴为假正例率FPR(越小越好),纵轴为真正例率TPR(越大越好)。
ROC计算过程:
- 首先每个样本都需要有一个label值,并且还需要一个预测的score值(取值0到1)
- 然后按这个score对样本由大到小进行排序,假设这些数据位于表格中的一列,从上到下依次降序
- 现在从上到下按照样本点的取值进行划分,位于分界点上面的我们把它归为预测为正样本,位于分界点下面的归为负样本
- 分别计算出此时的TPR和FPR,然后在图中绘制(FPR, TPR)点
AUC
AUC的含义:测试任意给一个正类样本和一个负类样本,正类样本的score有多大的概率大于负类样本的score。或者,任意给定一个负样本,所有正样本的score中有多大比例是大于该负类样本的score
from sklearn.metrics import roc_curve
from sklearn import metrics
fpr, tpr, thresholds = roc_curve(
test[:, 3],
predict_result,
pos_label=1
)
auc = metrics.auc(fpr, tpr)
plt.plot(fpr, tpr, linewidth=2, label='ROC(area = %0.2f)' % auc, color='green')
plt.xlabel('Fail Positive Rate')
plt.ylabel('Ture Positive Rate')
plt.xlim(0, 1.05)
plt.ylim(0, 1.05)
plt.legend(loc=4)
plt.show()
NDCG(Normalized Discounted Cummulative Gain)
CG(Cumulative Gain)
累积增益CG,推荐系统中CG表示将每个推荐结果相关性的分值累加后作为整个推荐列表的得分:
其中,表示位置iii的推荐结果的相关性,表示推荐列表的大小。
CG没有考虑每个推荐结果处于不同位置对整个推荐结果的影响,例如,我们总是希望相关性大大的结果排在前面,相关性低的排在前面会影响用户体验。
DCG(Discounted Cumulative Gain)
DCG在CG的基础上引入了位置影响因素,计算公式如下:
从上面的式子可以得出:
- 推荐结果的相关性越大,DCG越大。
- 相关性好的排在推荐列表前面的话,推荐效果越好,DCG越大。
NDCG(Normalized DCG)
DCG针对不同的推荐列表之间很难进行横向评估,而我们评估一个推荐系统不可能仅使用一个用户的推荐列表及相应结果进行评估,而是对整个测试集中的用户及其推荐列表结果进行评估。那么,不同用户的推荐列表的评估分数就需要进行归一化,也就是NDCG。
IDCG表示推荐系统某一用户返回的最好推荐结果列表, 即假设返回结果按照相关性排序, 最相关的结果放在最前面, 此序列的DCG为IDCG。因此DCG的值介于 ,故NDCG的值介于,那么用户的定义为:
平均NDCG的值为:
import pandas as pd
import numpy as np
df = pd.DataFrame(data = [3, 2, 3, 0, 1, 2], columns=["reli"])
df = df.reset_index()
df = df.rename(columns = {"index":"i"})
df["i"] += 1
df["log2(i+1)"] = np.log2(df["i"]+1)
df["reli /log2(i+1)"] = df["reli"] /df["log2(i+1)"]
df
---------------------
i reli log2(i+1) reli /log2(i+1)
0 1 3 1.000000 3.000000
1 2 2 1.584963 1.261860
2 3 3 2.000000 1.500000
3 4 0 2.321928 0.000000
4 5 1 2.584963 0.386853
5 6 2 2.807355 0.712414
----------------------
CG = df["reli"].sum()
CG
----------------------
11
----------------------
DCG = df["reli /log2(i+1)"].sum()
DCG
----------------------
6.861126688593502
----------------------
#理想情况排序
df["reli"] = df.sort_values(by="reli" , ascending=False).reset_index(drop=True)["reli"]
df["log2(i+1)"] = np.log2(df["i"]+1)
df["reli /log2(i+1)"] = df["reli"] /df["log2(i+1)"]
df
----------------------
i reli log2(i+1) reli /log2(i+1)
0 1 3 1.000000 3.000000
1 2 3 1.584963 1.892789
2 3 2 2.000000 1.000000
3 4 2 2.321928 0.861353
4 5 1 2.584963 0.386853
5 6 0 2.807355 0.000000
1
IDCG = df["reli /log2(i+1)"].sum()
IDCG
----------------------
7.1409951840957
----------------------
NDCG = DCG/IDCG
NDCG
----------------------
0.9608081943360617
参考
https://blog.csdn.net/qq_40006058/article/details/89432773
https://www.cnblogs.com/by-dream/p/9403984.html
https://en.wikipedia.org/wiki/Discounted_cumulative_gain