程序员学长 | 最强总结,机器学习中处理不平衡数据集的五种方法!!

本文来源公众号“程序员学长”,仅用于学术分享,侵权删,干货满满。

原文链接:最强总结,机器学习中处理不平衡数据集的五种方法!!

今天给大家分享处理不平衡数据集的常用方法。

在开始之前,我们先来了解一下什么是不平衡的数据集。

不平衡数据集是指在分类任务中,不同类别的样本数量差异显著的数据集,通常表现为少数类样本远少于多数类样本。这样的数据集在现实生活中很常见,比如欺诈检测、医疗诊断、故障预测等场景。

例如,在一个包含 10,000 个实例的数据集中,95% 属于一个类(类 0),只有 5% 属于另一个类(类 1),很明显,模型可能会高度关注多数类,而经常完全忽略少数类。

不平衡数据的问题

在不平衡的数据集中,多数类别主导着模型的预测,导致少数类别的预测性能较差。

例如,如果 95% 的数据被标记为 0 类,则将所有实例预测为 0 类可获得 95% 的准确率,即使 1 类预测完全不正确。

示例

考虑一个欺诈检测系统,其中 99% 的交易是合法的,只有 1% 是欺诈的。预测所有交易均为合法的模型将达到 99% 的准确率,但无法检测到任何欺诈行为,使其无法达到预期目的。

让我们通过一个例子来可视化不平衡数据

import numpy as np
import pandas as pd
import plotly.express as px
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
import plotly.figure_factory as ff# Generate imbalanced data
n_samples = 10000
class_0_ratio = 0.95
n_class_0 = int(n_samples * class_0_ratio)
n_class_1 = n_samples - n_class_0X_class_0 = np.random.randn(n_class_0, 2)
X_class_1 = np.random.randn(n_class_1, 2) + 2  # Shift class 1 datay_class_0 = np.zeros(n_class_0)
y_class_1 = np.ones(n_class_1)X = np.concatenate((X_class_0, X_class_1), axis=0)
y = np.concatenate((y_class_0, y_class_1), axis=0)# Create a Pandas DataFrame for easier handling
df = pd.DataFrame(X, columns=['Feature 1', 'Feature 2'])
df['Target'] = y# Visualize class distribution
fig = px.histogram(df, x='Target', title='Class Distribution', width=800, height=600)
fig.update_layout(title_x=0.5)
fig.update_xaxes(tickvals=[0, 1], ticktext=['Class 0', 'Class 1'])
fig.show()# Split data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Train a Logistic Regression model
model = LogisticRegression()
model.fit(X_train, y_train)# Make predictions on the test set
y_pred = model.predict(X_test)# Evaluate the model
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-score: {f1:.4f}")# Confusion Matrix
cm = confusion_matrix(y_test, y_pred)
fig = ff.create_annotated_heatmap(cm, x=['Predicted 0', 'Predicted 1'], y=['True 0', 'True 1'])
fig.update_layout(title_text='Confusion Matrix', width=800, height=600, title_x=0.5)
fig.show()

此代码生成一个不平衡的数据集,其中 95% 的实例被标记为类 0,只有 5% 被标记为类 1。

当我们可视化类别分布时,我们会看到两个类别之间的明显不平衡。

Accuracy: 0.9815
Precision: 0.8451
Recall: 0.6977
F1-score: 0.7643

混淆矩阵显示,虽然准确率很高,但少数类(类1)的准确率和召回率要低得多。该模型偏向多数类。

import plotly.express as pxdf["Target"] = df["Target"].astype(str)
fig = px.scatter(df, x='Feature 1', y='Feature 2', color='Target', title='Original Dataset')
fig.update_layout(title_x=0.5, width=800, height=600)
fig.show()

处理不平衡数据的技术

1.随机欠采样

随机欠采样是一种通过减少多数类样本的数量来平衡类分布的方法。

具体做法是随机选择部分多数类样本并将其移除,使得多数类和少数类的样本数量接近平衡。

优点

  • 简单易行,不需要复杂的算法。

  • 减少了数据集的规模,降低了计算成本。

缺点

  • 可能丢失重要的多数类信息,导致模型性能下降。

  • 缩小的数据集可能导致模型对多数类的泛化能力变差。

from imblearn.under_sampling import RandomUnderSampler
from collections import Counter# Use RandomUnderSampler to balance the dataset
undersampler = RandomUnderSampler(sampling_strategy='auto', random_state=42)
X_resampled, y_resampled = undersampler.fit_resample(X, y)# Check the original class distribution
print("Original class distribution:", Counter(y))
# Check the new class distribution after undersampling
print("New class distribution after undersampling:", Counter(y_resampled))X_train, X_test, y_train, y_test = train_test_split(X_resampled, y_resampled, test_size=0.2, random_state=42)# Train a simple logistic regression model
model = LogisticRegression(solver='liblinear')
model.fit(X_train, y_train)# Make predictions
y_pred = model.predict(X_test)# Evaluate the model
accuracy = accuracy_score(y_test, y_pred)print(f"Accuracy: {accuracy:.4f}")# Distribution of undersampled data
df_resampled = pd.DataFrame(X_resampled, columns=['Feature 1', 'Feature 2'])
df_resampled['Target'] = y_resampleddf_resampled["Target"] = df_resampled["Target"].astype(str)
fig = px.scatter(df_resampled, x='Feature 1', y='Feature 2', color='Target', title='Undersampled Dataset')
fig.update_layout(title_x=0.5, width=800, height=600)
fig.show()

2.随机过采样

随机过采样通过增加少数类样本的数量来平衡类分布。

常见的做法是随机复制少数类的样本,直到少数类样本的数量与多数类样本的数量相等。

优点

  • 不会丢失数据,不像欠采样那样丢失多数类的样本。

  • 在数据较少时,可以通过增加样本数量提高模型的学习效果。

缺点

  • 由于重复样本的存在,可能导致模型过拟合少数类样本。

from imblearn.over_sampling import RandomOverSampler# Check the original class distribution
original_class_distribution = Counter(y)
print("Original class distribution:", original_class_distribution)# Initialize RandomOverSampler
oversampler = RandomOverSampler(sampling_strategy='auto', random_state=42)# Apply random oversampling to balance the dataset
X_oversampled, y_oversampled = oversampler.fit_resample(X, y)# Check the new class distribution after oversampling
new_class_distribution = Counter(y_oversampled)
print("New class distribution after oversampling:", new_class_distribution)X_train, X_test, y_train, y_test = train_test_split(X_oversampled, y_oversampled, test_size=0.2, random_state=42)# Train a simple logistic regression model
model = LogisticRegression(solver='liblinear')
model.fit(X_train, y_train)# Make predictions
y_pred = model.predict(X_test)# Evaluate the model
accuracy = accuracy_score(y_test, y_pred)print(f"Accuracy: {accuracy:.4f}")df_resampled = pd.DataFrame(X_oversampled, columns=['Feature 1', 'Feature 2'])
df_resampled['Target'] = y_oversampleddf_resampled["Target"] = df_resampled["Target"].astype(str)
fig = px.scatter(df_resampled, x='Feature 1', y='Feature 2', color='Target', title='Oversampled Dataset')
fig.update_layout(title_x=0.5, width=800, height=600)
fig.show()

3.SMOTE

SMOTE 是一种合成过采样方法,通过生成新的少数类样本来平衡数据集。

它不是简单地复制现有的少数类样本,而是通过对现有少数类样本的特征进行插值,创建新样本。

具体来说,SMOTE 从少数类样本中选取一个样本和其最近邻样本,在它们之间生成新的合成样本。

优点

  • 通过生成新样本代替简单复制,缓解了过拟合的问题。

  • 利用插值方法生成多样化的少数类样本,扩展了少数类样本的分布。

缺点

  • 生成的合成样本可能落在错误的决策边界上,尤其是在样本分布不清晰时。

  • 对高维数据的效果不佳,因为高维数据中的样本通常稀疏,插值生成的样本可能不具有代表性。

from imblearn.over_sampling import SMOTE# Check the original class distribution
original_class_distribution = Counter(y)
print("Original class distribution:", original_class_distribution)# Initialize SMOTE
smote = SMOTE(sampling_strategy='auto', random_state=42)# Apply SMOTE to balance the dataset
X_smote, y_smote = smote.fit_resample(X, y)# Check the new class distribution after SMOTE
new_class_distribution = Counter(y_smote)
print("New class distribution after SMOTE:", new_class_distribution)X_train, X_test, y_train, y_test = train_test_split(X_smote, y_smote, test_size=0.2, random_state=42)# Train a simple logistic regression model
model = LogisticRegression(solver='liblinear')
model.fit(X_train, y_train)# Make predictions
y_pred = model.predict(X_test)# Evaluate the model
accuracy = accuracy_score(y_test, y_pred)print(f"Accuracy: {accuracy:.4f}")df_resampled = pd.DataFrame(X_smote, columns=['Feature 1', 'Feature 2'])
df_resampled['Target'] = y_smotedf_resampled["Target"] = df_resampled["Target"].astype(str)
fig = px.scatter(df_resampled, x='Feature 1', y='Feature 2', color='Target', title='SMOTE Dataset')
fig.update_layout(title_x=0.5, width=800, height=600)
fig.show()
df_resampled["Target"].value_counts()

4.成本敏感型学习

