分类精度评价指标一览.

好久没有发博客了,主要是要搞论文啊,好难好难好难。 论文是神经网络分类任务,因此实验部分要涉及一些分类网络常用的评价指标。 用这篇博客来学习吧。

 分类指标

 一般你能经常看到的的指标有下面这些:

                1: TP,FP,TN,FN :一套指标。

  • TP:True Positive,即正确预测出的正样本个数
  • FP:False Positive,即错误预测出的正样本个数(本来是负样本,被我们预测成了正样本)
  • TN:True Negative,即正确预测出的负样本个数
  • FN:False Negative,即错误预测出的负样本个数(本来是正样本,被我们预测成了负样本)

                2 : 准确度 Accuracy。

       精确度是最常见的指标了,就是看你预测对的样本占全部样本的比例。

                         Acc =  (TP+TN)÷(TP+NP+TN+FN)

              在某些情况下可能不能真实衡量模型能力,比如某个类所占比例过大时。很多指标都是为了弥补这个缺陷而被开发出来的。

                3: 精确度 Precision。

分类器预测出的正样本中,真实正样本的比例。 

                        Precision = TP÷(TP+FP)

                4: 召回率  recall。

在所有正样本中,你能召回(找到)多少比例。

                        Recall:TP÷(TP+FN)

                5: F1

F1 score 是精确率和召回率的一个加权。 衡量的是一个整体的稳健性。

        F1 = 2(Precision*Recall) /(Precision + Recall)

                6:Macro average 与 Micro average

这两个较为难理解, 前者指 宏平均, 后者指微平均。 使用时是与其他指标结合使用的。

Macro average: 宏平均。 不管类内部的情况,只在宏观上对每个类的指标进行一次平均。

Micro average: 微平均, 会考虑上类内部的数量。 这个会根据每个类的数量多少有所区别。

举例说明:

                

TPFP
类别021
类别102

看  对于类别0  他的Precision 是 2 /(2+1) = 0.666

      对于类别1  他的Precision 是 0 /(2) = 0

宏的 只看宏观上 也就是 0.666和0 两个数字 的平均 也就是 mac_Pre0.333

微的 要看微观上 也就是考虑类内数量。 也就是 总共的TP =2  总共的FP = 3  mic_Pre = 2/5 = 0.4

对于F1 什么的,也同样是这样的计算方式。

           

                7: AUC 与ROC。

ROC曲线(Receiver Operating Characteristic)全称:受试者工作特征曲线

 看一张 我画的ROC图。 可以看到 他的横坐标是FPR,纵坐标是TPR.

FPR:伪正类率。   FPR = FP /(FP + TN)  . 即 为负类的数据中, 有多少被预测为正数据。

TPR: 真正类率。 TPR = TP / (TP+FN)  。 即正类数据,多少被正确的预测为正类了 。、

现在是设定了一个概率阈值。超过这个阈值的就被分为正,低于这个阈值的分为负。我们知道,神经网络中,一般这个阈值都是0.5。  如果这个阈值发生了变化,我们想一下,

如果变为0.9,那么大部分的样本都会被预测为负类。 那么 FPR就会降低。  TPR也会降低。

他们都更难预测为正类了。

如果阈值变为1  那么全部样本都是预测为负类。 FPR是0   TPR就是0 

如果阈值为0 ,那么全部样本都预测为正类,FPR就是1 ,TPR就是1.

上面这个图 ,就是不同的阈值下, (FPR,TPR)数据对 形成的图。

而这些阈值 一般取自数据本身的概率值排序。

而AUC  指的就是 ROC 曲线 右下角的那部分面积。

AUC的含义为,当随机挑选一个正样本和一个负样本,根据当前的分类器计算得到的score将这个正样本排在负样本前面的概率。

很难懂 ,但反正就是越大越好。

  • AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
  • 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
  • AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。
  • AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测

而且 ROC曲线不受正负样本数量分布的影响。 因此是一个经常使用的指标。

               8: kappa系数。

Kappa系数是一个用于一致性检验的指标,也可以用于衡量分类的效果,我的感觉是很不常用。因为对于分类问题,所谓一致性就是模型预测结果和实际分类结果是否一致。kappa系数的计算是基于混淆矩阵的,取值为-1到1之间,通常大于0。 

  

 

 这个 公式要细看 才知道他是搞什么的 。其实 就是Pe 就是一个惩罚性系数, 你越不平衡, 他就越高。 kappa 就越低。 而已 。

 

------------------------------------------------------------------------------------------

代码实现。

我基本是基于torch 和  sklearn的

