如何开发针对不平衡分类的成本敏感神经网络 python

news2024/11/15 8:27:54

如何开发针对不平衡分类的成本敏感神经网络

深度学习神经网络是一类灵活的机器学习算法,可以在各种问题上表现良好。

神经网络使用误差反向传播算法进行训练,该算法涉及计算模型在训练数据集上产生的误差,并根据这些误差的比例更新模型权重。这种训练方法的局限性在于,每个类别的示例都被视为相同,对于不平衡的数据集,这意味着模型对一个类别的适应性要强得多,而对另一个类别的适应性则弱得多。

反向传播算法可以更新,以根据类别的重要性对错误分类误差进行加权,称为加权神经网络或成本敏感神经网络。这可以使模型在类别分布严重倾斜的数据集中更加关注少数类别的样本,而不是多数类别的样本。

在本教程中,您将发现用于不平衡分类的加权神经网络。

完成本教程后,您将了解:

  • 标准神经网络算法为何不支持不平衡分类。
  • 如何修改神经网络训练算法,以根据类别重要性对错误分类误差进行加权。
  • 如何为神经网络配置类权重并评估对模型性能的影响。

教程概述

本教程分为四个部分:

  1. 不平衡分类数据集
  2. Keras 中的神经网络模型
  3. 深度学习解决不平衡分类问题
  4. 使用 Keras 的加权神经网络

不平衡分类数据集

在深入研究如何修改神经网络以解决不平衡分类问题之前,让我们首先定义一个不平衡分类数据集。

我们可以使用make_classification() 函数来定义一个合成的不平衡二分类数据集。我们将生成 10,000 个示例,少数类与多数类的比例约为 1:100。

...
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
	n_clusters_per_class=2, weights=[0.99], flip_y=0, random_state=4)

一旦生成,我们可以总结类分布以确认数据集是按照我们预期创建的。

...
# summarize class distribution
counter = Counter(y)
print(counter)

最后,我们可以创建示例的散点图并按类标签对其进行着色,以帮助理解从该数据集对示例进行分类的挑战。

...
# scatter plot of examples by class label
for label, _ in counter.items():
	row_ix = where(y == label)[0]
	pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()

综合以上几点,生成合成数据集和绘制示例的完整示例如下所示。

# Generate and plot a synthetic imbalanced classification dataset
from collections import Counter
from sklearn.datasets import make_classification
from matplotlib import pyplot
from numpy import where
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
	n_clusters_per_class=2, weights=[0.99], flip_y=0, random_state=4)
# summarize class distribution
counter = Counter(y)
print(counter)
# scatter plot of examples by class label
for label, _ in counter.items():
	row_ix = where(y == label)[0]
	pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()

首先运行示例会创建数据集并汇总类分布。

我们可以看到,数据集的类别分布近似于 1:100,其中多数类别有不到 10,000 个示例,少数类别有 100 个示例。

Counter({0: 9900, 1: 100})

接下来,创建数据集的散点图,显示多数类别的大量示例(蓝色)和少数类别的少量示例(橙色),其中有一些适度的类别重叠。
在这里插入图片描述
具有 1 到 100 类不平衡的二分类数据集的散点图

Keras 中的神经网络模型

接下来,我们可以在数据集上拟合标准的神经网络模型。

首先,我们可以定义一个函数来创建合成数据集,并将其分成单独的训练数据集和测试数据集,每个数据集有 5,000 个示例。

# prepare train and test dataset
def prepare_data():
	# generate 2d classification dataset
	X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
	n_clusters_per_class=2, weights=[0.99], flip_y=0, random_state=4)
	# split into train and test
	n_train = 5000
	trainX, testX = X[:n_train, :], X[n_train:, :]
	trainy, testy = y[:n_train], y[n_train:]
	return trainX, trainy, testX, testy

可以使用Keras 深度学习库定义多层感知器神经网络。我们将定义一个神经网络,该网络需要两个输入变量,一个包含 10 个节点的隐藏层,然后是一个预测类标签的输出层。

我们将在隐藏层中使用流行的ReLU 激活函数,在输出层中使用 sigmoid 激活函数,以确保预测的概率在 [0,1] 范围内。该模型将使用具有默认学习率的随机梯度下降进行拟合,并根据交叉熵损失进行优化。

