广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python中怎么解决非平衡数据问题
  • 150
分享到

Python中怎么解决非平衡数据问题

2023-06-17 02:06:21 150人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

python中怎么解决非平衡数据问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。SMOTE算法的介绍在实际应用中,读者可能会碰到一种比较头疼的问题,那就是分类

python中怎么解决非平衡数据问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

SMOTE算法的介绍

在实际应用中,读者可能会碰到一种比较头疼的问题,那就是分类问题中类别型的因变量可能存在严重的偏倚,即类别之间的比例严重失调。如欺诈问题中,欺诈类观测在样本集中毕竟占少数;客户流失问题中,非忠实的客户往往也是占很少一部分;在某营销活动的响应问题中,真正参与活动的客户也同样只是少部分。

如果数据存在严重的不平衡,预测得出的结论往往也是有偏的,即分类结果会偏向于较多观测的类。对于这种问题该如何处理呢?最简单粗暴的办法就是构造1:1的数据,要么将多的那一类砍掉一部分(即欠采样),要么将少的那一类进行Bootstrap抽样(即过采样)。但这样做会存在问题,对于***种方法,砍掉的数据会导致某些隐含信息的丢失;而第二种方法中,有放回的抽样形成的简单复制,又会使模型产生过拟合。

为了解决数据的非平衡问题,2002年Chawla提出了SMOTE算法,即合成少数过采样技术,它是基于随机过采样算法的一种改进方案。该技术是目前处理非平衡数据的常用手段,并受到学术界和工业界的一致认同,接下来简单描述一下该算法的理论思想。

SMOTE算法的基本思想就是对少数类别样本进行分析和模拟,并将人工模拟的新样本添加到数据集中,进而使原始数据中的类别不再严重失衡。该算法的模拟过程采用了KNN技术,模拟生成新样本的步骤如下:

  • 采样最邻近算法,计算出每个少数类样本的K个近邻;

  • 从K个近邻中随机挑选N个样本进行随机线性插值;

  • 构造新的少数类样本;

  • 将新样本与原数据合成,产生新的训练集;

为了使读者理解SMOTE算法实现新样本的模拟过程,可以参考下图和人工新样本的生成过程:

Python中怎么解决非平衡数据问题

如上图所示,实心圆点代表的样本数量要明显多于五角星代表的样本点,如果使用SMOTE算法模拟增加少类别的样本点,则需要经过如下几个步骤:

  • 利用KNN算法,选择离样本点x1最近的K个同类样本点(不妨最近邻为5);

  • 从最近的K个同类样本点中,随机挑选M个样本点(不妨M为2),M的选择依赖于最终所希望的平衡率;

  • 对于每一个随机选中的样本点,构造新的样本点;新样本点的构造需要使用下方的公式:

Python中怎么解决非平衡数据问题

其中,xi表示少数类别中的一个样本点(如图中五角星所代表的x1样本);xj表示从K近邻中随机挑选的样本点j;rand(0,1)表示生成0~1之间的随机数。

假设图中样本点x1的观测值为(2,3,10,7),从图中的5个近邻中随机挑选2个样本点,它们的观测值分别为(1,1,5,8)和(2,1,7,6),所以,由此得到的两个新样本点为:

Python中怎么解决非平衡数据问题
  • 重复步骤1)、2)和3),通过迭代少数类别中的每一个样本xi,最终将原始的少数类别样本量扩大为理想的比例;

通过SMOTE算法实现过采样的技术并不是太难,读者可以根据上面的步骤自定义一个抽样函数。当然,读者也可以借助于imblearn模块,并利用其子模块over_sampling中的SMOTE“类”实现新样本的生成。有关该“类”的语法和参数含义如下:

SMOTE(ratio=’auto’, random_state=None, k_neighbors=5, m_neighbors=10,      out_step=0.5, kind=’regular’, svm_estimator=None, n_jobs=1)
  • ratio:用于指定重抽样的比例,如果指定字符型的值,可以是’minority’,表示对少数类别的样本进行抽样、’majority’,表示对多数类别的样本进行抽样、’not  minority’表示采用欠采样方法、’all’表示采用过采样方法,默认为’auto’,等同于’all’和’not  minority’;如果指定字典型的值,其中键为各个类别标签,值为类别下的样本量;

  • random_state:用于指定随机数生成器的种子,默认为None,表示使用默认的随机数生成器;

  • k_neighbors:指定近邻个数,默认为5个;

  • m_neighbors:指定从近邻样本中随机挑选的样本个数,默认为10个;

  • kind:用于指定SMOTE算法在生成新样本时所使用的选项,默认为’regular’,表示对少数类别的样本进行随机采样,也可以是’borderline1’、’borderline2’和’svm’;

  • svm_estimator:用于指定SVM分类器,默认为sklearn.svm.SVC,该参数的目的是利用支持向量机分类器生成支持向量,然后再生成新的少数类别的样本;

  • n_jobs:用于指定SMOTE算法在过采样时所需的CPU数量,默认为1表示仅使用1个CPU运行算法,即不使用并行运算功能;

分类算法的应用实战

本次分享的数据集来源于德国某电信行业的客户历史交易数据,该数据集一共包含条4,681记录,19个变量,其中因变量churn为二元变量,yes表示客户流失,no表示客户未流失;剩余的自变量包含客户的是否订购国际长途套餐、语音套餐、短信条数、话费、通话次数等。接下来就利用该数据集,探究非平衡数据转平衡后的效果。

# 导入第三方包 import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn import model_selection from sklearn import tree from sklearn import metrics from imblearn.over_sampling import SMOTE # 读取数据churn = pd.read_excel(r'C:\Users\Administrator\Desktop\Customer_Churn.xlsx') churn.head()
Python中怎么解决非平衡数据问题
# 中文乱码的处理 plt.rcParams['font.sans-serif']=['Microsoft YaHei']  # 为确保绘制的饼图为圆形,需执行如下代码 plt.axes(aspect = 'equal') # 统计交易是否为欺诈的频数 counts = churn.churn.value_counts()  # 绘制饼图 plt.pie(x = counts, # 绘图数据         labels=pd.Series(counts.index).map({'yes':'流失','no':'未流失'}), # 添加文字标签         autopct='%.2f%%' # 设置百分比的格式,这里保留一位小数        ) # 显示图形 plt.show()
Python中怎么解决非平衡数据问题

如上图所示,流失用户仅占到8.3%,相比于未流失用户,还是存在比较大的差异的。可以认为两种类别的客户是失衡的,如果直接对这样的数据建模,可能会导致模型的结果不够准确。不妨先对该数据构建随机森林模型,看看是否存在偏倚的现象。

原始数据表中的state变量和Area_code变量表示用户所属的“州”和地区编码,直观上可能不是影响用户是否流失的重要原因,故将这两个变量从表中删除。除此,用户是否订购国际长途业务international_plan和语音业务voice_mail_plan,属于字符型的二元值,它们是不能直接代入模型的,故需要转换为0-1二元值。

# 数据清洗 # 删除state变量和area_code变量 churn.drop(labels=['state','area_code'], axis = 1, inplace = True)  # 将二元变量international_plan和voice_mail_plan转换为0-1哑变量 churn.international_plan = churn.international_plan.map({'no':0,'yes':1}) churn.voice_mail_plan = churn.voice_mail_plan.map({'no':0,'yes':1}) churn.head()
Python中怎么解决非平衡数据问题

如上表所示,即为清洗后的干净数据,接下来对该数据集进行拆分,分别构建训练数据集和测试数据集,并利用训练数据集构建分类器,测试数据集检验分类器:

# 用于建模的所有自变量 predictors = churn.columns[:-1] # 数据拆分为训练集和测试集 X_train,X_test,y_train,y_test = model_selection.train_test_split(churn[predictors], churn.churn, random_state=12)  # 构建决策树 dt = tree.DecisionTreeClassifier(n_estimators = 300) dt.fit(X_train,y_train) # 模型在测试集上的预测 pred = dt.predict(X_test)  # 模型的预测准确率 print(metrics.accuracy_score(y_test, pred)) # 模型评估报告 print(metrics.classification_report(y_test, pred))
Python中怎么解决非平衡数据问题

如上结果所示,决策树的预测准确率超过93%,其中预测为no的覆盖率recall为97%,但是预测为yes的覆盖率recall却为62%,两者相差甚远,说明分类器确实偏向了样本量多的类别(no)。