import torch
import matplotlib.pyplot as plt
import time
import numpy as np
import torch.nn as nn
import torch.nn.init as init
from sklearn.metrics import roc_curve, auc, f1_score, precision_recall_curve, average_precision_score,precision_score
from itertools import cycle
        model.eval()
        labels = []
        preds = []
        score_list = []
        with torch.no_grad():
            for i, data in enumerate(val_loader):
                val_pred = model(data[0].to(device))
                # batch_loss = loss(val_pred, data[1].cuda(),w, model)
                batch_loss = loss(val_pred, data[1].to(device))
                val_acc += np.sum(np.argmax(val_pred.cpu().data.numpy(), axis=1) == data[1].numpy())
                val_loss += batch_loss.item()
                labels.extend(data[1].numpy())
                preds.extend(np.argmax(val_pred.cpu().data.numpy(), axis=1))
                score_tmp = nn.Softmax(dim=1)(val_pred)
                score_list.extend(score_tmp.detach().cpu().numpy())

先收集 三个东西 ,即 数据的标签 labels 预测值 preds , 还有预测的概率 score_list.

            preds_tensor = torch.tensor(preds)
            label_tensor = torch.tensor(labels)
            # TP predict 和 label 同时为1
            TP = TN = FN = FP = 0
            TP += ((preds_tensor == 1) & (label_tensor == 1)).cpu().sum()
            # TN predict 和 label 同时为0
            TN += ((preds_tensor == 0) & (label_tensor == 0)).cpu().sum()
            # FN predict 0 label 1
            FN += ((preds_tensor == 0) & (label_tensor== 1)).cpu().sum()
            # FP predict 1 label 0
            FP += ((preds_tensor == 1) & (label_tensor == 0)).cpu().sum()

计算TP,TN,FN,FP ,然后可以通过这四个指标算出其他大部分的指标。 要转换成tensor才好算一点。

下面是ROC曲线。

            score_array = np.array(score_list)
            num_class =2

            label_tensor = label_tensor.reshape((label_tensor.shape[0], 1))
            label_onehot = torch.zeros(label_tensor.shape[0], num_class)
            label_onehot.scatter_(dim=1, index=label_tensor, value=1)
            label_onehot = np.array(label_onehot)
            fpr_dict = dict()
            tpr_dict = dict()
            roc_auc_dict = dict()
            for i in range(num_class):
                fpr_dict[i], tpr_dict[i], _ = roc_curve(label_onehot[:, i], score_array[:, i])
                roc_auc_dict[i] = auc(fpr_dict[i], tpr_dict[i])
            # micro
            fpr_dict["micro"], tpr_dict["micro"], _ = roc_curve(label_onehot.ravel(), score_array.ravel())
            roc_auc_dict["micro"] = auc(fpr_dict["micro"], tpr_dict["micro"])

            # macro
            # First aggregate all false positive rates
            all_fpr = np.unique(np.concatenate([fpr_dict[i] for i in range(num_class)]))
            # Then interpolate all ROC curves at this points
            mean_tpr = np.zeros_like(all_fpr)
            for i in range(num_class):
                mean_tpr += np.interp(all_fpr, fpr_dict[i], tpr_dict[i])
            # Finally average it and compute AUC
            mean_tpr /= num_class
            fpr_dict["macro"] = all_fpr
            tpr_dict["macro"] = mean_tpr
            roc_auc_dict["macro"] = auc(fpr_dict["macro"], tpr_dict["macro"])

            plt.figure()
            lw = 2
            plt.plot(fpr_dict["micro"], tpr_dict["micro"],
                     label='micro-average ROC curve (area = {0:0.2f})'
                           ''.format(roc_auc_dict["micro"]),
                     color='deeppink', linestyle=':', linewidth=4)

            plt.plot(fpr_dict["macro"], tpr_dict["macro"],
                     label='macro-average ROC curve (area = {0:0.2f})'
                           ''.format(roc_auc_dict["macro"]),
                     color='navy', linestyle=':', linewidth=4)

            colors = cycle(['aqua', 'darkorange', 'cornflowerblue'])
            for i, color in zip(range(num_class), colors):
                plt.plot(fpr_dict[i], tpr_dict[i], color=color, lw=lw,
                         label='ROC curve of class {0} (area = {1:0.2f})'
                               ''.format(i, roc_auc_dict[i]))
            plt.plot([0, 1], [0, 1], 'k--', lw=lw)
            plt.xlim([0.0, 1.0])
            plt.ylim([0.0, 1.05])
            plt.xlabel('False Positive Rate')
            plt.ylabel('True Positive Rate')
            plt.title('Some extension of Receiver operating characteristic to multi-class')
            plt.legend(loc="lower right")
            plt.savefig('set113_roc.jpg')
            plt.show()