网络架构和超参数并未针对该问题进行优化;相反,当训练算法稍后被修改来处理倾斜的类分布时,网络提供了比较的基础。

*下面的define_model()*函数定义并返回模型,将网络输入变量的数量作为参数。

# define the neural network model
def define_model(n_input):
	# define model
	model = Sequential()
	# define first hidden layer and visible layer
	model.add(Dense(10, input_dim=n_input, activation='relu', kernel_initializer='he_uniform'))
	# define output layer
	model.add(Dense(1, activation='sigmoid'))
	# define loss and optimizer
	model.compile(loss='binary_crossentropy', optimizer='sgd')
	return model

一旦定义了模型,它就可以适合训练数据集。

我们将使用默认的批量大小对模型进行 100 个训练周期的拟合。

...
# fit model
model.fit(trainX, trainy, epochs=100, verbose=0)

一旦拟合,我们就可以使用该模型对测试数据集进行预测,然后使用ROC AUC分数评估预测。

...
# make predictions on the test dataset
yhat = model.predict(testX)
# evaluate the ROC AUC of the predictions
score = roc_auc_score(testy, yhat)
print('ROC AUC: %.3f' % score)

综合以上内容,下面列出了在不平衡分类数据集上拟合标准神经网络模型的完整示例。

# standard neural network on an imbalanced classification dataset
from sklearn.datasets import make_classification
from sklearn.metrics import roc_auc_score
from keras.layers import Dense
from keras.models import Sequential

# prepare train and test dataset
def prepare_data():
	# generate 2d classification dataset
	X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
	n_clusters_per_class=2, weights=[0.99], flip_y=0, random_state=4)
	# split into train and test
	n_train = 5000
	trainX, testX = X[:n_train, :], X[n_train:, :]
	trainy, testy = y[:n_train], y[n_train:]
	return trainX, trainy, testX, testy

# define the neural network model
def define_model(n_input):
	# define model
	model = Sequential()
	# define first hidden layer and visible layer
	model.add(Dense(10, input_dim=n_input, activation='relu', kernel_initializer='he_uniform'))
	# define output layer
	model.add(Dense(1, activation='sigmoid'))
	# define loss and optimizer
	model.compile(loss='binary_crossentropy', optimizer='sgd')
	return model

# prepare dataset
trainX, trainy, testX, testy = prepare_data()
# define the model
n_input = trainX.shape[1]
model = define_model(n_input)
# fit model
model.fit(trainX, trainy, epochs=100, verbose=0)
# make predictions on the test dataset
yhat = model.predict(testX)
# evaluate the ROC AUC of the predictions
score = roc_auc_score(testy, yhat)
print('ROC AUC: %.3f' % score)

运行该示例可在不平衡数据集上评估神经网络模型并报告 ROC AUC。

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行示例几次并比较平均结果。

在这种情况下,该模型的 ROC AUC 达到约 0.949。这表明,与 ROC AUC 为 0.5 的朴素分类器相比,该模型具有一定的技巧。

ROC AUC: 0.949

这为对标准神经网络训练算法进行的任何修改提供了比较的baseline。

深度学习解决不平衡分类问题

神经网络模型通常使用误差反向传播算法进行训练。

这涉及使用模型的当前状态对训练集示例进行预测,计算预测的误差,然后使用误差更新模型权重,并将误差信用分配给从输出层到输入层的不同节点和层。

鉴于对错误分类错误的平衡关注,大多数标准神经网络算法并不适用于类别分布严重偏斜的数据集。

现有的深度学习算法大多没有考虑数据不平衡问题,导致这些算法在平衡的数据集上能够表现良好,而在不平衡的数据集上性能却无法保证。

—在不平衡数据集上训练深度神经网络,2016 年。

这个训练过程可以进行修改,使得一些例子比其他例子有更多或更少的错误。

还可以通过改变最小化的误差函数来考虑误分类成本。反向传播学习过程应该最小化误分类成本,而不是最小化平方误差。

—使用神经网络进行成本敏感学习,1998 年。

