模型评估方法

一、导入第三方库

导入相关第三方库,以及设置横纵坐标属性

import numpy as np
import os
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
import warnings
warnings.filterwarnings('ignore')
np.random.seed(42)

二、读取数据集

Mnist数据是图像数据:(28,28,1)的灰度图

from sklearn.datasets import fetch_openml
mnist = fetch_openml('mnist_784')
mnist
X,y = mnist['data'], mnist['target']
X.shape 
# 输出 (70000, 784)
# (70000 数据集中共70000个样本  每个样本为28*28大小 即 784)
y.shape
# 输出(70000,)

bilstm模型及评估指标代码python python 模型评估_python

三、数据集切分

X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:] # 选择前6万个样本作为训练集 ,之后的样本作为测试集

由于样本中是按照数字的顺序进行排列,为了减少样本顺序对模型训练的影响,保证样本的独立性,需要对样本进行洗牌操作。

# 洗牌操作
import numpy as np

shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]
shuffle_index

洗牌后的样本索引

bilstm模型及评估指标代码python python 模型评估_交叉验证_02

四、交叉验证

bilstm模型及评估指标代码python python 模型评估_人工智能_03


bilstm模型及评估指标代码python python 模型评估_交叉验证_04

y_train_5 = (y_train == 5)
y_test_5 = (y_test == 5)
y_train_5[:10]

bilstm模型及评估指标代码python python 模型评估_python_05


True:当前的值是5 False:当前的值不是5

from sklearn.linear_model import SGDClassifier
# 初始化分类器
sgd_clf = SGDClassifier(max_iter=5,random_state=42) # max_iter最大的迭代次数 random_state 随机种子
sgd_clf.fit(X_train,y_train_5)

bilstm模型及评估指标代码python python 模型评估_召回率_06

sgd_clf.predict([X[35000]]) # array([ True]) predict()函数传入测试集的值
y[35000] # 5.0
交叉验证实验分析
方法一:调用
from sklearn.model_selection import cross_val_score
cross_val_score(sgd_clf,X_train,y_train_5,cv=3,scoring='accuracy')
# cv=3 交叉验证3次 计算准确度
# 输出 array([0.9502 , 0.96565, 0.96495])
方法二:手动实现
from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone # 划分数据集

skflods = StratifiedKFold(n_splits=3,random_state=42)
for train_index,test_index in skflods.split(X_train,y_train_5):
    clone_clf = clone(sgd_clf)
    X_train_folds = X_train[train_index]
    y_train_folds = y_train_5[train_index]
    X_test_folds = X_train[test_index]
    y_test_folds = y_train_5[test_index]
    
    clone_clf.fit(X_train_folds,y_train_folds)
    # 计算准确度
    y_pred = clone_clf.predict(X_test_folds)
    n_correct = sum(y_pred == y_test_folds)
    print(n_correct/len(y_pred))
# 输出   0.9502
		0.96565
		0.96495

五、混淆矩阵

bilstm模型及评估指标代码python python 模型评估_python_07

实验分析
from sklearn.model_selection import cross_val_predict
y_train_pred = cross_val_predict(sgd_clf,X_train,y_train_5,cv=3)
y_train_pred.shape # 输出(60000,)
X_train.shape # 输出(60000, 784)
from sklearn.metrics import confusion_matrix
confusion_matrix(y_train_5,y_train_pred)

bilstm模型及评估指标代码python python 模型评估_人工智能_08

实验结果

bilstm模型及评估指标代码python python 模型评估_召回率_09

六、Precision and Recall

bilstm模型及评估指标代码python python 模型评估_交叉验证_10


bilstm模型及评估指标代码python python 模型评估_召回率_11


在sklearn中,有现成的计算精确度、召回率、F1值得方法

from sklearn.metrics import precision_score,recall_score
precision_score(y_train_5,y_train_pred)
# 输出0.7687135020350381
recall_score(y_train_5,y_train_pred)
# 输出0.801328168234643
from sklearn.metrics import f1_score
f1_score(y_train_5,y_train_pred)
# 输出0.7846820809248555

PrecisionRecall结合到一个称为F1 score 的指标,调和平均值给予低值更多权重。 因此,如果召回和精确度都很高,分类器将获得高F1分数。

