Weiguo's Station

  • 博客首页

  • 文章归档

  • 分类专栏

  • 各种标签

  • 站点搜索

各种评价指标

发表于 2018-09-29 更新于 2021-03-22 分类于 基础知识

1. 混淆矩阵及其衍生

1.1 Confusion Matrix

实际负例 实际正例
预测负例 TN (将负例预测为负例个数) FN (将正例预测为负例个数)
实际正例 FP (将负例预测为正例个数) TP (将正例预测为正例个数)

1.2 召回率 Recall

1.3 精确率 Precision

1.4 准确率 Accuracy

1.5 调和均值 F-score

1.6 True Positive Rate (TPR):代表将正例分对的概率

1.7 False Positive Rate (FPR):代表将负例错分为正例的概率

2. ROC & AUC & GAUC

2.1 受试者曲线 ROC

在ROC空间中,每个点的横坐标是 FPR(假正数-负样本被预测为正样本的个数/概率),纵坐标是 TPR(真正数-正样本被预测为正样本的个数/概率), 这也就描绘了分类器在 TP(真正的正例) 和 FP(错误的正例) 间的 trade-off。 ROC的主要分析工具是一个画在ROC空间的曲线(ROC curve),对于二分类问题,实例的值往往是连续值,我们通过设定一个阈值,将实例分类到正例或负例(比如大于阈值划分为正类)。 因此可以变化阈值,根据不同的阈值进行分类,根据分类结果计算得到ROC空间中相应的点,连接这些点就形成ROC curve。 ROC curve经过(0,0)、(1,1),实际上(0,0)和(1,1)连线形成的ROC curve实际上代表的是一个随机分类器;一般情况下,这个曲线都应该处于(0,0)和(1,1)连线的上方。

2.2 受试者曲线下面积 AUC

用ROC curve来表示分类器的performance很直观好用。可是,人们总是希望能有一个数值来标志分类器的好坏。于是 AUC (Area Under roc Curve)就出现了。AUC的值就是处于ROC curve下方的那部分面积的大小。

计算方法一

  • example1:

    index label predictScore
    0 0 0.1
    1 0 0.4
    2 1 0.35
    3 1 0.8

    负样本和正样本两两组合后的index集合是:(0, 2)、(0, 3)、(1, 2)、(1, 3)

    • (0, 2): 中正样本概率大于负样本概率(0.35 > 0.1), 计 1
    • (0, 3): 中正样本概率大于负样本概率(0.8 > 0.1), 计 1
    • (1, 2): 中正样本概率小于负样本概率(0.35 < 0.4), 计 0
    • (1, 3): 中正样本概率大于负样本概率(0.8 > 0.4), 计 1

      所以这个batch的AUC为:$AUC = \frac{3}{4} = 0.75$

  • example2: 当存在正负样本得到的 predictScore 相同时,计 $0.5$

    index label predictScore
    0 0 0.1
    1 0 0.4
    2 1 0.4
    3 1 0.8

    负样本和正样本两两组合后的index集合是:(0, 2)、(0, 3)、(1, 2)、(1, 3)

    • (0, 2): 中正样本概率大于负样本概率(0.4 > 0.1), 计 1
    • (0, 3): 中正样本概率大于负样本概率(0.8 > 0.1), 计 1
    • (1, 2): 中正样本概率小于负样本概率(0.4 = 0.4), 计 0.5
    • (1, 3): 中正样本概率大于负样本概率(0.8 > 0.4), 计 1

      所以这个batch的AUC为:$AUC = \frac{3.5}{4} = 0.875$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def calculate_auc(y_true, y_pred):
import numpy as np

pos_index = np.where(y_true == 1)
neg_index = np.where(y_true == 0)

pos_cnt = sum(y_true)
neg_cnt = len(y_true) - pos_cnt

count = 0
for pindex in pos_index[0]:
for nindex in neg_index[0]:
if y_pred[pindex] > y_pred[nindex]:
count += 1
elif y_pred[pindex] == y_pred[nindex]:
count += 0.5
else:
count += 0

return 1.0 * count / (pos_cnt * neg_cnt)

