IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 使用分类权重解决数据不平衡的问题 -> 正文阅读

[人工智能]使用分类权重解决数据不平衡的问题

在分类任务中,不平衡数据集是指数据集中的分类不平均的情况,会有一个或多个类比其他类多的多或者少的多。

在我们的日常生活中,不平衡的数据是非常常见的比如本篇文章将使用一个最常见的例子,信用卡欺诈检测来介绍,在我们的日常使用中欺诈的数量要远比正常使用的数量少很多,对于我们来说这就是数据不平衡的问题。

在这里插入图片描述

我们使用kaggle上的信用卡交易数据集作为本文的数据集。数据的细节不是特别重要。因为为了进行脱敏,这个数据集的特征是经过PCA降维后输出的,所以讨论这些特征代表什么没有任何意义。除了PCA输出的特征以外,这个数据集还包括与每笔交易相关的美元金额、以秒为单位的连续时间索引,以及一个表示存在或不存在欺诈的二进制目标。对于时间索引,我们考虑到某些特征工程,它可能会很有用,但这不是本文的重点。对于我们真实可见的数据只有金额一项,这个很重要!

我们再看看目标,在284,807行数据中只有0.173%的行是欺诈案例,这绝对是不平衡数据的样例,这种数据的分布会使建模和预测欺诈行为变得有非常的棘手。

性能指标

在不平衡数据时,可以使用几个有价值的性能指标来了解模型的性能。通常情况下,指标的选择很大程度上取决于应用以及与正负相关的结果。单独的一种方法不能适用于所有人。

在信用卡欺诈的背景下,我们不会对产生高准确度分数的模型感兴趣。因为数据集非常不平衡欺诈的数据很少,如果我们将所有样本分类为不存在欺诈,那么准确率还是很高。但是我们对准确预测信用卡交易何时不存在欺诈不感兴趣,我们关心的是信用卡是否存在欺诈,也就是样本量少的分类是否能够被判断出来。

最简单的办法就是召回分数作为模型性能的主要指标。召回是衡量有多少正面案例被模型准确预测的指标。在我们的特定用例中,更高的召回分数意味着我们检测到更多的欺诈案例。

在本文中,我们除了使用召回以外还将分类与最后的财务指标相结合,还记得我们前面提到的数据集的包含交易的美元金额吗?我们也将把它纳入绩效评估,称之为“财务召回”。我们将在下面详细介绍。

数据准备

首先,让我们读入数据,并将其分成训练集和测试集:

import pandas as pd
from sklearn.model_selection import train_test_split

df = pd.read_csv('creditcard.csv')

# enumerate the feature columns
feats = [col for col in df.columns if 'V' in col]

# Split data
x = df[feats + ['Amount']]
y = df['Class']

X_train, X_test, y_train, y_test = train_test_split(
    x, y,
    test_size=.2,
    stratify=y,
    random_state=41)

如果以前没有在train_test_split中使用过stratify参数,那么在处理不平衡数据时应该使用该参数,train_test_split分割后欺诈案例的比例会根据传递列的比例进行分配(具体使用方法可以查看sklearn的文档),我们的目标是为了确保我们在训练集和测试集中保持相同比例类别分布。

基类模型

我们将创建并训练一个基本的逻辑回归模型作为基线。但在此之前我们先创建一个小函数,将每笔交易的金额纳入性能评估。

因为关心的是能够正确分类的欺诈案件的数量,并且我们也关心(可能更关心)将欺诈损失的美元保持在最低限度。这就是我们之前讨论的“财务召回”。让我们创建一个函数来计算正确识别的欺诈金额:

from sklearn.metrics import recall_score

def assess_test_set_performance(model):
    # create predictions
    yhat = model.predict(X_test[feats])
    # evaluate performance using counts
    model_recall = recall_score(y_test, yhat)*100
    print("Classification Test Performance:")
    print(f"Recall: {model_recall:.2f}%")
    
    # calculate financial performance using the dollar amount associated with each transaction
    performance_df = pd.DataFrame({'Amount':X_test['Amount'], 'Actual':y_test, 'Pred':yhat})
    performance_df['fraud_amount'] = performance_df['Amount']*performance_df['Actual']
    performance_df['fraud_prevented'] = performance_df['fraud_amount']*performance_df['Pred']
    performance_df['fraud_realized'] = performance_df['fraud_amount'] - performance_df['fraud_prevented']
    
    financial_recall = (performance_df['fraud_prevented'].sum() / (performance_df['fraud_prevented'].sum() + performance_df['fraud_realized'].sum()))*100

    print()
    print("Financial Test Performance:")
    print(f"Financial Recall: {financial_recall:.2f}%")

现在我们已经确定了评估函数,让我们训练基线模型并评估它的性能:

from sklearn.linear_model import LogisticRegression

baseline_model = LogisticRegression()
baseline_model.fit(X_train[feats], y_train)

assess_test_set_performance(baseline_model)

我们的基线模型实现了59%的召回和61%的财务召回,这实际上比预期的要好。但是这在实际使用时肯定不好,所以其实我们可以做的更好。

改进模型加入类权重

基线模型将两个类设置成同等重要,因为模型不知道我们更关心欺诈的情况,所以我们需要重新定义我们的损失函数。sklearn API提供了让模型知道对正确识别欺诈的偏好:class_weight参数。

当使用class_weight时,模型接收一个字典,每个类都有一个键,其中的值是该类的权重。我们有两类,为了说明这个例子,我们假设欺诈案的重要性是前者的10倍。在这种情况下,我们可以像这样向class_weight传递一个字典:

fraud_class_weights = {0:1, 1:10}

但是sklearn API实际上使这个过程更容易。class_weight参数也可以取’balanced’的值。我们需要做的是使用下面的公式建立一个字典,其中权重与数据中的类分布成比例:

len(X_train) / (2 * numpy.bincount(y_train))

将上面的公式应用到我们的数据中,我们估计正情况实际上比负情况重要575倍。

当我们把这个新的代码放到逻辑回归模型中时,它将更专注于正确地对我们的欺诈交易进行分类。这正是我们想要的结果!

让我们设置它,然后研究性能:

lr_class_weights = LogisticRegression(class_weight='balanced')
lr_class_weights.fit(X_train[feats], y_train)

assess_test_set_performance(lr_class_weights)

这个简单的改变将使我们的召回率提高到90%和93% !因为现在对欺诈更加敏感,比使用基线模型准确地识别更多的欺诈案例。

总结

在模型中使用class_weight肯定会帮助从模型中获得更多相关的性能。并且它很容易设置,至少值得试一试。本文中介绍的方法是解决分类不平衡问题的一种过简单的方法,在这个领域中还有许多其他的方法可以讨论,但是为分类设置权重是一个非常好的开始。

https://avoid.overfit.cn/post/13e8cb84f1e1480eb62d9f029647ed3a

作者;Greg J

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:44:55  更:2022-08-06 10:49:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:36:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码