Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >调整模型以减少错误预测

调整模型以减少错误预测

作者头像
磐创AI
发布于 2024-03-12 09:53:14
发布于 2024-03-12 09:53:14
29500
代码可运行
举报
运行总次数:0
代码可运行

介绍

在创建分类模型时,许多算法提供了predict_proba()函数,用于给出观察结果被分类到每个类别的概率。因此,通常会看到如下输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[0.925, 0.075]

在上述情况下,模型有92.5%的确信度认为观察结果属于类别0,而只有7.5%的机会属于类别1。

因此,如果我们请求这个同样的模型使用predict()函数来进行二元预测,我们将只会得到结果[0],对吗?

在这个例子中,很可能我们不希望模型将观察结果预测为类别1,因为它只有很小的机会。但是,让我们假设我们对另一个观察结果进行了预测,结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[0.480, 0.520]

现在怎么办?

很多模型的粗糙切割预测肯定会给我们[1]的结果。但这是最佳决策吗?有时是,有时不是。

在本文中,我们将学习如何使用Python中的catboost包,根据我们对于可接受的假阳性率[FPR]或假阴性率[FNR]的理解,为分类提供最佳的阈值值。

数据科学背景

为了将这篇文章置于上下文中,让我们了解为什么要将阈值从默认的50%更改为其他数字。

我们有一个最好的例子来自医疗保健行业。我们知道许多实验室检查和药物测试依赖于机器学习,以帮助专家得出最精确的答案。毕竟,在这个行业,每个百分点都关系到一个人的生命。

所以让我们说我们正在使用数据来诊断乳腺癌。与利益相关者讨论后,我们达成了一项协议,即我们希望我们的模型最多产生1%的假阴性。我们想要确保一个人是健康的,以便说它对乳腺癌是阴性的。如果有疑虑,我们将将其分类为阳性,并建议进行第二次检查或不同的确认测试。

正如你可能已经得出的结论,这样做将降低我们模型的准确性,因为我们将增加假阳性的数量,但这是可以接受的,因为人们始终可以再次检查并进行其他检查以确认是否是真正的阳性。另一方面,我们不会漏掉任何一个患有疾病并得到阴性结果的人。

编码

你可以在我的GitHub存储库中找到这个练习的全部代码,链接在这里。

https://github.com/gurezende/Studying/tree/master/Python/CatBoost

要安装catboost,使用pip install catboost。下面列出了一些需要的导入。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Basics
import pandas as pd
import numpy as np
# Visualizations
import plotly.express as px
# CatBoost
from catboost import CatBoostClassifier
from catboost import Pool
# Train test
from sklearn.model_selection import train_test_split
# Metrics
from sklearn.metrics import confusion_matrix, f1_score
数据集

要使用的数据是著名的toy数据集Breast Cancer,原生来自sklearn。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Dataset
from sklearn.datasets import load_breast_cancer

# Load data
data = load_breast_cancer()

# X
X = pd.DataFrame(data.data, columns=data.feature_names)
# y
y = data.target

正如你可能已经知道或不知道的那样,这个数据集已经准备好了。在建模之前没有太多可以探索或转换的内容。这也不是我们在这里的目的,所以我只会继续进行代码。

训练测试分割

让我们将数据拆分为训练集和测试集。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Train test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

print(f'Train shapes: {X_train.shape} | {y_train.shape}')
print(f'Test shapes: {X_test.shape} | {y_test.shape}')

Train shapes: (455, 30) | (455,)
Test shapes: (114, 30) | (114,)
第一个模型

接下来,我们将使用CatBoostClassifier训练第一个模型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Creating a Pool for training and validation sets
train_pool = Pool( data=X_train, label=y_train)
test_pool = Pool( data=X_test, label=y_test)

# Fit
model = CatBoostClassifier(iterations=500)
model.fit(train_pool, eval_set=test_pool, verbose=100)

在此序列中,F1分数为:97%。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Predict
preds = model.predict(X_test)
f1_score(y_test, preds)

0.971830985915493

非常好。但是我们的模型有点复杂,因为它有超过30个特征。让我们尝试减少特征数量,而不会失去太多性能。Catboost具有feature_importances_属性,可以帮助我们确定要选择的最佳特征。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Feature importances to dataframe
feature_importances = (
    pd.DataFrame({'feature': data.feature_names, 
                  'importance': model.feature_importances_})
    .sort_values(by='importance', ascending=False)
)
# Plot
px.bar(feature_importances,
       x= data.feature_names, y=model.feature_importances_,
       height=600, width=1000).update_layout(xaxis={'categoryorder':'total descending'})

