繁体   English   中英

如何在Spark数据集的不同分区上做自笛卡尔积?

[英]How to do a self cartesian product over the different partitions of a Spark dataset?

我需要将数据集的不同行进行二到两比较。 理想情况下,我将对数据集进行自笛卡尔乘积运算,然后将重复的比较删除(因为A, BB, A相同),最后我将进行map以确定每对行是否相等或相等。不。 但是,这将导致大量的行,而且我负担不起它的计算成本。

为了尽可能减少生成的行数,我想对行进行排序,并且仅将自笛卡尔积乘以整个数据集的不同子集。 例如,子集将是以下子集:

  • 从第0行到第100行
  • 从第50行到150行
  • 从第100到200行
  • ....

通过这种方式,我将每一行与其近邻进行比较,并且要进行比较的最终行数将比在整个数据集上进行自笛卡尔乘积的情况小得多。

我的尝试

我实际上已经实现了一个解决方案,但是由于某种原因,即使数据集很小,也要花费很多时间。

首先,我对数据集进行排序和压缩以识别每一列。

val sortedByTitle = journalArticles.orderBy("title")
val withIndex = sortedByTitle.rdd.zipWithIndex().toDF("article", "index").as[IndexArticle]

然后,我做了一个函数来做除法和自笛卡尔乘积:

def divideAndCartesian(data: Dataset[IndexArticle], fromIndex: Long, divisionSize: Int): Dataset[CartessianIndexArticles] = {
  val division = data.filter(x => x.index >= fromIndex && x.index < fromIndex + divisionSize)
  if(division.count() == 0) Seq.empty[(JournalArticle, Long, JournalArticle, Long)].toDF("article1", "index1", "article2", "index2").as[CartessianIndexArticles]
  else
    division.crossJoin(division).toDF("article1", "index1", "article2", "index2").as[CartessianIndexArticles].union(divideAndCartesian(data, fromIndex + (divisionSize / 2), divisionSize))
}

有任何想法吗?

谢谢!

我建议您阅读有关使用局部敏感哈希的Approximate Similarity Join 根据文档:

LSH的一般想法是使用一个函数族(“ LSH族”)将数据点散列到存储桶中,以便彼此靠近的数据点很有可能位于同一存储桶中,而彼此相距很远的情况很可能在不同的存储桶中。

具体来说,近似相似联接:

近似相似联接采用两个数据集,并近似返回数据集中距离小于用户定义阈值的行对。 近似相似联接既支持联接两个不同的数据集,又支持自联接。 自连接会产生一些重复的对。

简而言之,LSH将对您的行进行存储分区,以避免比较所有可能的对。 例如,在您执行近似相似连接后,如果对欧氏距离使用桶装随机投影

val joined = model.approxSimilarityJoin(data, data, 2.5)

在2.5距离之内的所有joined对将被返回。 然后由您决定该近似值是否足以过滤掉重复项,或者您是否要计算各行之间的精确相似度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM