Skip to main content
 首页 » 编程设计

python之带 Spark 的 Kmeans

2024年10月25日5wayfarer

以下是使用Apache Spark编写的Kmeans算法的一部分:

closest = data.map(lambda p: (closestPoint(p, kPoints), (p, 1))) 
pointStats = closest.reduceByKey(lambda (x1, y1), (x2, y2): (x1 + x2, y1 + y2)) 
newPoints = pointStats.map(lambda (x, (y, z)): (x, y / z)).collect() 

谁能给我解释一下它是如何工作的?假设我们有两个集群和 1000 个点,我们希望在具有两个从节点和一个主节点的集群中运行它。我认为第一个函数(最接近的)可以被认为是映射器,第二个函数是组合器但是最后一个函数应该做什么呢?哪个充当 reducer ?

请您参考如下方法:

您向 reduceByKey 传递一个可以用作组合器和缩减器的函数,因为您需要向它传递一个聚合函数,如果您的用例不能使用组合器,则需要使用 groupByKey。是的,无论何时您在 spark 中的 RDD 上调用 map,您传递给它的函数都可以被视为映射器。你绝对应该看看 RDD docsPairRDDFunctions .请记住,spark 程序往往会有多个映射和减少阶段,因为它试图将中间输出保存在内存中,而标准 Hadoop MapReduce 每次都从磁盘读取和写入。此外,如果您使用的是 spark,则可以使用 k-means in MLlib

更新:
关于您的评论,他们“将(总和/数量点)映射到每个从属节点”的原因是因为 spark 的工作方式意味着这没有开销。由于 spark 为每个 RDD 使用 DAG,在执行操作(如 collect() 在这种情况下)之前,不会计算任何内容,因此最后的映射实际上可以无缝地获得 reducer 的输出,这不应该溢出到磁盘,因为它非常小。这类似于 ChainReducer在 Hadoop 中,然而在 spark 中,连接的 RDD 中的每一步都保存在内存中(显然这并不总是可能的,所以有时它会溢出到磁盘,这也取决于序列化级别)。所以基本上最后的计算实际上是在与 reducer 相同的节点上完成的(之后不需要洗牌),然后才收集到驱动程序。