实现这一点的最简单方法是根据样本的类别对误差分数使用固定的权重,其中对于更重要的类别中样本的预测误差会增加,而对于不太重要的类别中样本的预测误差则会减少或保持不变。

…成本敏感学习方法基于对错误分类样本相关成本的考虑来解决数据不平衡问题。具体来说,它为样本的错误分类分配不同的成本值。

—在不平衡数据集上训练深度神经网络,2016 年。

可以对少数类中的例子应用较大的误差权重,因为在不平衡分类问题中,它们通常比多数类中的例子更重要。

  • 大权重:分配给少数类的例子。
  • 小权重:分配给来自多数类别的例子。

这种对神经网络训练算法的修改被称为加权神经网络或成本敏感神经网络。

通常,在定义用于成本敏感型学习的成本或“权重”时需要小心谨慎。但是,对于仅关注错误分类的不平衡分类,权重可以使用在训练数据集中观察到的类分布的逆。

使用 Keras 的加权神经网络

Keras Python 深度学习库提供了对类权重的支持。

用于训练 Keras 神经网络模型的fit() 函数采用一个名为class_weight的参数。此参数允许您定义一个字典,将类整数值映射到要应用于每个类的重要性。

此函数用于训练每种不同类型的神经网络,包括多层感知器、卷积神经网络和循环神经网络,因此类加权功能适用于所有这些网络类型。

例如,每个类 0 和 1 的 1 比 1 权重可以定义如下:

...
# fit model
weights = {0:1, 1:1}
history = model.fit(trainX, trainy, class_weight=weights, ...)

类别权重可以通过多种方式定义;例如:

  • 领域专业知识,通过与主题专家交谈确定。
  • 调整,由超参数搜索(例如网格搜索)确定。
  • 启发式,使用一般的最佳实践来指定。

使用类权重的最佳实践是使用训练数据集中存在的类分布的倒数。

例如,测试数据集的类分布为少数类与多数类的比例为 1:100。该比例的倒数可以为 1 表示多数类,100 表示少数类,例如:

...
# fit model
weights = {0:1, 1:100}
history = model.fit(trainX, trainy, class_weight=weights, ...)

表示相同比例的分数不会产生相同的效果。例如,分别对多数类和少数类使用 0.01 和 0.99 可能会导致比使用 1 和 100 更差的性能(在本例中确实如此)。

...
# fit model
weights = {0:0.01, 1:0.99}
history = model.fit(trainX, trainy, class_weight=weights, ...)

原因是从多数类和少数类中抽取的示例的误差都减少了。此外,多数类的误差减少幅度显著缩小到非常小的数字,这些数字对模型权重的影响可能有限或非常小。

因此,建议使用整数来表示类权重,例如 1 表示无变化,100 表示类 1 的错误分类错误,其影响或惩罚比类 0 的错误分类错误大 100 倍。

我们可以使用上一节中定义的相同评估程序来评估具有类权重的神经网络算法。

我们期望神经网络的类加权版本比没有任何类加权的训练算法版本表现更好。

完整的示例如下。

# class weighted neural network on an imbalanced classification dataset
from sklearn.datasets import make_classification
from sklearn.metrics import roc_auc_score
from keras.layers import Dense
from keras.models import Sequential

# prepare train and test dataset
def prepare_data():
	# generate 2d classification dataset
	X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
	n_clusters_per_class=2, weights=[0.99], flip_y=0, random_state=4)
	# split into train and test
	n_train = 5000
	trainX, testX = X[:n_train, :], X[n_train:, :]
	trainy, testy = y[:n_train], y[n_train:]
	return trainX, trainy, testX, testy

# define the neural network model
def define_model(n_input):
	# define model
	model = Sequential()
	# define first hidden layer and visible layer
	model.add(Dense(10, input_dim=n_input, activation='relu', kernel_initializer='he_uniform'))
	# define output layer
	model.add(Dense(1, activation='sigmoid'))
	# define loss and optimizer
	model.compile(loss='binary_crossentropy', optimizer='sgd')
	return model

