news 2026/6/2 18:19:41

Macro、Micro、Weighted F1傻傻分不清?一篇用Python代码和例子讲透sklearn的f1_score

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Macro、Micro、Weighted F1傻傻分不清?一篇用Python代码和例子讲透sklearn的f1_score

Macro、Micro、Weighted F1:用Python代码彻底讲透多分类评估指标

刚接触机器学习分类任务时,我们常常被各种评估指标搞得晕头转向。特别是当数据集中各类别样本数量不均衡时,传统准确率可能完全失效。这时候F1分数及其变体就显得尤为重要,但macro、micro、weighted这些参数到底有什么区别?让我们用实际代码和可视化来彻底搞懂它们。

1. 构建不平衡数据集:猫狗兔分类案例

为了直观理解不同F1分数的区别,我们先创建一个简单的三分类数据集。假设我们有一个图片分类任务,需要区分猫、狗和兔子,但数据分布极不均衡:

import numpy as np from sklearn.metrics import f1_score, confusion_matrix import seaborn as sns import matplotlib.pyplot as plt # 模拟真实标签:0=猫,1=狗,2=兔子 y_true = np.array([0]*70 + [1]*20 + [2]*10) # 共100个样本:70猫,20狗,10兔 # 模拟预测结果:模型对多数类(猫)表现好,对少数类(兔子)表现差 y_pred = np.array( [0]*65 + [1,2,0,0,0] + # 猫样本:65正确,5个错误 [1]*15 + [0]*3 + [2]*2 + # 狗样本:15正确,5个错误 [2]*4 + [0]*4 + [1]*2 # 兔样本:4正确,6个错误 ) print("类别分布:", {0: "猫", 1: "狗", 2: "兔"}) print("各类样本数:", {0: sum(y_true==0), 1: sum(y_true==1), 2: sum(y_true==2)})

输出结果:

类别分布: {0: '猫', 1: '狗', 2: '兔'} 各类样本数: {0: 70, 1: 20, 2: 10}

让我们先看看混淆矩阵:

def plot_confusion_matrix(y_true, y_pred): cm = confusion_matrix(y_true, y_pred) plt.figure(figsize=(8,6)) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['猫','狗','兔'], yticklabels=['猫','狗','兔']) plt.xlabel('预测标签') plt.ylabel('真实标签') plt.title('混淆矩阵') plt.show() plot_confusion_matrix(y_true, y_pred)

从混淆矩阵可以直观看出:

  • 猫(多数类)的预测准确率很高
  • 狗(中等数量)的预测还算可以
  • 兔子(少数类)的预测效果很差

2. 三种F1分数的计算原理

2.1 基础概念回顾

在深入三种F1分数前,先快速回顾几个关键指标:

  • 精确率(Precision):预测为正的样本中实际为正的比例

    Precision = TP / (TP + FP)
  • 召回率(Recall):实际为正的样本中被预测为正的比例

    Recall = TP / (TP + FN)
  • F1分数:精确率和召回率的调和平均数

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

2.2 Macro-F1:平等对待每个类别

Macro-F1计算每个类别的F1分数后直接取算术平均,不考虑各类别的样本数量差异。

macro_f1 = f1_score(y_true, y_pred, average='macro') print(f"Macro-F1: {macro_f1:.4f}")

计算过程:

  1. 分别计算猫、狗、兔的F1分数
  2. 将三个F1分数相加后除以3

特点

  • 平等对待所有类别
  • 少数类的表现对最终结果影响与大类别相同
  • 适用于各类别重要性相当的情况

2.3 Micro-F1:基于全体样本统计

Micro-F1先汇总所有类别的TP、FP、FN,然后计算全局F1分数。

micro_f1 = f1_score(y_true, y_pred, average='micro') print(f"Micro-F1: {micro_f1:.4f}")

计算过程:

  1. 汇总所有类别的TP、FP、FN
  2. 用汇总值计算全局精确率和召回率
  3. 计算F1分数

特点

  • 受大类别影响大
  • 实际上等同于准确率(Accuracy)在多分类中的扩展
  • 适用于关注整体预测正确率的情况

2.4 Weighted-F1:按样本量加权平均

Weighted-F1根据每个类别的样本数量对F1分数进行加权平均。

weighted_f1 = f1_score(y_true, y_pred, average='weighted') print(f"Weighted-F1: {weighted_f1:.4f}")

计算过程:

  1. 计算每个类别的F1分数
  2. 根据各类别样本数占总样本比例赋予权重
  3. 计算加权平均值

特点

  • 大类别对结果影响更大
  • 是Macro-F1的加权版本
  • 适用于类别重要性与其样本量相关的情况

3. 三种F1分数的对比分析

让我们同时计算三种F1分数并比较:

from sklearn.metrics import classification_report print(classification_report(y_true, y_pred, target_names=['猫','狗','兔'])) print("\n三种F1分数对比:") print(f"Macro-F1: {f1_score(y_true, y_pred, average='macro'):.4f}") print(f"Micro-F1: {f1_score(y_true, y_pred, average='micro'):.4f}") print(f"Weighted-F1: {f1_score(y_true, y_pred, average='weighted'):.4f}")

输出结果:

precision recall f1-score support 猫 0.88 0.93 0.90 70 狗 0.75 0.75 0.75 20 兔 0.50 0.40 0.44 10 accuracy 0.84 100 macro avg 0.71 0.69 0.70 100 weighted avg 0.83 0.84 0.83 100 三种F1分数对比: Macro-F1: 0.6979 Micro-F1: 0.8400 Weighted-F1: 0.8333

3.1 结果差异解读

指标说明
Macro-F10.698三个类别的F1分数简单平均,兔子表现差拉低了分数
Micro-F10.840等同于整体准确率,受猫的高准确率影响大
Weighted-F10.833考虑了样本量权重,接近Micro但保留了各类别差异信息

关键发现

  • Macro-F1最低,因为它平等对待了表现差的兔子类别
  • Micro-F1和Weighted-F1接近,但计算原理不同
  • 对于不平衡数据,Macro和Weighted通常比Micro更有参考价值

4. 如何选择合适的F1计算方式

4.1 选择标准

场景推荐方法原因
各类别同等重要Macro-F1不偏袒任何类别
大类别更重要Weighted-F1按样本量加权
关注整体正确率Micro-F1等同于准确率
极端不平衡数据Macro-F1防止忽视小类别

4.2 实际应用建议

  1. 医疗诊断(少数病例很重要):

    • 优先使用Macro-F1,确保罕见病不被忽视
    • 示例代码:
      # 医疗场景推荐 medical_f1 = f1_score(y_true, y_pred, average='macro')
  2. 电商推荐(热门商品更重要):

    • 使用Weighted-F1,反映实际销售分布
    • 示例代码:
      # 电商场景推荐 ecommerce_f1 = f1_score(y_true, y_pred, average='weighted')
  3. 平衡数据集

    • 三种方法结果相似,可任选
    • 示例代码:
      # 平衡数据时差异小 balanced_f1_macro = f1_score(y_true_balanced, y_pred_balanced, average='macro') balanced_f1_weighted = f1_score(y_true_balanced, y_pred_balanced, average='weighted')

4.3 综合评估最佳实践

在实际项目中,建议同时计算多种指标:

from sklearn.metrics import precision_score, recall_score metrics = { 'Accuracy': accuracy_score(y_true, y_pred), 'Macro Precision': precision_score(y_true, y_pred, average='macro'), 'Macro Recall': recall_score(y_true, y_pred, average='macro'), 'Macro F1': f1_score(y_true, y_pred, average='macro'), 'Weighted F1': f1_score(y_true, y_pred, average='weighted') } for name, value in metrics.items(): print(f"{name}: {value:.4f}")

提示:永远不要只依赖单一指标评估模型,特别是在数据不平衡时。结合混淆矩阵和多种指标才能全面评估模型性能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 18:17:03

Arduino继电器控制入门:用旋钮改造传统雪球玩具

1. 项目概述:当传统玩具遇上开源硬件几年前,我在整理旧物时翻出了一个尘封的雪球玩具。按下开关,里面的小雪花会随着音乐缓缓飘落,但除了这个单一的触发动作,它似乎再没有其他可能性。这让我萌生了一个想法&#xff1a…

作者头像 李华
网站建设 2026/6/2 18:14:17

为啥高大厂房都标配工业折叠门?核心特点在这里

现在的高大厂房、大型仓库、重工车间,基本都会优先标配工业折叠门,早已替代传统平开门、推拉门和卷帘门,成为大空间工业厂房的主流选择,核心原因是它完美适配高大厂房的特殊使用需求,实用性、适配性远超普通工业门。工…

作者头像 李华
网站建设 2026/6/2 18:14:15

基于Attiny13A的PCB艺术徽章制作:从设计到编程全流程

1. 项目概述:当PCB遇上动漫,打造一枚会呼吸的徽章如果你和我一样,既是个电子爱好者,又对《龙珠》里的角色情有独钟,那你肯定能理解我想把这两者结合起来的冲动。这次的项目,就是一枚以“魔人贝吉塔”为主题…

作者头像 李华
网站建设 2026/6/2 18:11:20

手把手教你部署用友U8 HTTP接口(.NET 4.8/4.6环境,含Redis配置避坑点)

手把手教你部署用友U8 HTTP接口(.NET 4.8/4.6环境,含Redis配置避坑点)在企业数字化转型过程中,ERP系统的接口集成往往是技术实施的关键环节。用友U8作为国内广泛应用的ERP解决方案,其标准接口在实际开发中常遇到兼容性…

作者头像 李华