计算方法二

  • 其中 $rank_{ins_i}$ 代表第 $i$ 条样本的序号。(概率得分从小到大,排在第$rank$个位置);
  • $M$表示正样本的个数; $N$表示负样本的个数;
  • $\sum_{ins_i \in positiveclass}$ 把所有正样本的累加

  • 使用example1中的样本计算,按照概率排序后得到:

    index label predictScore rank
    0 0 0.1 1
    1 1 0.35 2
    2 0 0.4 3
    3 1 0.8 4

    按照上面的公式,将正样本的序号加起来,即index=1, index=3的rank值加起来,之后减去一个常数项 $0.5 \times M \times (M + 1)$; 得到的公式结果:$\frac{(2 + 4) - 0.5 \times 2 \times (2 + 1)}{2 \times 2} = \frac{6 - 3}{4} = 0.75$

  • 当存在相同的 predictScore, 并且其中存在着正负样本

    index label predictScore rank
    0 0 0.3 1
    1 1 0.5 2
    2 1 0.5 3
    3 0 0.5 4
    4 0 0.5 5
    5 1 0.7 6
    6 1 0.8 7

    这里需要注意的是:相等概率得分的样本,无论正负,谁在前,谁在后无所谓。

    由于只考虑正样本的rank值:
    对于正样本index=1,其rank值为 (5+4+3+2)/4
    对于正样本index=2,其rank值为 (5+4+3+2)/4
    对于正样本index=5,其rank值为 6
    对于正样本index=6,其rank值为 7

    最终得到:$\frac{(5+4+3+2)/4 + (5+4+3+2)/4 + 6 + 7 - 0.5 \times 4 \times (4 + 1)}{4 \times 3} = \frac{10}{12}$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def calculate_auc(y_true, y_pred):
pos_cnt = sum(y_true)
neg_cnt = len(y_true) - pos_cnt
sum_rank = 0

ranked_data = sorted(zip(y_true, y_pred), key=lambda x: x[1])

score2rank = {}
for index, (label, score) in enumerate(ranked_data):
if score not in score2rank:
score2rank[score] = [index + 1]
else:
score2rank[score].append(index + 1)

for label, score in ranked_data:
if label == 1:
sum_rank += sum(score2rank[score]) / 1.0 * len(score2rank[score])

numerator = sum_rank - 0.5 * pos_cnt * (pos_cnt + 1)
denominator = pos_cnt * neg_cnt
return numerator / denominator

2.3 推荐系统常用 GAUC (group AUC)

即按照用户进行聚合后单独计算每个用户的AUC,然后将所有用户的AUC进行按照样本数量进行加权平均

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from collections import defaultdict
from sklearn.metrics import roc_auc_score
import numpy as np

def cal_group_auc(labels, preds, user_id_list):
"""Calculate group auc"""
if len(user_id_list) != len(labels):
raise ValueError(
"impression id num should equal to the sample num," \
"impression id num is {0}".format(len(user_id_list)))
group_score = defaultdict(lambda: [])
group_truth = defaultdict(lambda: [])
for idx, truth in enumerate(labels):
user_id = user_id_list[idx]
score = preds[idx]
truth = labels[idx]
group_score[user_id].append(score)
group_truth[user_id].append(truth)

# 标记一个用户是不是全是正样本或者全是负样本
group_flag = defaultdict(lambda: False)
for user_id in set(user_id_list):
truths = group_truth[user_id]
flag = False
for i in range(len(truths) - 1):
if truths[i] != truths[i + 1]:
flag = True
break
group_flag[user_id] = flag

impression_total = 0
total_auc = 0
for user_id in group_flag:
# 全是正样本或负样本的用户不统计
if group_flag[user_id]:
auc = roc_auc_score(np.asarray(group_truth[user_id]),
np.asarray(group_score[user_id]))
# 用户的auc按照样本数量进行加权
total_auc += auc * len(group_truth[user_id])
# 总的统计auc的样本数量
impression_total += len(group_truth[user_id])

group_auc = float(total_auc) / impression_total
group_auc = round(group_auc, 4)
return group_auc

3. AP & MAP

3.1 AP(Average Precision)

假使当我们使用google搜索某个关键词,返回了10个结果。当然最好的情况是这10个结果都是我们想要的相关信息。 但是假如只有部分是相关的,比如5个,那么这5个结果如果被显示的比较靠前也是一个相对不错的结果。 但是如果这个5个相关信息从第6个返回结果才开始出现,那么这种情况便是比较差的。 这便是AP所反映的指标,与recall的概念有些类似,不过是“顺序敏感的recall”。

比如对于用户 $u$, 我们给他推荐一些物品,那么 $u$ 的平均准确率定义为:

在这里 $p_{ui}$ 表示推荐列表中物品 $i$ 的排序位置。$p_{uj} \lt p_{ui}$ 表示在对用户 $u$ 的排序列表中物品 $j$ 的排序位置在物品 $i$ 的前面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

3.2 MAP(Mean Average Precision)

即为所有用户 $u$ 的AP再取均值(mean)而已。

4. CG & DCG & NDCG

4.1 CG(Cummulative Gain)