# prepare dataset
trainX, trainy, testX, testy = prepare_data()
# get the model
n_input = trainX.shape[1]
model = define_model(n_input)
# fit model
weights = {0:1, 1:100}
history = model.fit(trainX, trainy, class_weight=weights, epochs=100, verbose=0)
# evaluate model
yhat = model.predict(testX)
score = roc_auc_score(testy, yhat)
print('ROC AUC: %.3f' % score)

运行该示例准备合成的不平衡分类数据集,然后评估神经网络训练算法的类加权版本。

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行示例几次并比较平均结果。

报告了 ROC AUC 分数,在这种情况下显示出比训练算法的未加权版本更好的分数,或者约为 0.973,而约为 0.949。

ROC AUC: 0.973

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2093786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙开发入门day16-拖拽事件和手势事件

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,还请三连支持一波哇ヾ(@^∇^@)ノ) 目录 拖拽事件 概述 拖拽流程 ​手势拖拽 ​鼠标拖拽 拖拽背板图 …

如何有效防止表单重复提交

如何有效防止表单重复提交 1. 使用重定向(Redirect)2. 点击后按钮失效3. Loading 遮罩4. 自定义重复提交过滤器 💖The Begin💖点点关注,收藏不迷路💖 在Web开发中,表单重复提交是一个常见问题&…

计算物理精解【3】

文章目录 力学单位矢量基础定义 矢量加法矢量加法的几何方法矢量加法的代数方法示例注意事项 矢量间的关系矢量(或向量)的标量积(也称为点积、内积或数量积)性质计算两矢量之间的夹角例子步骤数值结果 计算两三维矢量之间夹角的例…

厨房老鼠检测算法解决方案老鼠检测算法源码样本详细介绍

厨房老鼠检测算法是一种创新的解决方案,它结合了机器学习和图像识别技术。通过使用高精度的传感器和智能摄像头,这些算法可以实时监控厨房环境,并检测到老鼠的活动痕迹。与传统的检测方法相比,这种算法具有更高的灵敏度和准确性&a…

Java对象的访问定位技术

Java虚拟机规范中规定reference类型是一个指向对象的引用,但规定并没有定义这个引用应该通过什么方式去定位、访问堆中的对象的具体位置,所以对象访问方式取决于具体的虚拟机实现。 目前主流的访问方式有两种:使用句柄和直接指针。 使用句柄…

Altium designer设计经验谈——常用规则的使用(二)

文章目录 前言三、规则设置介绍——走线规则1、Routing——>Width 线宽2、Routing——>Topology 拓扑 四、规则设置介绍——平面层规则1、Plane——>电源层连接样式 Power Plane Connect Style2、Plane——>电源层间距距离 Power Plane Clearance3、Plane——>多…

单片机编程魔法师-并行多任务程序

程序架构 程序代码 小结 数码分离,本质上就是将数据和代码逻辑进行分离,跟第一章使用数据驱动程序一样的道理。 不过这里不同之处在于。这里使用通过任务线程,但是却有2个任务在运行,两个任务都通过先初始化任务数据参数&#x…

C++ | Leetcode C++题解之第387题字符串中的第一个唯一字符

题目&#xff1a; 题解&#xff1a; class Solution { public:int firstUniqChar(string s) {unordered_map<char, int> position;queue<pair<char, int>> q;int n s.size();for (int i 0; i < n; i) {if (!position.count(s[i])) {position[s[i]] i;…

设备管理与文件系统

1、设备管理框架 对于不同类型的设备的操作&#xff0c;全部由一下函数指针来完成。即操作系统对设备进行操作&#xff0c;只需要调用统一的API接口&#xff0c;无需了解相关的细节。 比如如下的接口设计&#xff1a; int (*open) (device_t * dev) ; int (*read) (device_t …

直播行业的未来:南昌络喆科技有限公司的创新无人直播项目!

随着数字化时代的推进&#xff0c;直播行业迎来了前所未有的增长机遇。南昌络喆科技有限公司凭借其创新的无人直播技术&#xff0c;正引领着行业的新潮流&#xff0c;展现出直播领域的新面貌。 无人直播技术突破了传统直播的局限&#xff0c;实现了自动化的高效运营模式。它摒弃…

用Python解决预测问题_对数线性模型模板