成本敏感型学习通过为分类错误分配不同的成本来解决数据不平衡问题。

在不平衡数据集中,错分少数类的代价通常比多数类更高。成本敏感型学习通过在损失函数中引入成本矩阵来调整模型,使得少数类的错分类损失更大,从而引导模型更加关注少数类。

优点

  • 不需要对数据进行重采样,可以直接在模型训练中融入不平衡问题。

  • 可以灵活调整不同错误分类的成本,适应不同场景的需求。

缺点

  • 成本矩阵的设置需要根据实际问题调整,具有一定的挑战性。

  • 在处理严重不平衡的数据时,仍可能遇到少数类样本过少的问题。

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report
from imblearn.under_sampling import RandomUnderSampler
from collections import Counter
from sklearn.datasets import make_classification# Create a mock imbalanced dataset
X, y = make_classification(n_classes=2, weights=[0.99, 0.01], n_samples=1000, random_state=42)
print('Original class distribution:', Counter(y))# Train a cost-sensitive decision tree
model = DecisionTreeClassifier(class_weight={0: 1, 1: 10}, random_state=42)
model.fit(X, y)# Evaluate the model
y_pred = model.predict(X)
print(classification_report(y, y_pred))
5.平衡随机森林

平衡随机森林是在随机森林的基础上改进的一种方法,针对不平衡数据集做了优化。

它通过在构建每棵决策树时,对多数类进行随机欠采样,确保每棵树的训练集都是平衡的。同时,它结合了随机森林的特性,通过多个弱分类器的集成来提高整体的预测能力。

优点

  • 保留了随机森林的优势,如高准确性和鲁棒性。

  • 对多数类进行欠采样,能够减少模型对多数类的偏向,提高对少数类的预测能力。

  • 集成多个决策树,具有较强的泛化能力,减少了单一模型的偏差。

缺点

  • 相比于传统随机森林,平衡随机森林的计算成本更高,因为需要对多数类进行多次欠采样。

  • 欠采样过程中可能丢失多数类的重要信息,影响模型的整体表现。

from imblearn.ensemble import BalancedRandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score# Split the data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# Train a Balanced Random Forest model
brf = BalancedRandomForestClassifier(random_state=42)
brf.fit(X_train, y_train)# Evaluate
y_pred = brf.predict(X_test)
print('Balanced Random Forest Accuracy:', accuracy_score(y_test, y_pred))

THE END !

文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

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

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

相关文章

08 Oracle数据库故障应对与恢复策略:全面掌握RMAN恢复方法

文章目录 Oracle数据库故障应对与恢复策略:全面掌握RMAN恢复方法一、故障场景及恢复策略1.1 实例失败1.2 介质故障1.3 数据丢失 二、RMAN恢复方法详解2.1 全库恢复2.2 增量恢复2.3 时间点恢复 三、实践与总结 Oracle数据库故障应对与恢复策略:全面掌握RM…

线段树专题(1)

线段树 线段树可维护的信息类型 线段树可以维护的信息类型,父范围上的某个信息,可以用O(1)的时间,从子范围的信息加工得到,例如求某个范围的最大最小值,给某个范围每个位置加相同的数字,进行求和。 0到2范…

Linux应用开发基础知识——tslib应用编程(十一)

文章目录 一、tslib是啥?二、tslib 框架分析三、交叉编译、测试 tslib3.1、交叉编译tslib(1)设置交叉编译工具链(2)进入tslib目录(3)安装工具链(4)确定工具链中头文件、库…

MySQL必会知识精华6(组合WHERE子句)

我们的目标是:按照这一套资料学习下来,大家可以完成数据库增删改查的实际操作。同时轻松应对面试或者笔试题中MySQL相关题目。 上篇文章我们先做一下数据库的where条件过滤的方法,都是单个条件的过滤。本篇文章主要介绍查询的组合WHERE子句的…

系统架构师2023版:习题

架构设计基础 计算机基础 目前处理器市场中存在 CPU 和 DSP 两种类型的处理器,分别用于不同的场景,这两种处理器具有不同的体系结构,DSP采用()。 A.冯诺依曼结构 B.哈佛结构 C.FPGA 结构 D.与 GPU 相同的结构 解析:…

企微SCRM价格解析及其性价比分析

内容概要 在如今的数字化时代,企业对于客户关系管理的需求日益增长,而企微SCRM(Social Customer Relationship Management)作为一款新兴的客户管理工具,正好满足了这一需求。本文旨在为大家深入解析企微SCRM的价格体系…

RocketMQ学习笔记