# 绘制ROC曲线 # 计算流失用户的概率值,用于生成ROC曲线的数据 y_score = dt.predict_proba(X_test)[:,1] fpr,tpr,threshold = metrics.roc_curve(y_test.map({'no':0,'yes':1}), y_score)  # 计算AUC的值 roc_auc = metrics.auc(fpr,tpr) # 绘制面积图 plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black') # 添加边际线 plt.plot(fpr, tpr, color='black', lw = 1) # 添加对角线 plt.plot([0,1],[0,1], color = 'red', linestyle = '--') # 添加文本信息 plt.text(0.5,0.3,'ROC curve (area = %0.3f)' % roc_auc) # 添加x轴与y轴标签 plt.xlabel('1-Specificity') plt.ylabel('Sensitivity') # 显示图形 plt.show()
Python中怎么解决非平衡数据问题

如上图所示,ROC曲线下的面积为0.79***UC的值小于0.8,故认为模型不太合理。(通常拿AUC与0.8比较,如果大于0.8,则认为模型合理)。接下来,利用SMOTE算法对数据进行处理:

# 对训练数据集作平衡处理 over_samples = SMOTE(random_state=1234)  over_samples_X,over_samples_y = over_samples.fit_sample(X_train, y_train)  # 重抽样前的类别比例 print(y_train.value_counts()/len(y_train)) # 重抽样后的类别比例 print(pd.Series(over_samples_y).value_counts()/len(over_samples_y))
Python中怎么解决非平衡数据问题

如上结果所示,对于训练数据集本身,它的类别比例还是存在较大差异的,但经过SMOTE算法处理后,两个类别就可以达到1:1的平衡状态。下面就可以利用这个平衡数据,重新构建决策树分类器了:

# 基于平衡数据重新构建决策树模型 dt2 = ensemble.DecisionTreeClassifier(n_estimators = 300) dt2.fit(over_samples_X,over_samples_y) # 模型在测试集上的预测 pred2 =dt2.predict(np.array(X_test))  # 模型的预测准确率 print(metrics.accuracy_score(y_test, pred2)) # 模型评估报告 print(metrics.classification_report(y_test, pred2))
Python中怎么解决非平衡数据问题

如上结果所示,利用平衡数据重新建模后,模型的准确率同样很高,为92.6%(相比于原始非平衡数据构建的模型,准确率仅下降1%),但是预测为yes的覆盖率提高了10%,达到72%,这就是平衡带来的好处。

# 计算流失用户的概率值,用于生成ROC曲线的数据 y_score = rf2.predict_proba(np.array(X_test))[:,1] fpr,tpr,threshold = metrics.roc_curve(y_test.map({'no':0,'yes':1}), y_score) # 计算AUC的值 roc_auc = metrics.auc(fpr,tpr) # 绘制面积图 plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black') # 添加边际线 plt.plot(fpr, tpr, color='black', lw = 1) # 添加对角线 plt.plot([0,1],[0,1], color = 'red', linestyle = '--') # 添加文本信息 plt.text(0.5,0.3,'ROC curve (area = %0.3f)' % roc_auc) # 添加x轴与y轴标签 plt.xlabel('1-Specificity') plt.ylabel('Sensitivity')  # 显示图形 plt.show()
Python中怎么解决非平衡数据问题

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网Python频道,感谢您对编程网的支持。

--结束END--

本文标题: Python中怎么解决非平衡数据问题