bilstm模型及评估指标代码python python 模型评估_交叉验证_12

七、阈值对结果的影响

阈值越底,得到的结果精度越底,召回率越高;

阈值越高,得到的结果精度越高,召回率越低。

bilstm模型及评估指标代码python python 模型评估_交叉验证_13

y_scores = sgd_clf.decision_function([X[35000]])
y_scores # 输出array([43349.73739616])
t = 50000
y_pred = (y_scores > t)
y_pred # 输出array([False])

Scikit-Learn不允许直接设置阈值,但它可以得到决策分数,调用其decision_function()方法,而不是调用分类器的predict()方法,该方法返回每个实例的分数,然后使用想要的阈值根据这些分数进行预测:

y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,
                             method="decision_function")
y_scores[:10]  
# 输出
array([ -434076.49813641, -1825667.15281624,  -767086.76186905,
        -482514.55006702,  -466416.8082872 ,  -311904.74603814,
        -582112.5580173 ,  -180811.15850786,  -442648.13282116,
         -87710.09830358])
from sklearn.metrics import precision_recall_curve
precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)
y_train_5.shape # 输出(60000,)
thresholds.shape # 输出(59698,)
precisions[:10] 
# 输出
array([0.09080706, 0.09079183, 0.09079335, 0.09079487, 0.09079639,
       0.09079792, 0.09079944, 0.09080096, 0.09080248, 0.090804  ])
precisions.shape # (59699,)
recalls.shape # (59699,)
def plot_precision_recall_vs_threshold(precisions,recalls,thresholds):
    plt.plot(thresholds,
             precisions[:-1],
            "b--",
            label="Precision")
    
    plt.plot(thresholds,
             recalls[:-1],
            "g-",
            label="Recall")
    plt.xlabel("Threshold",fontsize=16)
    plt.legend(loc="upper left",fontsize=16)
    plt.ylim([0,1])
    
plt.figure(figsize=(8, 4))
plot_precision_recall_vs_threshold(precisions,recalls,thresholds)
plt.xlim([-700000, 700000])
plt.show()

bilstm模型及评估指标代码python python 模型评估_交叉验证_14

def plot_precision_vs_recall(precisions, recalls):
    plt.plot(recalls, 
             precisions, 
             "b-", 
             linewidth=2)
    
    plt.xlabel("Recall", fontsize=16)
    plt.ylabel("Precision", fontsize=16)
    plt.axis([0, 1, 0, 1])

plt.figure(figsize=(8, 6))
plot_precision_vs_recall(precisions, recalls)
plt.show()

bilstm模型及评估指标代码python python 模型评估_交叉验证_15

八、ROC curves

receiver operating characteristic (ROC) 曲线是二元分类中的常用评估方法

  • 它与精确度/召回曲线非常相似,但ROC曲线不是绘制精确度与召回率,而是绘制true positive rate(TPR)false positive rate(FPR)
  • 要绘制ROC曲线,首先需要使用roc_curve()函数计算各种阈值的TPR和FPR

TPR = TP / (TP + FN) (Recall)

FPR = FP / (FP + TN)

from sklearn.metrics import roc_curve
fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)

def plot_roc_curve(fpr, tpr, label=None):
    plt.plot(fpr, tpr, linewidth=2, label=label)
    plt.plot([0, 1], [0, 1], 'k--')
    plt.axis([0, 1, 0, 1])
    plt.xlabel('False Positive Rate', fontsize=16)
    plt.ylabel('True Positive Rate', fontsize=16)

plt.figure(figsize=(8, 6))
plot_roc_curve(fpr, tpr)
plt.show()

bilstm模型及评估指标代码python python 模型评估_数据集_16

虚线表示纯随机分类器的ROC曲线; 一个好的分类器尽可能远离该线(朝左上角)。

比较分类器的一种方法是测量曲线下面积(AUC)。完美分类器的ROC AUC等于1,而纯随机分类器的ROC AUC等于0.5。 Scikit-Learn提供了计算ROC AUC的函数:

from sklearn.metrics import roc_auc_score
roc_auc_score(y_train_5, y_scores)
# 输出 0.9624496555967156