处理大型不平衡数据集

数据挖掘 Python 大数据 多类分类 阶级失衡
2022-03-06 08:53:22

我有一个不平衡的数据集,由大约 10 百万个文本字符串组成,每个字符串都有数千个由 uni- 和 bigram 创建的特征,此外,我还有字符串长度和字符串的熵作为特征。

它是一个multiclass数据集(40-50 个类别),但它是不平衡的。与最大的类相比,某些类可以小 1000 倍。我已将数据限制为每个类最多 100 万个字符串,否则不平衡可能会更大。

因此,我想使用过采样来改善代表性不足的类的数据。我已经查看ADASYNSMOTEpythonimblearn包。但是当我运行它时,进程会耗尽我RAM在交换内存中的所有内容,并且在进程被杀死后不久。我假设是因为内存不够。

我现在的问题是如何最好地进行。显然我的数据太大而不能被过度采样。我想到了两个选项,但我无法确定哪个是最“正确”的。

  • 我只派了一个人数不足的班级和最大的班级,并为每个人数不足的班级重复了这一点。我不确定这是否意味着类可能开始重叠。

  • 相反,我对数据进行了欠采样,每类可能低至 10 万个样本。这可能会减少足够的数据,以便我可以对较少表示的类(使用 1k-10k 样本)进行过采样。

我错过了其他更合适的选择吗?

3个回答

有多种选择,具体取决于您的问题和您要使用的算法。最有希望(或最接近您的原始计划)是使用生成器来准备批量训练数据。这仅对允许部分拟合的模型有用,例如神经网络。您的生成器可以通过例如生成包含每个目标中的一个的批次来对示例进行分层。一个时代是你为最大班级的所有样本提供服务。

下采样不是一个坏主意,但这取决于您任务的难度,因为您最终会丢弃信息。您可以根据模型的样本数量查看一些曲线,如果它看起来相对上限,这不会是一个大问题。

许多模型允许在您的损失函数中加权类。如果我们有 10,000 个 A 类和 1,000 个 B 类,我们可以将 B 类加权 10 倍,这意味着这样的错误更难计数,并且它将相对更多地关注 B 类的样本。你可以试试这个,但我可以看到这会发生极端不平衡是错误的。

您甚至可以组合这些方法,对最大的类进行下采样,对较小的类进行上采样,并使用权重来完美平衡它们。

编辑:批处理选项的示例:

我们有 4x A、2x B 和 1x C,所以我们的集合是:

A1 A2 A3 A4 B1 B2 C1

定期上采样将转到:

A1 A2 A3 A4 B1 B2 B1 B2 C1 C1 C1 C1

但这不适合我们在大数据环境中的记忆。相反,我们所做的只是将原始数据存储在内存中(甚至可以在磁盘上)并跟踪每个类的位置(因此它们在目标上是分开的)。

A: A1 A2 A3 A4 B: B1 B2 C: C1

我们的第一批每个班级都有一个:

A1 B1 C1

现在我们的 C 类是空的,这意味着我们重新初始化它,打乱它们(在这种情况下它只是一个例子)。

A: A2 A3 A4 B: B2 C: C1

下一批:

A2 B2 C1

B 和 C 是空的,重新初始化它们并洗牌:

A: A3 A4 B: B2 B1 C: C1

下一批是:

A3 B2 C1

我们的最后一个时代将是 A4 B1 C1

如您所见,我们与完整内存选项具有相同的分布,但我们从未保留比原始内存更多的内存,并且模型始终保持平衡、分层的批次。

分析的目的是什么?主要兴趣(准确性)的标准是什么?

类别不平衡问题源于少数类别的数据不足,无法充分表征其分布。这意味着只有当你有一个小数据集时,不平衡才是一个问题,如果你有很多数据,不平衡问题通常会自行解决,重新采样数据集可能会使事情变得更糟而不是更好。

我怀疑所选答案的有效性,因为给定的示例完全忽略了这样一个事实,即采样过程不会简单地生成更多不常见示例的副本,而是使用更复杂的东西,例如找到最近的邻居。

我认为很可能是后一个计算成本高的过程(最近邻计算)导致了内存问题。我认为制作多个副本的简单过程不会产生与原始算法预期相同的效果。