别再傻傻分不清了!用Python代码实战带你搞懂准确率、精确率、召回率和F1分数
用Python代码实战解析分类模型四大核心指标在数据科学项目中评估分类模型性能是至关重要的一环。很多初学者虽然能背诵准确率、精确率、召回率和F1分数的定义但当面对实际数据集时仍然会困惑于这些指标的具体计算方式和应用场景。本文将通过Python代码实战带你从数据加载到指标计算彻底掌握这些核心评估指标。1. 理解基础概念与混淆矩阵在开始编码前我们需要明确几个关键术语。分类模型的预测结果可以归纳为四种情况from sklearn.metrics import confusion_matrix # 假设我们有以下真实标签和预测结果 y_true [1, 0, 1, 1, 0, 1, 0, 0] y_pred [1, 0, 0, 1, 0, 1, 1, 0] # 生成混淆矩阵 tn, fp, fn, tp confusion_matrix(y_true, y_pred).ravel() print(f真负例(TN): {tn}, 假正例(FP): {fp}, 假负例(FN): {fn}, 真正例(TP): {tp})这四种情况构成了混淆矩阵的基础实际\预测预测为正例预测为负例实际为正例TPFN实际为负例FPTN理解这个矩阵是计算所有指标的基础。让我们通过一个垃圾邮件分类的例子来具体说明TP(真正例)确实是垃圾邮件且被正确分类为垃圾邮件FP(假正例)正常邮件被误判为垃圾邮件FN(假负例)垃圾邮件被漏判为正常邮件TN(真负例)正常邮件被正确识别为正常邮件2. 从零实现四大指标计算2.1 准确率(Accuracy)的实现与局限准确率是最直观的指标表示模型预测正确的比例def accuracy(y_true, y_pred): correct sum(1 for t, p in zip(y_true, y_pred) if t p) return correct / len(y_true) # 使用sklearn验证 from sklearn.metrics import accuracy_score print(f自定义准确率: {accuracy(y_true, y_pred):.2f}) print(fsklearn准确率: {accuracy_score(y_true, y_pred):.2f})然而准确率在类别不平衡时会产生误导。假设我们有1000封邮件其中990封是正常邮件10封是垃圾邮件。如果一个模型简单地将所有邮件预测为正常邮件它的准确率高达99%但这个模型对垃圾邮件的识别完全失效。2.2 精确率(Precision)的实战计算精确率关注的是模型预测为正例的样本中实际为正例的比例def precision(y_true, y_pred): tp sum(1 for t, p in zip(y_true, y_pred) if t 1 and p 1) fp sum(1 for t, p in zip(y_true, y_pred) if t 0 and p 1) return tp / (tp fp) if (tp fp) 0 else 0 # 对比sklearn实现 from sklearn.metrics import precision_score print(f自定义精确率: {precision(y_true, y_pred):.2f}) print(fsklearn精确率: {precision_score(y_true, y_pred):.2f})在垃圾邮件检测中高精确率意味着被标记为垃圾邮件的邮件中确实大多是垃圾邮件。这对用户体验很重要因为把正常邮件误判为垃圾邮件(FP)会造成严重问题。2.3 召回率(Recall)的代码实现召回率衡量的是实际为正例的样本中被正确预测为正例的比例def recall(y_true, y_pred): tp sum(1 for t, p in zip(y_true, y_pred) if t 1 and p 1) fn sum(1 for t, p in zip(y_true, y_pred) if t 1 and p 0) return tp / (tp fn) if (tp fn) 0 else 0 # 对比sklearn实现 from sklearn.metrics import recall_score print(f自定义召回率: {recall(y_true, y_pred):.2f}) print(fsklearn召回率: {recall_score(y_true, y_pred):.2f})在医疗诊断等场景中高召回率至关重要因为它意味着尽可能少地漏诊实际患病者(FN)。2.4 F1分数的计算与意义F1分数是精确率和召回率的调和平均数用于平衡两者def f1_score(y_true, y_pred): p precision(y_true, y_pred) r recall(y_true, y_pred) return 2 * p * r / (p r) if (p r) 0 else 0 # 对比sklearn实现 from sklearn.metrics import f1_score as sklearn_f1 print(f自定义F1分数: {f1_score(y_true, y_pred):.2f}) print(fsklearn F1分数: {sklearn_f1(y_true, y_pred):.2f})F1分数在以下场景特别有用当数据类别不平衡时当假正例(FP)和假负例(FN)的成本都很高时需要单一指标来比较模型时3. 使用sklearn全面评估模型sklearn提供了便捷的classification_report函数可以一次性计算所有指标from sklearn.metrics import classification_report from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression # 加载乳腺癌数据集 data load_breast_cancer() X_train, X_test, y_train, y_test train_test_split( data.data, data.target, test_size0.3, random_state42 ) # 训练模型 model LogisticRegression(max_iter10000) model.fit(X_train, y_train) # 预测并生成报告 y_pred model.predict(X_test) print(classification_report(y_test, y_pred))报告输出包含每个类别的精确率、召回率、F1分数和支持数以及宏观平均和加权平均。对于二分类问题通常关注正类的指标。4. 阈值调整对指标的影响分类模型通常输出概率而非直接输出类别。通过调整决策阈值我们可以权衡精确率和召回率import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import precision_recall_curve # 获取预测概率 y_scores model.predict_proba(X_test)[:, 1] # 计算不同阈值下的精确率和召回率 precisions, recalls, thresholds precision_recall_curve(y_test, y_scores) # 绘制P-R曲线 plt.figure(figsize(10, 6)) plt.plot(thresholds, precisions[:-1], b--, labelPrecision) plt.plot(thresholds, recalls[:-1], g-, labelRecall) plt.xlabel(Threshold) plt.legend(loccenter left) plt.ylim([0, 1]) plt.show()通过曲线可以发现提高阈值会增加精确率但降低召回率降低阈值会增加召回率但降低精确率最佳阈值取决于具体业务需求在实际项目中我通常会尝试多个阈值选择使F1分数最大化的那个点除非业务有明确的精确率或召回率要求。例如在信用卡欺诈检测中我们可能更关注召回率宁愿多查一些可疑交易也不愿漏掉真正的欺诈。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2573010.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!