多类分类(Multi-label classification)性能评价之宏平均(macro-average)与微平均(micro-average)

本文介绍了在多类分类任务中,仅使用accuracy评估分类器性能的不足,并详细阐述了宏平均(macro-average)和微平均(micro-average)的概念。宏平均是各类别的F1值的算术平均,而微平均则关注总体预测正确的样本数量。通过实例解释了两者之间的区别,指出宏平均在类别分布不均衡时更能体现分类器的性能,而微平均则更侧重整体预测的准确性。

通常,我们在评价classifier的性能时使用的是accuracy

考虑在多类分类的背景下

accuracy = (分类正确的样本个数) / (分类的所有样本个数)

这样做其实看上去也挺不错的,不过可能会出现一个很严重的问题:例如某一个不透明的袋子里面装了1000台手机,其中有600台iphone6, 300台galaxy s6, 50台华为mate7,50台mx4(当然,这些信息分类器是不知道的。。。)。如果分类器只是简单的把所有的手机都预测为iphone6, 那么通过上面的公式计算的准确率accuracy为0.6,看起来还不错;可是三星,华为和小米的全部预测错了。如果再给一个袋子,里面装着600台galaxy s6, 300台mx4, 50台华为mate7,50台iphone,那这个分类器立马就爆炸了,连回家带孩子的要求都达不到

所以,仅仅用accuracy来衡量一个分类器的性能是很不科学的

为此,引入了宏平均(micro-average)的概念

介绍宏平均之前,还要介绍几个概念:

(1)precision(准确率,查准率)

(2)recall(召回率,查全率)

(3)F-measure

文字性的概念我就不水,我从符号上来表示一下吧:

多类分类问题中,分类结果一般有4种情况:

  • 属于类C的样本被正确分类到类C,记这一类样本数为 TP
  • 不属于类C的样本被错误分类到类C,记这一类样本数为 FP
  • 属于类别C的样本被错误分类到类C的其他类,记这一类样本数为 TN
  • 不属于类别C的样本被正确分类到了类别C的其他类,记这一类样本数为 FN                     

从字面意思上来说,某一类别C的准确率(查准率)可以理解为预测该类样本的准确性:

<

### 多分类问题中的 ROC 和 AUC 在多分类问题中,传统的二分类 ROC 曲线和 AUC 需要扩展到多个类别上。通常的做法是通过一对多(One-vs-Rest, OvR)或一对一(One-vs-One, OvO)策略来处理多分类问题。 #### One-vs-Rest (OvR) 方法 在这种方法下,每个类别的样本被标记为正类,而其他所有类别的样本则被视为负类。这样可以构建 \( C \) 条独立的 ROC 曲线(\( C \) 是类别总数)。每条曲线对应于一个特定类别的性能表现[^1]。 对于每一类,计算其对应的 TPR(True Positive Rate)和 FPR(False Positive Rate),并绘制相应的 ROC 曲线。最终可以通过平均这些单类别的 AUC 值得到整体的 AUC 表现: \[ AUC_{macro} = \frac{1}{C} \sum_{i=1}^{C} AUC_i \] 其中,\( AUC_i \) 表示第 \( i \) 类别下的 AUC 值[^2]。 #### Micro 平均Micro 平均法则是在全局范围内统计真正例数(TP)、假正例数(FP)和真反例数(TN),从而统一计算整个数据集上的 TPR 和 FPR。这种方法不区分具体类别,而是将所有预测结果汇总在一起进行分析。这种方式更适合关注总体错误率的应用场景[^3]。 以下是基于 Python 的 `scikit-learn` 实现多分类 ROC-AUC 的代码示例: ```python from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.preprocessing import label_binarize from sklearn.multiclass import OneVsRestClassifier from sklearn.linear_model import LogisticRegression from sklearn.metrics import roc_curve, auc, roc_auc_score import matplotlib.pyplot as plt from itertools import cycle import numpy as np # 创建模拟数据集 X, y = make_classification(n_samples=1000, n_classes=3, n_informative=3, random_state=42) # 将标签转换为 one-hot 编码形式 y_bin = label_binarize(y, classes=[0, 1, 2]) n_classes = y_bin.shape[1] # 划分训练集测试集 X_train, X_test, y_train, y_test = train_test_split(X, y_bin, test_size=.5, random_state=42) # 使用逻辑回归作为基础分类器 classifier = OneVsRestClassifier(LogisticRegression()) y_score = classifier.fit(X_train, y_train).predict_proba(X_test) # 计算平均 ROC 曲线和 AUC fpr_micro, tpr_micro, _ = roc_curve(y_test.ravel(), y_score.ravel()) auc_micro = auc(fpr_micro, tpr_micro) # 计算平均 ROC 曲线和 AUC fpr = dict() tpr = dict() roc_auc = dict() for i in range(n_classes): fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i]) roc_auc[i] = auc(fpr[i], tpr[i]) all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)])) mean_tpr = np.zeros_like(all_fpr) for i in range(n_classes): mean_tpr += np.interp(all_fpr, fpr[i], tpr[i]) mean_tpr /= n_classes fpr_macro = all_fpr tpr_macro = mean_tpr auc_macro = auc(fpr_macro, tpr_macro) plt.figure(figsize=(8, 6)) # 绘制平均 ROC 曲线 plt.plot(fpr_micro, tpr_micro, label=f'Micro-average ROC curve (area = {auc_micro:.2f})', color='deeppink') # 绘制平均 ROC 曲线 plt.plot(fpr_macro, tpr_macro, label=f'Macro-average ROC curve (area = {auc_macro:.2f})', color='navy') # 添加对角线基线和其他设置 plt.plot([0, 1], [0, 1], 'k--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver Operating Characteristic for multi-class data') plt.legend(loc="lower right") plt.show() ``` 上述代码展示了如何利用 `scikit-learn` 库实现多分类问题中的 ROC 和 AUC 计算,并分别给出了 MacroMicro 平均的结果可视化。 ---
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值