直接翻译的话叫做“累计增益”。 在推荐系统中,CG即将每个推荐结果相关性(relevance)的分值累加后作为整个推荐列表(list)的得分。

这里, $rel_i$ 表示处于位置 $i$ 的推荐结果的相关性,$k$ 表示所要考察的推荐列表的大小。

4.2 DCG(Discounted Cummulative Gain)

CG的一个缺点是没有考虑每个推荐结果处于不同位置对整个推荐效果的影响,例如我们总是希望相关性高的结果应排在前面。显然,如果相关性低的结果排在靠前的位置会严重影响用户体验, 所以在CG的基础上引入位置影响因素,即DCG(Discounted Cummulative Gain), “Discounted”有打折,折扣的意思,这里指的是对于排名靠后推荐结果的推荐效果进行“打折处理”:

  • 分子部分 $2^{rel_i}−1$, $rel_i$越大,即推荐结果 $i$ 的相关性越大,推荐效果越好, DCG越大。
  • 分母部分 $log_2 (i+1)$, $i$ 表示推荐结果的位置,$i$ 越大,则推荐结果在推荐列表中排名越靠后,推荐效果越差,DCG越小。

4.3 NDCG(Normalized Discounted Cummulative Gain)

DCG仍然有其局限之处,即不同的推荐列表之间,很难进行横向的评估。而我们评估一个推荐系统,不可能仅使用一个用户的推荐列表及相应结果进行评估, 而是对整个测试集中的用户及其推荐列表结果进行评估。 那么不同用户的推荐列表的评估分数就需要进行归一化,也即NDCG(Normalized Discounted Cummulative Gain)。

在介绍NDCG之前,还需要了解一个概念:IDCG, 即Ideal DCG, 指推荐系统为某一用户返回的最好推荐结果列表, 即假设返回结果按照相关性排序,最相关的结果放在最前面,此序列的DCG为IDCG。因此DCG的值介于 $(0, IDCG]$,故NDCG的值介于$(0,1]$。

对于用户 $u$ 的 $NDCG@k$ 定义为:

这里的 $k$ 表示推荐列表的大小。那么,则有:

在具体操作中, 可以事先确定推荐目标和推荐结果的相关性分级。

  • 例如可以使用 $0,1$ 分别表示相关或不相关,比如此处我们用 $ref_i = \delta( i \in I_u^{te} )$, 在这里如果 $x$ 为true, 则 $\delta (x) = 1$,否则 $\delta(x)=0$。
  • 或是使用 $0 \sim 5$ 分别表示严重不相关到非常相关, 也即相当于确定了 $rel$ 值的范围。之后对于每一个推荐目标的返回结果给定 $rel$ 值,然后使用DCG的计算公式计计算出返回结果的DCG值。使用根据排序后的 rel 值序列计算IDCG值,即可计算NDCG.

Ref

  1. 推荐系统常见评测标准之MAP与NDCG
  2. AUC的计算方法
  3. sklearn.metrics.roc_auc_score
  4. 图解AUC和GAUC
  5. qiaoguan/deep-ctr-prediction/DeepCross/metric.py
# 评估方法 # ROC & AUC & GAUC # AP & MAP # CG & DCG & NDCG
My Resume (2018)
K-Means聚类
  • 文章目录
  • 站点概览
WeiguoZHAO

WeiguoZHAO

Welcome to my blog~
87 日志
13 分类
49 标签
GitHub E-Mail
大牛们
  • colah's blog
  • 王喆的Github
  • 刘建平的Github
  • 美团技术团队
  1. 1. 混淆矩阵及其衍生
    1. 1.1 Confusion Matrix
    2. 1.2 召回率 Recall
    3. 1.3 精确率 Precision
    4. 1.4 准确率 Accuracy
    5. 1.5 调和均值 F-score
    6. 1.6 True Positive Rate (TPR):代表将正例分对的概率
    7. 1.7 False Positive Rate (FPR):代表将负例错分为正例的概率
  2. 2. ROC & AUC & GAUC
    1. 2.1 受试者曲线 ROC
    2. 2.2 受试者曲线下面积 AUC
    3. 2.3 推荐系统常用 GAUC (group AUC)
  3. 3. AP & MAP
    1. 3.1 AP(Average Precision)
    2. 3.2 MAP(Mean Average Precision)
  4. 4. CG & DCG & NDCG
    1. 4.1 CG(Cummulative Gain)
    2. 4.2 DCG(Discounted Cummulative Gain)
    3. 4.3 NDCG(Normalized Discounted Cummulative Gain)
  5. Ref
© 2021 WeiguoZHAO
0%