前言
对于整个数据建模来看,数据均衡算法属于数据预处理一环。当整个数据集从调出数据库到拿到手的时候,对于分类数据集来说类别一般都是不均衡的,整个数据集合也是较为离散的。因此不可能一拿到数据集就可进行建模,类别的不均衡会极大影响建模判断准确率。其中我们希望整个数据集合的类别数目都是相似的,这样其特征数据权重能够更好的计算出来,便于分类。对于预测模型也是如此。数据均衡是整个数学建模以及研究最重要不得不重视的一环,下面我将详细介绍数据均衡的方法以及运用的不同场景。
一、为什么要做数据均衡?
首先在进行实验之前我们要了解数据均衡的重要性,这是一件值得我们去投入众多精力的事。一旦数据均衡做的不好将极大可能影响模型的准确性。数据预处理决定我们模型的上限,在一些重要的数学建模比赛或者是SCI论文中,数据均衡绝对是浓墨重彩的一环。我们可以这样思考:
我们现在需要对一种疾病进行甄别,该病的发病概率为2%,而且很严重,100个人之间就可能会有2个人携带病毒。现在我们需要根据该病的特征数据构建能够判断患病的人。如果我们不进行数据均衡,倘若我们获得了10000份人的检测指标数据,其中有200人被标记为患病。那么我们立刻进行建模,因为患病人群数量极少,那么模型根据每一次特征权重计算反复迭代,获取最优的结果。那该模型为何不直接把判断人员数据归为健康人群呢。这样一来不管是判断的人群是否有无此病都能够得到98%的正确率甚至更高。那么我们的模型意义何在?
若是根据这个模型,再给10份数据其中有5份是患病者数据,那么此时建立的模型丝毫没有用处,甚至造成严重的后果。所以说数据均衡是整个建模中很重要的一环。如果我们一开始就把这200份患病者的指标进行数据填充与健康数据均衡,那样我们还能够发现获得该病之后的指标显著特征,为后续医生的判断提供有力的支持。因此数据均衡是必不可少的一环,现在让我们来了解根据数据集场景的不同我们该如何进行数据均衡。
二、数据场景
1.大数据分布不均衡
拿两个我所遇到过的场景建模来说,第一个网络用户购买行为数据集来说。共拥有
十三万行的数据中仅3千条用户购买行为数据 ,这样大数据量的不均衡情况就为大数据量不均衡。
2.小数据分布不均衡
大数据量的不均衡情况居多,但难免有一些指标很难测量的场景。就如医学疾病检测。
该数据量小,仅有一万数据量,患病人数仅只有百名。这样的数据情况就为小数据分布不均衡。
这两类数据不均衡情况都有适合它们的处理算法。
三、均衡算法类型
在机器学习和深度学习中两者含义不同,但是思想方法类似。一个为数据中的采样方法,一个为图片的缩小和放大。这里重点解释机器学习的采样类型。
1.过采样
过采样也被称为上采样,这个方法更适用于小数据分布不均衡。如果是大数据分布不均衡,则将原来的小份类别不同的数据集扩充到与类别不同的数据集对等大小的情况。如第一个例子的数据,若进行过采样,则将会有超过26万的数据生成。与欠采样相比计算权重比例以及运算时间都会大大增加。甚至可能造成过拟合现象。而小数据分布不均衡运用该方法还能避免数据量太少引起的欠拟合。
以下是过采样效果图,图一为原始数据集。
2.欠采样
欠采样也被称为下采样,一般将将较大的类别数据进行缩减,直至和类型不同的小量数据集相对等。如我们将例子一的数据进行欠采样,13w的用户行为数据将缩减至6730条数据,进行建模的速度将会大大的加快。
以下是欠采样算法效果图:
3.组合采样
不论是过采样和欠采样都会与原数据集存在一定的误差,过采样会导致很多样本的数据特征与原样本数据重叠导致难以分类清楚。而数据清洗技术恰好可以处理掉重叠样本,所以可以将二者结合起来形成一个组合采样,先过采样再进行数据清洗。
四、算法具体种类
以Imbalancd sklearn库收录的算法来看,过采样共有11种方法,欠采样共有8种方法,组合采样有2种方法。
资源下载:机器学习之数据均衡算法种类大全+Python代码一文详解
下面我们将从过采样-欠采样-组合采样大体三个类型的算法逐个了解其重算法种类的大致功能作用,以及使用场景:
1.欠采样算法:
(1).RandomUnderSampler
随机欠采样是十分快捷的方式,从多数类样本中随机选取一些剔除掉。但是随着采样方法的研究和发展随机欠采样已经很少使用。随机欠采样会损失大量的数据,可能被剔除的样本可能包含着一些重要信息,导致后续建模模型质量并不是很好。
from imblearn.under_sampling import RandomUnderSampler X, y = create_dataset(n_samples=400, weights=(0.05, 0.15, 0.8), class_sep=0.8) samplers = { FunctionSampler(), # identity resampler RandomUnderSampler(random_state=0), } fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(15, 15)) for ax, sampler in zip(axs, samplers): model = make_pipeline(sampler, clf).fit(X, y) plot_decision_function( X, y, model, ax[0], title=f"Decision function with {sampler.__class__.__name__}" ) plot_resampling(X, y, sampler, ax[1]) fig.tight_layout()
(2).ClusterCentroids
通过使用K-Means聚类质心代替一个多数类的聚类,从而对多数类进行欠采样。通过带有N个聚类的KMeans算法拟合到多数类,并以N个聚类质心的坐标作为新的多数样本,从而保留N个多数样本。这和K-means方法原理是一样的
import matplotlib.pyplot as plt from imblearn import FunctionSampler from imblearn.pipeline import make_pipeline from imblearn.under_sampling import ClusterCentroids X, y = create_dataset(n_samples=400, weights=(0.05, 0.15, 0.8), class_sep=0.8) samplers = { FunctionSampler(), # identity resampler ClusterCentroids(random_state=0), } fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(15, 15)) for ax, sampler in zip(axs, samplers): model = make_pipeline(sampler, clf).fit(X, y) plot_decision_function( X, y, model, ax[0], title=f"Decision function with {sampler.__class__.__name__}" ) plot_resampling(X, y, sampler, ax[1]) fig.tight_layout()
(4).EditedNearestNeighbours
(5).RepeatedEditedNearestNeighbours
EditedNearestNeighbours删除其类别与其最近邻之一不同的多数类别的样本。这就是原理 RepeatedEditedNearestNeighbours。 通过更改内部最近邻算法的参数,在每次迭代中增加它,与AllKNN略有不同 。
from imblearn.under_sampling import ( EditedNearestNeighbours, RepeatedEditedNearestNeighbours, AllKNN, ) X, y = create_dataset(n_samples=500, weights=(0.2, 0.3, 0.5), class_sep=0.8) samplers = [ EditedNearestNeighbours(), RepeatedEditedNearestNeighbours(), AllKNN(allow_minority=True), ] fig, axs = plt.subplots(3, 2, figsize=(15, 25)) for ax, sampler in zip(axs, samplers): model = make_pipeline(sampler, clf).fit(X, y) plot_decision_function( X, y, clf, ax[0], title=f"Decision function for \n{sampler.__class__.__name__}" ) plot_resampling( X, y, sampler, ax[1], title=f"Resampling using \n{sampler.__class__.__name__}" ) fig.tight_layout()