在 pyspark 中实现类不平衡算法

Posted

技术标签:

【中文标题】在 pyspark 中实现类不平衡算法【英文标题】:Implementing class imbalance algorithm in pyspark 【发布时间】:2017-04-24 11:56:32 【问题描述】:

我有一个数据集,我想从中创建新的合成样本。问题有两个部分。

第 1 部分:要为每一行找出 5 个最近的邻居。我想在不使用笛卡尔的情况下以分布式方式找出邻居。如何使用整个数据集找到一行的欧几里得距离,即访问其他工作人员上存在的行。

第 2 部分:找到邻居后,我将取出每一行,并从我们在第 1 部分中找到的 5 个邻居中随机抽取的最近邻居中以分布式方式减去它。当我想使用 rdd 或数据框执行此操作时,就会出现问题。在 rdd 中,map 函数一次只占用一行,即使我有邻居的索引,我也无法访问它的最近邻居。同样在数据框中的 udf 中。另外,我不想在 rdd 或数据帧上使用过滤器来查找具有已知索引的最近邻居,因为对于非常庞大的数据集来说它很慢。此外,我无法将最近邻居的数据保存在驱动程序上并进行广播,因为它的大小也会非常大。

感谢您的帮助!

【问题讨论】:

抱歉否定,但第 1 部分您要问的是如何在不做笛卡尔的情况下做笛卡尔。对于第 2 部分,它是 original -> nn 的简单连接,但前提是您可以负担得起原始 RDD/数据帧的副本。您可以通过在现有数据中添加一些高斯噪声来创建合成样本吗?和/或只是更换样品? 我能想到的最近/最简单的事情是仅在分区内找到最近的邻居。为此,您可以使用rdd.mapPartitions(iterator => results),它为您提供了对该分区中记录的迭代器。然后,您可以仅将每条记录映射到该分区的最近邻居。 对于第 1 部分,我同意需要完成笛卡尔坐标。但它不会将我的数据大小增加几倍吗?我想知道是否有任何其他可能的方法。对于第 2 部分,我使用的是常规 SMOTE 算法,该算法根据其最近邻创建样本。是的,我们可以在分区本身中找到邻居,但它很可能不是我们想要的最近邻居,因为我们只查看分区中数据的子集,这可能最终影响我的合成样本的质量。 '对于第 2 部分,它是原始 -> nn 的简单连接,但假设您可以负担得起原始 RDD/数据帧的副本。为此,我将不得不使用过滤器和 zipWithIndex 从数据中的索引中找到邻居。正如我所说的,在一个巨大的数据集上它并没有那么快,这在很大程度上减慢了我的代码。 您将需要在某些方面做出妥协,无论是集群的大小、结果的准确性还是您愿意等待的时间。对不起! 【参考方案1】:

终于在@zero323 https://***.com/users/1560062/zero323的帮助下找到了答案

Spark 2.2.0 中的 pypsaprk.ml.feature 中有一个函数作为 BucketedRandomProjectionLSH 可用,通过它可以计算最近的邻居。 https://github.co2m/apache/spark/blob/d9f4ce6943c16a7e29f98e57c33acbfc0379b54d/python/pyspark/ml/feature.py#L197

【讨论】:

以上是关于在 pyspark 中实现类不平衡算法的主要内容,如果未能解决你的问题,请参考以下文章

针对类不平衡结合重采样和特定算法

在python中实现类接口的正确方法是啥

如何在头文件C++中实现类对象

如何在派生类中实现类的基本函数

在 Scala Slick 中实现类实例成员修改的最佳方法?

即使在 XCTest 文件中实现类扩展中的方法后,仍会调用协议的默认实现