所谓的数据不平衡(imbalanced data)是指数据集中各个类别的数量分布不均衡;不平衡数据在现实任务中十分的常见。如
不平衡数据一般是由于数据产生的原因导致的,类别少的样本通常是发生的频率低,需要很长的周期进行采集。
在机器学习任务(如分类问题)中,不平衡数据会导致训练的模型预测的结果会偏向于样本数量多的类别,这个时候除了要选择合适的评估指标外,想要提升模型的性能,就要对数据和模型做一些预处理。
处理数据不平衡的主要方法:
调整类别权重或者样本权重
imbalanced-learn库提供了许多不平衡数据处理的方法,本文的例子都以imbalanced-learn库来实现。
pip install -U imbalanced-learn
https://github.com/scikit-learn-contrib/imbalanced-learn
本文例子的数据来自进行中的比赛山东省第二届数据应用创新创业大赛-日照分赛场-公积金贷款逾期预测
先来看下数据
import pandas as pd train_data = './data/train.csv' test_data = './data/test.csv' train_df = pd.read_csv(train_data) test_df = pd.read_csv(test_data) print(train_df.groupby(['label']).size()) # label为是否违约, 1为违约, 0为非违约 # label # 0 37243 # 1 2757
所谓欠采样,就是将数量多类别(记为majority)的样本进行抽样,使之数量与数量少的类别(minority)的数量相当,以此达到数量的平衡。
由于欠采样是丢失了一部分数据,不可避免的使得数量多类别样本的分布发生了变化(方差变大)。好的欠采样策略应该尽可能保持原有数据分布。
欠采样是删除majority的样本,那哪些样本可以删除呢?
基于此,有两种思路来欠采样
下面这张图,展示6NN(6个最近邻居)
这里重点讲下TomekLinks, TomekLinks方法简单的说:对每一个minority样本找1NN(最近的邻居),如果最近的邻居是majority, 就形成一个tome-links,该方法人为这个majority是干扰的,将它删除。
from imblearn.under_sampling import TomekLinks X_train = train_df.drop(['id', 'type'], axis=1) y = train_df['label'] tl = TomekLinks() X_us, y_us = tl.fit_sample(X_train, y) print(X_us.groupby(['label']).size()) # label # 0 36069 # 1 2757
从上可知, 有1174个tomek-link被删除,好像删除还不够多,可以测试下是否对分类结果有帮助。需要注意的因为需要计算最近邻,所以样本属性必须数值属性,或者可以转化为数值属性。
这类方法通过多个聚类,把原始样本划分成多个聚类簇,然后用每个聚类簇的中心来代替这个聚类簇的特性,完成采样的目的。可知,这种采样的样本不是来自原始样本集,而是聚类生成的。
from imblearn.under_sampling import ClusterCentroids cc = ClusterCentroids(random_state=42) X_res, y_res = cc.fit_resample(X_train, y) X_res.groupby(['label']).size() # label # 0 2757 # 1 2757
im-balance提供的欠采样的方法如下:
所谓过采样,就是将数量少的类别(minority)的样本进行copy,使之数量与数量多的类别(majortity)的数量相当,以此达到数量的平衡。由于复制了多份minoruty样本,过采样会改变minority方差。
过采样一种简单的方式是随机copy minority的样本;另外一种是根据现有样本生成人造样本。这里介绍人造样本的经典算法SMOTE(Synthetic Minority Over-sampling Technique)。
SMOTE基于minority样本相似的特征空间构造新的人工样本。步骤如下:
from imblearn.over_sampling import SMOTE smote = SMOTE(k_neighbors=5, random_state=42) X_res, y_res = smote.fit_resample(X_train, y) X_res.groupby(['label']).size() # label # 0 37243 # 1 37243
对于SMOTE方法,对每一个minority都会构造新样本。但是并不总是这样的,考虑下面A,B,C三个点。从数据分布来看,C点很可能是一个异常点(Noise),B点是正常分布的点(SAFE),而A点分布在边界位置(DANGER);
直观上,对于C点我们不应该去构造新样本,对B点,构造新样本不会丰富minority类别的分布。只有A点,如果构造新样本能够使得A点从(DANGER)到(SAFE),加强minority类别的分类边界。这个就是Borderline-SMOTE
from imblearn.over_sampling import BorderlineSMOTE bsmote = BorderlineSMOTE(k_neighbors=5, random_state=42) X_res, y_res = bsmote.fit_resample(X_train, y) X_res.groupby(['label']).size() # label # 0 37243 # 1 37243
ADASYN方法从保持样本分布的角度来确定生成数据,生成数据的方式和SMOTE是一样的,不同在于每个minortiy样本生成样本的数量不同。
from imblearn.over_sampling import ADASYN adasyn = ADASYN(n_neighbors=5, random_state=42) X_res, y_res = adasyn.fit_resample(X_train, y) X_res.groupby(['label']).size() # label # 0 37243 # 1 36690
im-balance提供的过采样的方法如下(包括SMOTE算法的变种):
过采样是针对minority样本,欠采样是针对majority样本;而综合采样是既对minority样本,又对majority样本,同时进行操作的方法。主要有SMOTE+Tomek-links和SMOTE+Edited Nearest Neighbours。
综合采样的方法,是先进行过采样,在进行欠采样。
from imblearn.combine import SMOTETomek smote_tomek = SMOTETomek(random_state=0) X_res, y_res = smote_tomek.fit_sample(X_train, y) X_res.groupby(['label']).size() # label # 0 36260 # 1 36260
这里的模型集成主要体现在数据上,即用众多平衡的数据集(majortiry的样本进行欠采样加上minority样本)训练多个模型,然后进行集成。imblearn.ensemble提供几种常见的模型集成算法,如BalancedRandomForestClassifier
from imblearn.ensemble import BalancedRandomForestClassifier from sklearn.datasets import make_classification X, y = make_classification(n_samples=1000, n_classes=3, n_informative=4, weights=[0.2, 0.3, 0.5], random_state=0) clf = BalancedRandomForestClassifier(max_depth=2, random_state=0) clf.fit(X, y) print(clf.feature_importances_) print(clf.predict([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]))
im-balance提供的模型集成的方法如下
对于很多用梯度下降方法来学习(使得某个损失Loss最小)的机器学习的方法,可以通过调整类别权重或样本权重的方式,来一定程度上平衡不平衡数据。如gbdt模型lightgbm 中 class_weight
import lightgbm as lgb clf = lgb.LGBMRegressor(num_leaves=31, min_child_samples= np.random.randint(20,25), max_depth=25, learning_rate=0.1, class_weight={0:1, 1:10}, n_estimators=500, n_jobs=30)
本文分享了常见的几种处理不平衡数据集的方法,并且提供imbalanced-learn的简单例子。总结如下:
以上就是如何用 Python 处理不平衡数据集的详细内容,更多关于Python 处理不平衡数据集的资料请关注小牛知识库其它相关文章!
我面临的一个问题是KeyedStream在workers上是纯粹并行的,因为键的数量接近并行度 我的输入记录在0-N的范围内。当我使用keyBy时,有些工人处理零个键,有些则不止一个。这是因为在中对Key.HasCode使用murmurHash并选择通道。 我知道partitionCustom可以处理这种情况,但partitionCustom只返回数据流,而不是KeyStream。 那么我能做什么
本文向大家介绍如何解决数据不平衡问题?相关面试题,主要包含被问及如何解决数据不平衡问题?时的应答技巧和注意事项,需要的朋友参考一下 这主要是由于数据分布不平衡造成的。解决方法如下: 采样,对小样本进行加噪声采样,对大样本进行下采样 进行特殊的加权,如在Adaboost中或者SVM 采用对不平衡数据集不敏感的算法 改变评价标准:用AUC|ROC来进行评价 考虑数据的先验分布 https://blog
本文向大家介绍数据不平衡怎么办?相关面试题,主要包含被问及数据不平衡怎么办?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 使用正确的评估标准,当数据不平衡时可以采用精度,调用度,F1得分,MCC,AUC等评估指标。 重新采样数据集,如欠采样和过采样。欠采样通过减少冗余类的大小来平衡数据集。当数据量不足时采用过采样,尝试通过增加稀有样本的数量来平衡数据集,通过使用重复,自举,SMOTE等方
问题内容: 我有以下代码: 在这一行上: 我遇到了错误。 我究竟做错了什么? 问题答案: 括号在正则表达式中有特殊含义。您可以逃脱括号,但是 对于此问题,您实际上根本不需要正则表达式 :
本文向大家介绍如何使用Tensorflow和Python整理预处理的数据?,包括了如何使用Tensorflow和Python整理预处理的数据?的使用技巧和注意事项,需要的朋友参考一下 Tensorflow是Google提供的一种机器学习框架。它是一个开放源代码框架,与Python结合使用以实现算法,深度学习应用程序等等。它用于研究和生产目的。它具有优化技术,可帮助快速执行复杂的数学运算。这是因为它
我正在尝试用H2O(3.14)训练机器学习模型。我的数据集大小是4Gb,我的计算机RAM是2Gb,带有2G交换,JDK 1.8。参考本文,H2O可以使用2Gb RAM处理大型数据集。 关于大数据和GC的说明:当Java堆太满时,我们会进行用户模式的磁盘交换,即,您使用的大数据比物理DRAM多。我们不会因GC死亡螺旋而死亡,但我们会降级到核心外的速度。我们将以磁盘允许的速度运行。我个人测试过将12G
(自己模拟的数据效果) 如上路径动画,目前的问题是运行的坐标数据是依照地图来的 需要转换为画布能够展示的范围,但运行数据之前差别大部分情况下都很小 我要怎样处理会合适一点? help大佬们
问题内容: 我正在尝试训练数据不平衡的网络。我有A(198个样本),B(436个样本),C(710个样本),D(272个样本),并且我已经阅读了有关“weighted_cross_entropy_with_logits”的信息,但是我发现的所有示例都是针对二进制分类的,因此我不太了解对如何设置这些权重充满信心。 样本总数:1616 A_weight:198/1616 = 0.12? 如果我理解的话