本文链接: https://www.lsjlt.com/news/286868.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python中怎么解决非平衡数据问题
    Python中怎么解决非平衡数据问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。SMOTE算法的介绍在实际应用中,读者可能会碰到一种比较头疼的问题,那就是分类...
    99+
    2023-06-17
  • windows堆栈平衡问题怎么解决
    解决Windows堆栈平衡问题的方法取决于具体的情况和根因。以下是一些可能的解决方法:1. 检查代码中的递归调用:如果代码中存在递归...
    99+
    2023-10-18
    windows
  • 解决R语言 数据不平衡的问题
    R语言解决数据不平衡问题 一、项目环境 开发工具:RStudio R:3.5.2 相关包:dplyr、ROSE、DMwR 二、什么是数据不平衡?为什么要处理数据不平衡? 首先我们要知...
    99+
    2022-11-11
  • C语言平衡二叉树问题怎么解决
    这篇文章主要介绍“C语言平衡二叉树问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C语言平衡二叉树问题怎么解决”文章能帮助大家解决问题。一、题目描述给定一个二叉树,判断它是否是高度平衡的二...
    99+
    2023-06-30
  • Python中怎么处理不平衡数据集
    本篇文章给大家分享的是有关Python中怎么处理不平衡数据集,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1. 什么是数据不平衡所谓的数据不平衡(imbalanced data...
    99+
    2023-06-15
  • Oracle删除数据非常慢的问题及解决
    目录oracle删除数据非常慢问题描述处理流程Oracle删除表中大量数据卡顿的解决正确姿势总结Oracle删除数据非常慢 记一次数据库删除数据非常慢的处理流程 问题描述 单表数据3000条左右,根据主键删除需要509秒...
    99+
    2023-02-15
    Oracle删除数据 删除数据慢 Oracle数据删除
  • Java非法字符: ‘\ufeff‘问题怎么解决
    这篇“Java非法字符: ‘\ufeff‘问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java非法字...
    99+
    2023-07-05
  • MongoDB技术开发中遇到的数据分片平衡问题解决方案分析
    MongoDB技术开发中遇到的数据分片平衡问题解决方案分析,需要具体代码示例摘要:在使用MongoDB进行大规模数据存储时,数据分片是必不可少的技术手段。然而,在数据量增长的过程中,由于数据分片的不均衡或者其他原因,可能会导致数据分片的不平...
    99+
    2023-10-22
    MongoDB 数据分片 平衡问题解决方案
  • R语言中数据不平衡如何解决
    R语言中数据不平衡如何解决?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、项目环境开发工具:RStudioR:3.5.2相关包:dplyr、ROSE、DMwR二、什么是数据不...
    99+
    2023-06-15
  • Python数据传输黏包问题怎么解决
    本篇内容主要讲解“Python数据传输黏包问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python数据传输黏包问题怎么解决”吧!1.socket黏包问题原理黏包:指数据与数据之间没...
    99+
    2023-06-30
  • Python+OpenCV怎么解决彩色图亮度不均衡问题
    这篇文章主要介绍“Python+OpenCV怎么解决彩色图亮度不均衡问题”,在日常操作中,相信很多人在Python+OpenCV怎么解决彩色图亮度不均衡问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Pyt...
    99+
    2023-06-22
  • 负载均衡带宽问题怎么解决
    解决负载均衡带宽问题可以从以下几个方面入手:1. 增加带宽:可以联系网络服务提供商,升级带宽套餐或者增加带宽容量,以提高网络传输速度...
    99+
    2023-09-01
    负载均衡
  • Python解决非线性规划中经济调度问题
    目录1、概述2、scipy.optimize.minimize参数3、简单案例引出(1)Scipy.optimize实现(2)遗传算法包实现 (—sko.GA&...
    99+
    2022-11-10
  • Mysql怎么数据库平滑扩容解决高并发和大数据量问题
    本篇内容主要讲解“Mysql怎么数据库平滑扩容解决高并发和大数据量问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Mysql怎么数据库平滑扩容解决高并发和大数据量问题”吧!1 停机方案发布公告...
    99+
    2023-06-30
  • Python大数据量文本文件问题怎么解决
    这篇文章主要介绍“Python大数据量文本文件问题怎么解决”,在日常操作中,相信很多人在Python大数据量文本文件问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python大数据量文本文件问题怎...
    99+
    2023-07-04
  • kafka怎么解决数据堆积问题
    Kafka是一种分布式的流处理平台,可以高效地处理大量的数据流。解决数据堆积问题,可以通过以下几种方式:1. 增加消费者数量:可以通...
    99+
    2023-10-21
    kafka
  • 怎么解决数据库ORA-00837问题
    本篇内容介绍了“怎么解决数据库ORA-00837问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 解决...
    99+
    2022-10-19
  • 怎么解决MySQL误删数据问题
    本篇内容主要讲解“怎么解决MySQL误删数据问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么解决MySQL误删数据问题”吧!第一步:保证mysql已经开启...
    99+
    2022-10-18
  • 怎么解决数据库变慢问题
    这篇文章主要介绍“怎么解决数据库变慢问题”,在日常操作中,相信很多人在怎么解决数据库变慢问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么解决数据库变慢问题”的疑惑有所帮...
    99+
    2022-10-18
  • Redis热点数据问题怎么解决
    这篇文章主要介绍“Redis热点数据问题怎么解决”,在日常操作中,相信很多人在Redis热点数据问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Redis热点数据问...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作