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