对数线性模型&#xff08;Log-linear model&#xff09;是统计学中用于分析计数数据或频率数据的一类模型&#xff0c;特别是在多维列联表&#xff08;contingency tables&#xff09;分析中非常常见。这种模型通过取对数将乘法关系转换为加法关系&#xff0c;从而简化了数据分…

关于自己部署AI大模型踩的坑(三)—— 部署

最近一直在研究如何打算属于我自己的J.A.R.V.I.S.&#xff08;钢铁侠中的机器人管家&#xff09;。 上一篇写了我最近在部署自己的大模型&#xff0c;使用llama3.1&#xff0c; 和通义千问2。虽然最终结果也是成功了&#xff0c;过程却十分地坎坷。所以这一篇文章一是总结其中遇…

Nginx快速入门:编译及常用配置

Nginx 是一个高性能的 HTTP 服务器和反向代理服务器&#xff0c;也是一个 IMAP/POP3 邮件代理服务器。它以其高并发处理能力和低资源消耗而闻名&#xff0c;能够同时处理数千个连接。 Nginx 的主要功能包括&#xff1a; 静态资源服务器&#xff1a;Nginx 可以担任静态资源服务…

【Python零基础】Python测试

文章目录 前言一、使用pip安装pytest1.1 更新pip1.2 安装pytest 二、测试函数2.1 编写测试文件2.2 运行测试2.3 测试不通过2.4 测试不通过2.4 增加新测试 三、测试类3.1 断言3.2 夹具 总结 前言 代码测试是程序开发中极其重要的一环&#xff0c;任何代码都应该经过测试才能上生…

sqli-labs靶场通关攻略(五十一到五十六关)

sqli-labs-master靶场第五十一关 步骤一&#xff0c;尝试输入?sort1 我们发现这关可以报错注入 步骤二&#xff0c;爆库名 ?sort1 and updatexml(1,concat(0x7e,database(),0x7e),1)-- 步骤三&#xff0c;爆表名 ?sort1 and updatexml(1,concat(0x7e,(select group_conc…

数据结构:树形结构(树、堆)详解

数据结构&#xff1a;树形结构&#xff08;树、堆&#xff09;详解 一、树&#xff08;一&#xff09;树的性质&#xff08;二&#xff09;树的种类二叉树多叉树满N叉树完全N叉树 &#xff08;三&#xff09;二叉树的实现1、二叉树结构定义2、二叉树功能实现&#xff08;1&…

数字化转型中的数据应用:挑战、机遇与追赶之路

在数字化时代的大潮中&#xff0c;数据已悄然从企业的边缘资源跃升为最宝贵的核心资产。然而&#xff0c;这场数据盛宴并未带来普遍的数据应用成熟&#xff0c;反而揭示了企业在数据利用上的巨大鸿沟。即便是全球500强企业&#xff0c;在数据应用的征途上&#xff0c;也仅仅是比…

秋招突击——笔试总结——8/31——京东笔试

文章目录 引言正文第一题——下一个字典序的字符个人实现 第二题——冒泡排序的变种个人实现空间复杂度比较低的版本 第三题——两人走路个人实现 总结 引言 今天京东笔试做的并不好&#xff0c;有很多问题的关窍都没有找到&#xff0c;所以在很多问题上都浪费了大量的时间&am…

JVM下篇:性能监控与调优篇-04-JVM运行时参数

文章目录 4. JVM 运行时参数4.1. JVM 参数选项4.1.1. 类型一&#xff1a;标准参数选项4.1.2. 类型二&#xff1a;-X 参数选项4.1.3. 类型三&#xff1a;-XX 参数选项 4.2. 添加 JVM 参数选项4.3. 常用的 JVM 参数选项4.3.1. 打印设置的 XX 选项及值4.3.2. 堆、栈、方法区等内存…

Java多线程(二)线程同步

1、线程同步问题 当多个线程同时操作同一个数据时&#xff0c;就会产生线程同步问题。 为了确保在任何时间点一个共享的资源只被一个线程使用&#xff0c;使用了“同步”。当一个线程运行到需要同步的语句后&#xff0c;CPU不去执行其他线程中的、可能影响当前线程中的下一句代…