在不使用任何复杂技巧的情况下,我只是随意选择了保留任何具有3+重要性的特征。这保留了其中的10个特征,位于红线的左侧。

简化模型

让我们训练更简化的模型并评估分数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Simpler model
features = feature_importances.feature[:10]
# Creating a Pool for training and validation sets
train_pool2 = Pool( data=X_train[features], label=y_train)
test_pool2 = Pool( data=X_test[features], label=y_test)

# Model 
model2 = CatBoostClassifier(iterations=600)
model2.fit(train_pool2, eval_set=test_pool2, verbose=100)

# Score
preds2 = model2.predict(test_pool2)
f1_score(y_test, preds2)

0.979020979020979

不错。相同的F1分数:97%。

由于我们正在处理医学诊断,我们不应该对假阴性很宽容。我们希望我们的模型只有在非常确定患者实际上是健康的情况下才会说患者是健康的。

但我们知道,CatBoost算法使用标准的50%阈值来预测结果。这意味着,如果正面概率低于50%,患者将被诊断为乳腺癌阴性。但我们可以调整该数字,以使其仅在更高程度的确定性下给出负面预测。

让我们看看如何做到这一点。以下是我们模型的一些预测。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Regular predictions
default_preds = pd.DataFrame(model2.predict_proba(test_pool2).round(3))
default_preds['classification'] = model2.predict(test_pool2)
default_preds.sample(10)

请注意,观察结果82有63.4%的机会是阴性,但也有36%的机会是阳性,从医学标准来看可能被认为是高的。我们希望将此案例分类为阳性,即使知道它可能是错误的。因此,我们可以将这个人送去进行以后的测试。所以让我们将我们的假阴性率[FNR]容忍度设置为1%。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from catboost.utils import select_threshold
# Finding the right threshold
print(select_threshold(model2, test_pool2, FNR=0.01))

0.1420309044590601

太好了。现在,CatBoost计算出了新的阈值,被分类为负的阈值为1-0.142 = 0.858。简单来说,类别0的概率必须超过85.8%才能被标记为0,否则将被分类为1。

好的,所以我创建了一个自定义函数predict_threshold(df,threshold,rate_type)(请访问我的GitHub查看代码),该函数以解释变量的数据框、所需的阈值和速率类型(FNR或FPR)作为输入,并返回使用新切割的分类。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Predict
new_predictions = predict_threshold(df= test_pool2, 
                                    threshold= 0.01, 
                                    rate_type= "FNR")

# Standard predictions
normal_predictions = model2.predict(test_pool2)

同样的观察结果,在索引82处,先前以63%的概率被分类为阴性(0)的现在被分类为阳性(1)。

这是使用标准50%阈值的混淆矩阵。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Confusion Matrix 50% standard threshold
pd.DataFrame( confusion_matrix(y_true=y_test, y_pred=normal_predictions) )

这是使用更新后的阈值的新分类。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Confusion Matrix 1% of false negatives allowed threshold
pd.DataFrame( confusion_matrix(y_true=y_test, y_pred=new_predictions) )

观察底部左侧的单元格[true=1,pred=0,FN],来自两个混淆矩阵。顶部的一个显示了一个假阴性。这个人实际上患有癌症,但模型将其分类为阴性。在新模型中解决了这个问题,没有假阴性。另一方面,我们也增加了一个假阳性。因此,这一切都是关于权衡,就像数据科学中的许多其他事情一样。

FPR(I型错误)和FNR(II型错误)是互补的。当你降低一个时,必然会增加另一个。

如果项目需要非常低数量的假阳性,同样的方法也可以用来降低FPR。

总结

总之,在这篇文章中,我们学到了以下内容:

  • 分类的默认切割阈值是概率的50%。
  • 可以调整此数字以减少假阳性或假阴性的数量。
  • FPR(I型错误)和FNR(II型错误)是互补的。降低一个将增加另一个。
  • 使用catboost包计算概率切割的阈值值。
  • 例如:predict_threshold(test_pool2,threshold=0.01,rate_type="FNR")

参考资料