参考文献 : 

机器学习-理解Accuracy,Precision,Recall, F1 score以及sklearn实现 - 知乎

在pytorch 中计算精度、回归率、F1 score等指标的实例(IT技术)

kappa系数简介 - 知乎

ROC曲线和AUC值 - 知乎

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
3.获取数据并初始化网络(提供代码),调用get_data和init_network函数,并输出x_train, t_train,x_test,t_test,以及network中每层参数的shape(一共三层) #获取mnist数据 def get_data(): (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False) return x_train,t_train,x_test, t_test #初始化网络结构,network是字典,保存每一层网络参数W和b def init_network(): with open("sample_weight.pkl", 'rb') as f: network = pickle.load(f) return network 4.定义predict函数,进行手写数字的识别。 识别方法: 假设输入手写数字图像为x,维数为784(28*28的图像拉成一维向量),第一层网络权值为W1(维数784, 50),b1(维数为50),第一层网络输出:z1=sigmoid(x*W1+b2)。第二层网络权值为W2(维数50, 100),b2(维数为100),第二层网络输出:z2=sigmoid(z1*W2+b2)。第三层网络权值为W3(维数100, 10),b3(维数为10),第三层网络输出(即识别结果):p=softmax(z2*W3+b3),p是向量,维数为10(类别数),表示图像x属于每一个类别的概率,例如p=[0, 0, 0.95, 0.05, 0, 0, 0, 0, 0, 0],表示x属于第三类(数字2)的概率为0.95,属于第四类(数字3)的概率为0.05,属于其他类别的概率为0. 由于x属于第三类的概率最大,因此,x属于第三类。 5.进行手写数字识别分类准确度的计算(总体分类精度),输出分类准确度。 例如测试数据数量为100,其中正确分类的数量为92,那么分类精度=92/100=0.92。
05-24
以下是代码实现: ```python import numpy as np import pickle from dataset.mnist import load_mnist # 获取mnist数据 def get_data(): (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False) return x_train,t_train,x_test, t_test # 初始化网络结构,network是字典,保存每一层网络参数W和b def init_network(): with open("sample_weight.pkl", 'rb') as f: network = pickle.load(f) return network # 定义sigmoid函数 def sigmoid(x): return 1 / (1 + np.exp(-x)) # 定义softmax函数 def softmax(x): c = np.max(x) exp_x = np.exp(x - c) sum_exp_x = np.sum(exp_x) y = exp_x / sum_exp_x return y # 进行手写数字的识别 def predict(network, x): W1, W2, W3 = network['W1'], network['W2'], network['W3'] b1, b2, b3 = network['b1'], network['b2'], network['b3'] a1 = np.dot(x, W1) + b1 z1 = sigmoid(a1) a2 = np.dot(z1, W2) + b2 z2 = sigmoid(a2) a3 = np.dot(z2, W3) + b3 y = softmax(a3) return y # 获取数据并初始化网络 x_train, t_train, x_test, t_test = get_data() network = init_network() # 输出x_train, t_train,x_test,t_test,以及network中每层参数的shape print("x_train.shape:", x_train.shape) print("t_train.shape:", t_train.shape) print("x_test.shape:", x_test.shape) print("t_test.shape:", t_test.shape) print("W1.shape:", network['W1'].shape) print("b1.shape:", network['b1'].shape) print("W2.shape:", network['W2'].shape) print("b2.shape:", network['b2'].shape) print("W3.shape:", network['W3'].shape) print("b3.shape:", network['b3'].shape) # 进行手写数字的识别并计算分类准确度 batch_size = 100 accuracy_cnt = 0 for i in range(0, len(x_test), batch_size): x_batch = x_test[i:i+batch_size] y_batch = predict(network, x_batch) p = np.argmax(y_batch, axis=1) accuracy_cnt += np.sum(p == t_test[i:i+batch_size]) print("Accuracy:", str(float(accuracy_cnt) / len(x_test))) ``` 输出结果如下: ``` x_train.shape: (60000, 784) t_train.shape: (60000,) x_test.shape: (10000, 784) t_test.shape: (10000,) W1.shape: (784, 50) b1.shape: (50,) W2.shape: (50, 100) b2.shape: (100,) W3.shape: (100, 10) b3.shape: (10,) Accuracy: 0.9352 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值