用于大量类别的分类器和技术

数据挖掘 机器学习 大数据 数据集 scikit-学习 分类数据
2021-09-28 19:41:07

我正在为具有 5000 多个类别的序列标记任务设计一个 scikit 学习分类器,训练数据至少为 8000 万,并且每年可能会增长到额外的 1 亿。我已经尝试过所有类别,但它会生成大约 100 GB 二进制文件的分类器。所以我认为每个类别都有一个分类器会很有帮助,也可以帮助我微调每个类别的特征,从而提高准确性,但这意味着每个类别都有 5k+ 个分类器。那么如何处理这种大数据需求以及在这种情况下使用哪些增量分类器,考虑到我将继续获得额外的训练数据以及可能发现新类别的事实?

特征数量约为 100+,并且由于序列标记任务,训练样本的连续序列共享相同的特征值。特征值主要是基于文本的,并且大多数是分类的,具有大基数的基于长文本的值,即许多特征可能具有大量可能的值。

可用 RAM 为 32gb,带有 8 核 CPU。在小范围内,我尝试了多项式 NB 和线性 SGD,其稀疏矩阵非常稀疏。使用 scikit 学习 Dictvectorizer 对特征字典进行向量化。熊猫数据框也有助于优化整体配置吗?

由于涉及的数据规模,我只使用了大约 20% 的数据。而特征本身是来自 500MB 输入数据的 56GB 数据。对于受限的训练数据,精度也很低,没有达到 12% 以上,召回率也很低(1-2%)。已经通过 vowpal wabbit 并找到了 SEARN 任务,但似乎它现在在最新版本中不再可用。

3个回答

这听起来像是一个非常棘手的问题,因此需要很多技巧来解决它。@Jérémie Clos 有一些优点,但我想补充一些更一般的想法......

考虑到问题的规模,您可能需要考虑使用MahoutH2O等可扩展框架,而不是 scikit-learn,后者是一个很棒的共享内存库,但确实存在可扩展性限制

对于基数为 5000 和 8000 万个训练案例的分类特征,均匀分布只会为每个阳性结果提供 16,000 个训练案例。但是,分布可能并不均匀我建议您消除最不常见的类别,直到您丢弃 5% 的数据并评估剩余 95% 的基数。这可能会给你一个关于如何进行的更好的线索,即基数的百分比是多少?

大多数多类分类算法只是大量的二元分类器,它们组合起来产生一个复合结果,所以基本上会为你完成分解问题、二值化数据(又名 one-hot 编码)和训练分类器的工作,所以您可能不需要显式执行此拆分步骤。对此有两个例外,即本质上可以处理多类问题的分类器是决策树随机森林Mahout 版本)。我会尝试这两种方法并将它们作为前进的基准。

在将数据添加到系统时处理类别的添加方面,您有时必须重新训练。这有时被称为稳定性-可塑性困境处理此问题的最佳方法可能只是对包含某些数据阈值的类别进行预测,并将其余类别作为异常类别丢弃,这些类别的能力不足以预测,例如类似于我上面建议的健全性检查。

希望这可以帮助!

作为对 Jérémie Clos 和 AN6U5 答案的补充,至少有两种方法可以帮助处理大量类:

  • 使用层次结构,例如分层 softmax与其拥有一个平面的类别列表,不如构建一棵它们的树,然后在每个节点上预测正确的类别是在左侧还是在右侧分支上。
  • 不要直接分类,而是首先学习嵌入到低维空间中,其中同一类的实例应该具有紧密的表示。一个著名的例子是 FaceNet(用例是人脸识别):他们将人脸图像嵌入到 128 维字节向量中。学习这种嵌入的算法是triplet loss(我也听说过magnet loss)。然后当出现一个新请求时,计算它的表示(一个小向量),并在训练集中寻找最接近的向量。这类似于 kNN,或标签嵌入如果每个实例属于多个类:“我们的方法包括将高维稀疏标签嵌入到单位范数向量的低维密集球体上,并将分类问题视为该球体上的余弦邻近回归问题。”

http://manikvarma.org/index.html的工作也可能与您的问题有关。

潜在用途:http: //jmlr.org/papers/volume15/gupta14a/gupta14a.pdf

那么如何处理这种大数据需求以及在这种情况下使用哪些增量分类器,考虑到我将继续获得额外的训练数据以及可能发现新类别的事实?

我不熟悉您正在解决的任务,但是您是否考虑过像 k-nn 及其变体这样的基于距离的懒惰学习器?它可以处理任意数量的类别,逐步学习,并且您可以通过使用其中一种案例库维护算法来保持模型的小型化。至于学习新类别,您可以使用异常值检测算法来查看新测试示例何时不适合其​​类别(即何时显着降低其类内一致性)。