https://github.com/catboost/tutorials/blob/master/events/2019_pydata_london/pydata_london_2019.ipynb

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 磐创AI 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
七天学完十大机器学习经典算法-09.梯度提升算法:预测艺术的精进之道
接上一篇《七天学完十大机器学习经典算法-08.K均值聚类:无监督学习的万能分箱术》
熊猫钓鱼
2025/08/01
1230
七天学完十大机器学习经典算法-09.梯度提升算法:预测艺术的精进之道
一文速学-CatBoost算法模型实现贷款违约预测
此篇文章为整个Boost(提升方法)集成算法模型的终章,前几篇文章依次结合详细项目案例讲解了AdaBoost、GBDT、XGBoost、LightGBT共四个常用的集成算法模型,每一篇文章都包含实战项目以及可运行代码。仅通过看一遍文章不去实践是很难掌握集成算法模型的,其中很多思想和优化参数的方法需要长期使用才能掌握,集成学习的方法在全球各大机器学习、数据挖掘竞赛中使用的非常广泛,其概念和思想也是风靡学术界和工业界,所以有此需求的朋友推荐细读实践。
fanstuck
2025/01/01
5110
一文速学-CatBoost算法模型实现贷款违约预测
使用CatBoost和SHAP进行多分类完整代码示例
CatBoost是顶尖的机器学习模型之一。凭借其梯度增强技术以及内置函数,可以在不做太多工作的情况下生成一些非常好的模型。SHAP (SHapley Additive exPlanation)是旨在解释具有独特视觉效果和性能价值的机器学习模型的输出。CatBoost和SHAP结合在一起构成了一个强大的组合,可以产生一些非常准确并且可以进行解释的结果。
deephub
2023/08/30
9901
使用CatBoost和SHAP进行多分类完整代码示例
时间序列预测(三)基于Prophet+XGBoost的销售额预测
前面我们介绍了如何使用Prophet和LSTM,不知道你们发现了没有,前者似乎太简单了,后者呢好像又很复杂。那有没有什么很好的方法能很好的中和下呢?
HsuHeinrich
2023/05/25
1.5K0
时间序列预测(三)基于Prophet+XGBoost的销售额预测
一套完整的基于随机森林的机器学习流程(特征选择、交叉验证、模型评估))
为了展示随机森林的操作,我们用一套早期的前列腺癌和癌旁基因表达芯片数据集,包含102个样品(50个正常,52个肿瘤),2个分组和9021个变量 (基因)。(https://file.biolab.si/biolab/supp/bi-cancer/projections/info/prostata.html)
生信宝典
2021/11/23
10.1K0
算法金 | 一文彻底理解机器学习 ROC-AUC 指标
在机器学习和数据科学的江湖中,评估模型的好坏是非常关键的一环。而 ROC(Receiver Operating Characteristic)曲线和 AUC(Area Under Curve)正是评估分类模型性能的重要工具。
算法金
2024/06/11
1.9K0
算法金 | 一文彻底理解机器学习 ROC-AUC 指标
讯飞广告反欺诈赛的王牌模型catboost介绍
前段时间,MeteoAI小伙伴参加了讯飞移动广告反欺诈算法挑战赛算法挑战大赛[1],最终取得了复赛14/1428名的成绩。这是第一个我们从头到尾认真刷完的比赛,排名前1%其实我们觉得也还算可以,但还是比较遗憾与获奖区(前十名)擦肩而过......整个过程也是相当的波澜起伏,最高排名我们11名,可谓就是差一点点点就进入头部梯队了。不过通过这次比赛我们也确实收获了不少。
MeteoAI
2019/09/25
5.9K0
讯飞广告反欺诈赛的王牌模型catboost介绍
【吐血整理】一份完备的集成学习手册!(附Python代码)
试想一下,当你想买一辆新车时,你会直接走到第一家汽车商店,并根据经销商的建议购买一辆车吗?这显然不太可能。
红色石头
2022/01/12
5840
【吐血整理】一份完备的集成学习手册!(附Python代码)
银行风控案例:Logistics模型预测银行贷款违约
在面试中会经常碰到考察对数据挖掘算法的熟悉程度,面试官会出一道题或给出一些数据,让你结合实际谈谈你选择什么模型,该模型的大致原理是什么,使用条件有哪些,模型优缺点,如何选择特征,模型如何调参优化,如何评估模型效果等。 以下将要介绍逻辑回归,以历史数据判断银行或P2P金融机构客户贷款违约情况。 逻辑回归是用来做分类任务的。分类任务的目标是找一个函数,把观测值匹配到相关的类或标签上。算法必须用成对的特征向量和对应的标签来估计匹配函数的参数,从而实现更好的分类效果。在二元分类中,分类算法必须把一个实例配置两个类别
机器学习AI算法工程
2018/03/14
4.6K0
银行风控案例:Logistics模型预测银行贷款违约
从零开始学机器学习——逻辑回归
首先给大家介绍一个很好用的学习地址:https://cloudstudio.net/columns
努力的小雨
2024/09/24
6802
使用阈值调优改进分类模型性能
来源:Deephub Imba 本文约2500字,建议阅读7分钟 本文将演示如何通过阈值调优来提高模型的性能。 阈值调优是数据科学中一个重要且必要的步骤。它与应用程序领域密切相关,并且需要一些领域内的知识作为参考。在本文中将演示如何通过阈值调优来提高模型的性能。 用于分类的常用指标 一般情况下我们都会使用准确率accuracy来评价分类的性能,但是有很多情况下accuracy 不足以报告分类模型的性能,所以就出现了很多其他的指标:精确度Precision、召回率Recall、F1 分数F1 score和特
数据派THU
2022/10/09
9770
使用阈值调优改进分类模型性能
Transformer 模型实用介绍:BERT
在 NLP 中,Transformer 模型架构是一场革命,极大地增强了理解和生成文本信息的能力。
数据科学工厂
2023/08/10
6330
Transformer 模型实用介绍:BERT
期末大作业:客户流失数据可视化分析与预测
在二元问题中,你必须猜测一个示例是否应该归类到特定类别(通常是正类 (1) 和负类 (0)。在本例中,churn 是正类。
数据STUDIO
2024/08/01
4560
期末大作业:客户流失数据可视化分析与预测
CatBoost中级教程:集成学习与模型融合
集成学习是一种将多个基础模型组合起来以提高预测性能的技术。CatBoost作为一种梯度提升算法,可以与其他机器学习算法进行集成,以进一步提高模型的准确性和稳定性。本教程将详细介绍如何在Python中使用CatBoost进行集成学习与模型融合,并提供相应的代码示例。
Echo_Wish
2024/03/08
2820
精品教学案例 | 信用卡客户违约预测
本案例使用的是来自UCI网站上的台湾地区信用卡客户数据,包含了2005年4月到2005年9月客户的人口统计特征、信用数据、历史还款、账单等信息。目的是对客户下个月是否违约做出预测。原始数据格式是csv,一共有25个列:
数据酷客
2020/05/12
4K1
精品教学案例 | 信用卡客户违约预测
机器学习基础:类别不平衡问题处理方法汇总及实际案例解析
原文:https://www.cnblogs.com/shenggang/p/12133016.html
Ai学习的老章
2020/08/28
9.2K0
机器学习基础:类别不平衡问题处理方法汇总及实际案例解析
数据科学31 |机器学习-模型评价
在二元预测中,通常会估计样本出现其中一种结局(如阳性)的概率,需要找到一个常数,即阈值(threshold)或门槛值(cutoff value),若概率值大于阈值,则预测为阳性。通过变动这一阈值,可以改变预测的特异性和灵敏度。
王诗翔呀
2020/07/09
1.2K0
数据科学31 |机器学习-模型评价
医学假阴性?看看在机器学习中如何用来衡量分类模型的效果(附代码)
近日来,新冠肺炎核酸检测“假阴性”引起了关注。所谓的假阴性,就是患者是新型冠状病毒感染者,但是核酸没检测出来,报告阴性。有专家分析,任何核酸检测的检出率都不可能达到100%,出现假阴性具有不可避免性,这是技术本身存在的局限性。
数据派THU
2020/02/20
1.4K0
医学假阴性?看看在机器学习中如何用来衡量分类模型的效果(附代码)
使用CatBoost和NODE建模表格数据对比测试
来自俄罗斯在线搜索公司Yandex的CatBoost快速且易于使用,但同一家公司的研究人员最近发布了一种基于神经网络的新软件包NODE,声称其性能优于CatBoost和所有其他梯度增强方法。这是真的吗?让我们找出如何同时使用CatBoost和NODE!
deephub
2020/11/02
9230
使用CatBoost和NODE建模表格数据对比测试
CatBoost模型部署与在线预测教程
CatBoost是一个开源机器学习库,用于处理分类和回归任务。它特别适合处理具有大量类别特征的数据集。在这篇教程中,我们将学习如何部署一个CatBoost模型,并创建一个简单的Web服务来进行在线预测。
Echo_Wish
2024/03/12
3830
推荐阅读
相关推荐
七天学完十大机器学习经典算法-09.梯度提升算法:预测艺术的精进之道
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档