0

我正在自己使用 Spark 实施k-means作为练习。为此,我需要比较id -> cluster_id每一步的 2 张地图。目前,我通过收集它们并作为两个普通的 scala 地图进行比较来做到这一点。

有没有办法并行执行此操作?这值得么?

更新:

让我详细描述一下情况,从K-MEANS聚类算法开始(很简单)

  1. 从所有 N 个点中随机选择 K 个点,使它们成为质心。
  2. 将每个点分配给最近的质心(根据欧几里德距离)
  3. 重新计算质心,按指定的质心对所有点进行分组,计算这些点的平均值
  4. 如果重新计算生成的映射 (obj_id -> centroid_id) 不是上一步中的映射,则重复步骤 2-3

第 4 步是个问题。我需要将我在上一步中的映射与我现在的映射进行比较,这应该以某种方式并行完成,而不会在工作人员之间进行太多随机读取。

4

1 回答 1

1

我不确定“比较”它们是什么意思。你的问题的答案真的取决于这个!如果您可以提供更多详细信息,我将相应地编辑我的答案,但一般问题只能产生一般答案^_^

如果您只需要测试相等性,它非常简单(并且与地图预期的顺序无关):

val x = Map[Int, Int](1->2, 2->3)
val y = Map[Int, Int](2->3, 1->2)
(x == y) == true

如果您只想测试它们是否具有相同的键集但不同的映射(可能是因为您想测试更新步骤的终止),您可以直接将键作为迭代器或集合进行比较

(x.keys == y.keySet) == true

如果您的问题是由于您的地图太大而您想并行进行相等性测试,那么事情就会变得棘手:您可以根据键对对进行拆分并对每个切片进行并行检查:如果全部你的支票是正面的,那么你就有平等的权利。您可以通过根据键值/哈希将 x 和 y 拆分为切片并发送给不同的参与者(例如,如果您正在使用参与者),或者只是迭代 x 并检查不同的参与者 y 的值来做到这一点为那把钥匙。

在这两种情况下,我认为这仅在以下情况下才有意义:a)您的两个地图不在同一个进程的内存中,因此访问它们很慢且阻塞,b)您的比较不仅是价值平等,而且需要一些强烈的可以从异步流水线中受益的计算。

请注意,我在假设您使用的是基本的通用地图结构的情况下做出了答复。如果您有一些性能限制,您可能希望实现为您的特定需求量身定制的自己的地图结构,即使很难想象库版本不会优化到比您自己的更好的场景。

编辑 鉴于新信息,我的答案仍然没有改变。只需将 x 中的条目拆分为由键的哈希分配的 n 个切片,并检查 y 是否包含具有相同值的它们。

于 2014-10-23T08:23:57.470 回答