zoukankan      html  css  js  c++  java
  • 机器学习复习:模型评估指标

    分类指标

    • 精确率和召回率:多用于二分类问题

      • 混淆矩阵

        k2Ni38.png

        其中,TP(True Positive, 真正):被模型预测为正例的正样本;

        FP(False Positive, 假正):被模型预测为正例的负样本;

        FN(False Negative, 假负):被模型预测为负例的正样本;

        TN(True Negative, 真负):被模型预测为负例的负样本。且TP+FP+FN+TN=样本总数

      • 精确率和召回率

        • 精确率(P)

          [精确率(P)=frac{TP}{TP+FP} ]

          其中,精确率的分母为被模型预测为正例的样本总数。也就是说,精确率表示:预测为正例中正例的概率(抓来的小偷中有多少是真小偷)

        • 召回率(R)

          [召回率(R)=frac{TP}{TP+FN} ]

          其中,召回率的分母为实际为正例的样本总数。也就是说,召回率表示:正例被预测的概率(有多少小偷被抓到)

        • P-R曲线

          以召回率R为横轴,精确度P为纵轴,可以画出P-R曲线。P-R曲线越靠近右上角越好,曲线下面积称作AP分数(Average Precision Score,平均精确率分数)。

          k28szQ.md.jpg

          (F_1)值是权衡精确率和召回率两者的指标,是精确率和召回率的调和平均值:

          [frac{2}{F_1}=frac{1}{P}+frac{1}{R} ]

          (F)值可泛化为对精确率和召回率进行加权调和:

          [F_{alpha}=frac{(1+alpha^2)PR}{alpha^2P+R} ]

          此外,准确率和错误率也是常用的评估指标:

          [准确率(accuracy)=frac{TP+TN}{TP+TN+FP+FN}\ 错误率(error rate)=frac{FP+FN}{TP+TN+FP+FN} ]

          注意:精确率和准确率是不同的指标,精确率是二分类指标,而准确率可用于多分类

          [准确率(accuracy)=frac{1}{n}sum_{i=1}^nI(y_i=hat{y_i}) ]

    • ROCAUC

      众多模型输出概率,而使用精确率、召回率这类指标进行模型评估时,需要对预测概率设分类阈值,如预测概率大于0.5为正例,反之为负例。这使得评估模型时多了一个超参数。

      ROC(Receiver Operating Characteristics, 接收者操作特征)曲线不需要设定这样的阈值,ROC曲线纵坐标是真正率,横坐标是假正率

      [真正率(TPR)=frac{TP}{TP+FN}\ 假正率(FPR)=frac{FP}{FP+TN} ]

      其中,真正率的分母为样本中所有正例,表示预测的正例中真正例占所有正例的比例;假正率的分母为样本中所有负例,表示预测的正例中假正例占所有负例的比例。注意与精确率和查全率的对比。ROC曲线越靠近左上角越好。

      k2Umse.png

      绘制方法示例

      假设有6次展示记录,有2次被点击了,得到一个展示序列:{1:1, 2:0, 3:1, 4:0, 5:0, 6:0}。其中,字典的键表示序号,值表示本次点击(1)或没有点击(0)。通过模型预测得到概率序列,计算得到概率序列是:{1:0.9, 2:0.7, 3:0.8, 4:0.6, 5:0.5, 6:0.4}。

      绘制步骤:

      • 将概率序列从高到低排序,得到序列{1:0.9, 3:0.8, 2:0.7, 4:0.6, 5:0.5, 6:0.4}

      • 从概率最大开始取一个点作为正例,取到点1,计算得到:

        [FPR=frac{0}{0+4}=0\ TPR=frac{1}{1+1}=0.5 ]

      • 再从概率最大开始取一个点作为正例,取到点3,计算得到:

        [FPR=frac{0}{0+4}=0\ TPR=frac{2}{2+0}=1 ]

      • 再从概率最大开始取一个点作为正例,取到点2,计算得到:

        [FPR=frac{1}{1+3}=0.25\ TPR=frac{2}{2+0}=1 ]

      • 以此类推,得到各个FPR和TPR

      • 组成6个数据点(0,0.5), (0,1), (0.25,1), (0.5,1), (0.75,1), (1,1),将数据点绘制如图所示。

        k2dZHH.jpg

        上图左上角坐标为(0,1),即FPR=0,TPR=1。根据FPR和TPR的计算公式可知,此时FN=0、FP=0,模型对所有样本分类正确。

        AUC(Area Under ROC Curve)即ROC曲线下面积。取值越大,说明将预测序列按概率值降序排列时,模型越可能将正样本排在负样本前面。

        AUC的一些统计特性:

        • AUC等于随机选择一个正样本和负样本时,分类器将正样本排在负样本前面的概率;

        • AUC和Wilcoxon Test of Ranks等价;

        • AUC和基尼(Gini)指数满足:

        [Gini+1=2×AUC ]

        AUC从物理意义上讲,表示的是ROC曲线下面积;从概率意义上讲,AUC考虑的是样本的排序质量。AUC的计算主要与排序有关,所以它对排序敏感,对具体的概率值没那么敏感。

      代码实现

    • 最直观的做法:正样本m个,负样本n个,正负样本排列有m*n中情况(概率论的乘法法则),统计m×n中正样本概率>负样本概率的情况个数。

      AUC的物理意义不仅仅是ROC曲线下面积,而且是:对于给定的正样本M个,负样本N个,以及它们的预测概率,则AUC就是穷举所有的正负样本对,如果正样本的预测概率大于负样本的预测概率,就加1;如果正样本的预测概率等于负样本的预测概率,就加0.5;如果正样本的预测概率小于负样本的预测概率,就加0。将统计值除以(M imes N)就得到了AUC,公式描述如下:

      [AUC=frac{I(P_{pos},P_{neg})}{M imes N} ]

      import numpy as np
      from sklearn.metrics import roc_curve, auc
      
      
      def naive_auc(labels, preds):
      	pos_indexes = []
      	neg_indexes = []
      	for index, label in enumerate(labels):
      		if label == 1:
      			pos_indexes.append(index)
      		elif label == 0:
      			neg_indexes.append(index)
      
      	auc = 0.
      	for pos_index in pos_indexes:
      		for neg_index in neg_indexes:
      			if preds[pos_index] > preds[neg_index]:
      				auc += 1
      			elif preds[pos_index] == preds[neg_index]:
      				auc += 0.5
      
      	return auc / (len(pos_indexes) * len(neg_indexes))
      
      
      if __name__ == '__main__':
      	y = np.array([1, 0, 0, 0, 1, 0, 1, 0, ])
      	pred = np.array([0.9, 0.8, 0.3, 0.1, 0.4, 0.9, 0.66, 0.7])
      
      	fpr, tpr, threadholds = roc_curve(y, pred, pos_label=1)
      	print('naive auc: {}'.format(naive_auc(y, pred)))
      	print('sklearn auc: {}'.format(auc(fpr, tpr)))
      
    • 优化一

      • 对预测概率从低到高排序
      • 对每一个概率值设rank值,最低的概率对应的rank值为1,最高的概率对应的rank值为n。rank值表示了该样本超过的样本个数,统计所有正样本的rank和,再减去其中超过正样本的个数:rank为n的正样本表示超过了n-1个样本,其中超过了m-1个正样本。我们只希望求得对于每一个正样本,其超过的负样本个数。在下述示例代码中,直接不统计超过的正样本数量。
      • 除以m*n

      对应的计算公式:

      [AUC=frac{sum_{iin pos}rank_i-frac{m(m+1)}{2}}{m*n} ]

    • 优化二

      另外还有将预测值分桶,对正负样本分别构建直方图,再满足条件的正负样本数,复杂度降为O(n)。参见:wepe/auc.py

      def approximate_auc(labels, preds, n_bins=100):
          '''
          近似方法,将预测值分桶,对正负样本分别构建直方图,再统计满足条件的正负样本对
          复杂度O(n)
          '''
          n_pos = sum(labels)
          n_neg = len(labels) - n_pos
          total_pair = n_pos * n_neg
      
          pos_histogram = [0 for _ in range(n_bins)]
          neg_histogram = [0 for _ in range(n_bins)]
          bin_width = 1. / n_bins
          for i in range(len(labels)):
              nth_bin = int(preds[i] / bin_width)
              if labels[i] == 1:
                  pos_histogram[nth_bin] += 1
              else:
                  neg_histogram[nth_bin] += 1
      
          accumulated_neg = 0
          satisfied_pair = 0
          for i in range(n_bins):
              satisfied_pair += (pos_histogram[i] * accumulated_neg + pos_histogram[i] * neg_histogram[i] * 0.5)
              accumulated_neg += neg_histogram[i]
      
          return satisfied_pair / float(total_pair)
      

      参见:

      python实现AUC

      AUC理解与实现

      wepe/auc.py

    • 对数损失

      对数损失(Logistic Loss, logloss)是对预测概率的似然估计,其标准形式为:

      [logloss=-logP(Y|X) ]

      对数损失最下化本质上是利用样本中的已知分布,求解导致这种分布的最佳模型参数,使这种分布出现的概率最大。

      对数损失对应的二分类的计算公式为:

      [logloss=-frac{1}{N}sum_{i=1}^{N}(ylogp_i+(1-y)log(1-p_i)) ]

      其中,(yin {0,1})(p_i)为第(i)个样本预测为1的概率。这实际就是逻辑回归的目标函数,由最大似然推导而来。

      对数损失对应的多分类计算公式:

      [logloss=-frac{1}{N}frac{1}{C}sum_{i=1}^{N}sum_{j=1}^Cy_{ij}logp_{ij} ]

      其中,N为样本数,C为类别数,(y_{ij}=1)表示第(i)个样本的类别为(j)(p_{ij})为第(i)个样本类别为(j)的概率。

      logloss衡量的是预测概率分布和真实概率分布的差异性,值越小越好。与AUC不同,logloss对预测概率值敏感。

    回归指标

    • 平均绝对误差(Mean Absolute Error, MAE)
      也称(L_1)范数损失((L_1-Norm loss)):

      [MAE=frac{1}{N}sum_{i=1}^{N}|y_i-p_i| ]

      其中,(N)为样本数,(y_i)为第(i)条样本的真实值,(p_i)是第(i)条样本的预测值。因为预测误差有正有负,绝对值可以避免正负抵消。
      模型使用MAE作为损失函数是对数据分布的中值进行拟合。
      某些模型如XGBoost要求损失函数有二阶导数,所以不可以用来直接优化MAE。
      加权平均绝对误差(Weighted Mean Absolute Error, WMAE)是基于MAE的变种,对每条样本考虑不同的权重,如考虑时间因素,离当前时间越久,样本权重越低。

      [WMAE=frac{1}{N}sum_{i=1}^Nw_i|y_i-p_i| ]

      其中,(w_i)是第(i)条样本的权重。

    • 平均绝对百分误差(Mean Absolute Percentage Error, MAPE)

      [MAPE=frac{100}{N}sum_{i=1}^{N}|frac{y_i-p_i}{y_i}|,quad y_i eq 0 ]

      MAPE计算绝对误差的百分比以表示预测效果,其取值越小越好。若MAPE=10,表明预测平均偏离真实值10%,MAPE与量纲无关

      MAPE的缺点也很明显:在(y_i=0)处无定义,并且如果(y_i)接近0可能导致MAPE大于100%。

    • 均方根误差(Root Mean Squared Error, RMSE)

      [RMSE=sqrt{frac{1}{N}sum_{i=1}^{N}(y_i-p_i)^2} ]

      RMSE表示预测值和真实值差异的样本标准差。和MAE相比,RMSE对大误差样本有更大的惩罚,但它对离群点敏感,健壮性不如MAE。

      模型使用RMSE作为损失函数是对数据分布的平均值进行拟合。

      基于均方根误差有一个常用的变种评估指标:均方根对数误差(Root Mean Squared Logarithmic Error, RMSLE):

      [RMSLE=sqrt{frac{1}{N}sum_{i=1}^N(log(y_i+1)-log(p_i+1))} ]

      RMSLE对预测值偏小的样本惩罚比对预测值偏大的样本惩罚更大。比如酒店均价是200元,预测成150元要比预测成250元的惩罚更大。如果希望使用RMSLE作为评估指标,对于没办法直接优化RMSLE但能直接优化RMSE的模型,通常会对预测目标进行对数变换(p_{new}=log(p+1)),最后预测值再还原(p=e^{p_{new}}-1)

    排序指标

    • 平均准确率均值(Mean Average Precision, MAP)

      计算公式分两个部分,先计算一次排序平均准确率,再计算总体的平均准确率。常用的MAP指标会限定评估排在前面的文档质量。

      [AP@K=frac{sum_{k=1}^{min(M,K)}P(k)×rel(k)}{min(M,K)}\ P(i)=frac{前i个结果中相关文档数量}{i} ]

      其中,(AP@K)表示计算前(K)个结果的平均准确率;(M)表示每次参与排序的文档总数,有可能一次返回文档数不足(K)个;(P(k))表示前(k)个结果的准确率;(rel(k))表示第(k)个结果是否是相关文档,相关文档返回1,否则返回0。

      [MAP@K=sum_{q=1}^Qfrac{AP_q@K}{Q} ]

      其中,(Q)为查询的数量;(AP_q@K)为第(q)次查询的(AP@K)的结果。

      示例:以黄色表示案例相关,白色表示案例不相关

      kRtt2T.md.png

      对于案例1,有(P(1)=frac{1}{1}=1,P(3)=frac{2}{3},p(5)=frac{3}{5}),K=5,M=3,则:

      [egin{split} AP@5&=frac{sum_{k=1}^{min(3,5)}P(k)×rel(k)}{min(3,5)}\ &=frac{1}{3}(1+frac{2}{3}+frac{3}{5})\ &approx 0.76 end{split} ]

      对于案例2,有(P(2)=frac{1}{2},P(4)=frac{2}{4}),则:

      [egin{split} AP@5&=frac{sum_{k=1}^{min(2,5)}P(k)×rel(k)}{min(2,5)}\ &=frac{1}{2}(frac{1}{2}+frac{2}{4})\ &=0.5 end{split} ]

      (Q=2)

      [egin{split} MAP@Q&=sum_{q=1}^2frac{AP_q@5}{2}\ &=frac{1}{2}(0.76+0.5)\ &=0.63 end{split} ]

      另外,比较重要的排序指标还有NDCG(Normalized Discounted Cumulative Gain, 归一化贴现累计收益)

  • 相关阅读:
    Java :BufferedWriter类和BufferedReader类的构造方法、主要方法
    多线程:四大线程池详解
    多线程:head first Thread.join()
    多线程: 多线程中断机制
    多线程:深入Thread.sleep
    多线程:线程池原理
    java:java构造器和java方法的区别
    java: Java中this和super的用法总结
    postman: 用于网页调试和发送Http请求的chrome插件
    json:JSONObject包的具体使用(JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包)
  • 原文地址:https://www.cnblogs.com/mengnan/p/10411333.html
Copyright © 2011-2022 走看看