估计构造的预测模型的性能,也称为模型评估,在机器学习中是至关重要的。这是因为实际上模型的实用程度取决于它的预测性能。模型评价方法不仅对判断训练后的模型的效用至关重要,而且它们还可以在首先达到该模型方面发挥重要作用。在一大类候选模型中挑选最终模型的过程称为模型选择ーー目前有一些流行的模型选择技术是基于模型评价方法进行的。接下来将介绍常用的分类模型中的评价方法,以及Python实现
在以下示例中,将对鸢尾花分类问题进行多个评价指标的估计
import numpy as np
from sklearn import datasets
from sklearn.metrics import accuracy_score, confusion_matrix, recall_score, precision_score, f1_score, roc_auc_score, classification_report
from sklearn.linear_model import LogisticRegression as LRR
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
X_train = iris.data
y_train = iris.target
X_train, X_test, y_train, y_test= train_test_split(iris.data, iris.target, random_state=100, test_size=0.2, stratify=iris.target)
print('X_train_shape: ' + str(X_train.shape) + '\nX_test_shape: ' + str(X_test.shape)+ '\ny_train_shape: ' + str(y_train.shape) + '\ny_test_shape: ' + str(y_test.shape) + '\n')
lrr = LRR(C=0.1)
y_test_pred = lrr.fit(X_train, y_train).predict(X_test)
print("Accuracy = {:.3f}".format(accuracy\_score(y\_test, y\_test\_pred)))
准确率(Accuracy):
其中:
是真正例的数量(模型正确预测为正类别的样本数)
是真负例的数量(模型正确预测为负类别的样本数)
是假正例的数量(模型错误预测为正类别的样本数)
是假负例的数量(模型错误预测为负类别的样本数)
准确率是正确预测的样本数与总样本数的比率
print("Confusion Matrix is\n {}".format(confusion\_matrix(y\_test, y\_test\_pred)))
混淆矩阵(Confusion Matrix)是一个二维矩阵,用于衡量分类模型在测试数据上的性能。在二分类问题中,混淆矩阵的形式如下:
同理也存在多分类混淆矩阵,本质上是对模型在不同类别上的性能进行矩阵化的表示
print("Macro Average Recall = {:.3f}".format(recall\_score(y\_test, y\_test\_pred, average='macro')))
宏平均召回率(Macro Average Recall):
其中:
是类别的总数
是第 个类别的真正例数量(模型正确预测为该类别的样本数)
是第 个类别的假负例数量(实际为该类别但模型错误预测为其他类别的样本数)
宏平均召回率是所有类别召回率的平均值,每个类别的权重相等
print("Macro Average Precision = {:.3f}".format(precision\_score(y\_test, y\_test\_pred, average='macro')))
宏平均精确度(Macro Average Precision):
其中:
是第 个类别的假正例数量(模型错误预测为该类别但实际为其他类别的样本数)
宏平均精确度是所有类别精确度的平均值,每个类别的权重相等
print("Macro Average F1 score = {:.3f}".format(f1\_score(y\_test, y\_test\_pred, average='macro')))
宏平均F1分数(Macro Average F1 Score):
宏平均F1分数是宏平均精确度和宏平均召回率的调和平均值
print("Macro Average ROC AUC = {:.3f}".format(roc\_auc\_score(y\_test, lrr.predict\_proba(X\_test), multi\_class='ovr', average='macro')))
宏平均ROC AUC(Macro Average ROC AUC):
其中:
是第 个类别的 曲线下面积
运行结果:
np.set_printoptions(precision=3)
# 打印每个类别召回率
print("Class-specific Recall = {}".format(recall_score(y_test, y_test_pred, average=None)))
# 打印每个类别精确度
print("Class-specific Precision = {}".format(precision_score(y_test, y_test_pred, average=None)))
# 打印每个类别F1分数
print("Class-specific F1 score = {}".format(f1_score(y_test, y_test_pred, average=None)))
# 生成完整的分类报告
print(classification_report(y_test, y_test_pred))
返回每个类别的模型评估值:
为了在交叉验证过程中使用上述提到的度量标准之一,可以将 cross_val_score 函数的 scoring 参数设置为一个代表度量标准的字符串
from sklearn.metrics import SCORERS
SCORERS.keys()
从 scikit-learn 库中导入 SCORERS 对象,输出包含了所有可用于模型评估的度量标准的字典
使用 roc_auc_ovr 来计算带有重新洗牌的分层 3 折交叉验证,以一对多(OvR)的方式计算分类数据集的
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import StratifiedKFold
K_fold = 3
strkfold = StratifiedKFold(n_splits=K_fold, shuffle=True, random_state=42)
lrr = LRR(C=0.1)
cv_scores = cross_val_score(lrr, X_train, y_train, cv=strkfold, scoring='roc_auc_ovr')
cv_scores
Scikit-learn 实现用于在交叉验证中监控多个评估指标:在评估预测模型时,通常希望监控多个评估指标。就交叉验证规则而言,cross_val_score 函数不允许通过其 scoring 参数监控多个指标。为了监控多个评估指标,我们可以使用 sklearn.model_selection 模块中的 cross_validate 类。然后,一种计算各种指标的方法是将 cross_validate 的 scoring 参数设置为一个表示感兴趣的指标的字符串列表
from sklearn.model_selection import cross_validate
from sklearn.metrics import make_scorer, accuracy_score, precision_score, recall_score, f1_score
lrr = LRR(C=0.1)
scoring_metrics = {
'accuracy': make_scorer(accuracy_score),
'precision_macro': make_scorer(precision_score, average='macro'),
'recall_macro': make_scorer(recall_score, average='macro'),
'f1_macro': make_scorer(f1_score, average='macro')
}
# 使用 cross_validate 执行交叉验证并计算多个指标
results = cross_validate(lrr, X_train, y_train, scoring=scoring_metrics, cv=3)
# 获取每个类别的评价指标
precision_macro_per_class = results['test_precision_macro']
recall_macro_per_class = results['test_recall_macro']
f1_macro_per_class = results['test_f1_macro']
# 打印每个类别的评价指标
for i in range(len(precision_macro_per_class)):
print(f"Class {i + 1} - Precision: {precision_macro_per_class[i]:.3f}, Recall: {recall_macro_per_class[i]:.3f}, F1: {f1_macro_per_class[i]:.3f}")
# 打印每个指标的平均值和标准差
for metric in scoring_metrics:
print(f"{metric}: Mean {results['test_' + metric].mean():.3f}, Std {results['test_' + metric].std():.3f}")
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~