RocketMQ笔记 文章目录 一、引言⼆、RocketMQ介绍RocketMQ的由来 三、RocketMQ的基本概念1 技术架构2 部署架构 四、快速开始1.下载RocketMQ2.安装RocketMQ3.启动NameServer4.启动Broker5.使⽤发送和接收消息验证MQ6.关闭服务器 五、搭建RocketMQ集群1.RocketMQ集群模式2.搭建主…

基于AI大模型开发应用层产品经典解决方案:ASR+LLM+TTS

在 AI 大模型开发领域,ASR(自动语音识别)LLM(大语言模型)TTS(语音合成)的解决方案是一种将语音输入、语言理解和语音输出整合在一起的技术架构,能够实现智能的语音交互应用。 方案介…

tree-transfer-vue3插件(树形数据穿梭框)

tree-transfer-vue3 效果图 简介 tree-transfer-vue3 是一个基于 VUE 和 element-plus 的树形穿梭框组件,使用前请确认已经引入element-plus! 此组件功能类似于element-plus的transfer组件,但是里面的数据是树形结构! 实际上&am…

临床检验方法与仪器 第一部分作业:光谱分析仪器与技术的总结与归纳+新型光谱仪的调研

临床检验方法与仪器 第一部分作业 列表归纳紫外-可见分光光度计、荧光光谱分析仪、原子吸收光谱仪、原子发射光谱仪的原理、特点、技术优势和主要应用对象;调研新型光谱仪,每一类至少提供1个例子,列出图片、厂家、型号、主要技术特点和优势。…

Linux系统编程-多线程线程属性

如何查看有那些多线程系统调用属性api 线程属性系统api举例 /* int pthead_attr_init(pthread_attr_t *attr); -对属性变量初始化int pthread_attr_destroy(pthread_attr_t *attr); -使用完毕需要销毁int pthread_attr_getdetachstate(const pthread_attr_t *attr, int*detach…

LVGL加入外围字库

一、首先lvgl是有自带字库的 lvgl/src/font 如下图 二、但如果这个字库不能满足我们的需求我们就要外建字库。 1、字库生成软件LVGL官网,字体转换器 — LVGL如下图: 最后按“提交”就可以看到有一个字体被下载到你电脑里。他是以.c文件的型式,把它COPY到lvgl的根目录下 2、…

【Steam登录】protobuf协议逆向

https://api.steampowered.com/IAuthenticationService/GetPasswordRSAPublicKey/v1 搜索 input_protobuf_encoded定位 input_protobuf_encoded的值就是 o s r.SerializeBody() o i.iI(s) 精准定位 打上条件断点:t ‘Authentication.GetPasswordRSAPublicKey…

ML 系列:第 21 节 — 离散概率分布(二项分布)

一、说明 二项分布描述了在固定数量的独立伯努利试验中一定数量的成功的概率,其中每个试验只有两种可能的结果(通常标记为成功和失败)。 二、探讨伯努利模型 例如,假设您正在抛一枚公平的硬币 (其中正面成功&#xff…

【模拟集成电路】知识点笔记_1

知识点笔记_1 零极点相关1 PM和GM相关概念2零极点 温度系数五种常见噪声源MOS管和BJT选取BJT刨面图工艺角衬底主要噪声来源共模反馈三种常用CMFB1 工作在线性区MOS作为CMFB(匹配决定输出电压)2 电阻反馈(Buf)3 电流差分对&#xf…

资产管理:SpringBoot框架的高效解决方案

6系统测试 6.1概念和意义 测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个…

Redis - 集群(Cluster)

一、基本概念 上述的哨兵模式,提⾼了系统的可⽤性.但是真正⽤来存储数据的还是master和slave节点.所有的数 据都需要存储在单个master和slave节点中. 如果数据量很⼤,接近超出了master/slave所在机器的物理内存,就可能出现严重问题了. 如何获取更⼤的空间?加机器即可!所谓&q…

基于springboot的高校科研管理系统(源码+调试+LW)

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据你想解决的问题,今天给…

pwn学习笔记(11)--off_by_one

pwn学习笔记&#xff08;11&#xff09;–off_by_one ​ 在处理for循环或者while循环的时候&#xff0c;有的可能会遇到如下情况&#xff1a; #include<stdio.h>int main(){char buf[0x10];for (int i 0 ; i < 0x10 ; i ){buf[i] getchar();}puts(buf);}​ 多次输…

YOLOv8模型改进 第十九讲 添加倒置残差移动块iRMB(Inverted Residual Mobile Block,) 去除图像噪声

本文这次分享的是倒置残差移动块iRMB&#xff0c;iRMB&#xff08;Inverted Residual Mobile Block&#xff09;的作用主要是在神经网络中实现高效的特征提取&#xff0c;它融合了卷积神经网络&#xff08;CNN&#xff09;捕捉局部特征的高效性和 Transformer 动态建模长距离交…