K-Means算法Hadoop

K-Means算法Hadoop,hadoop,mapreduce,Hadoop,Mapreduce,我正在Hadoop(旧API)上实现K-Means算法,我被困在一个无法进一步解决问题的地方 到目前为止,我的逻辑是: 维护两个文件质心和数据 步骤1:读取质心文件并将此数据存储在一些列表(ArrayList)中 步骤2:然后通过mapper读取数据文件,因为它将逐行扫描,然后将此值与列表中已存储的质心进行比较 步骤3:将相应的质心和数据输出到减速器 步骤4:Reducer将处理新的质心并将其与数据一起发出 我的问题 我的流程正确吗 将质心文件先存储在某个集合中,然后再继续存储,这是正确的方

我正在Hadoop(旧API)上实现K-Means算法,我被困在一个无法进一步解决问题的地方

到目前为止,我的逻辑是:

维护两个文件质心和数据

  • 步骤1:读取质心文件并将此数据存储在一些
    列表(ArrayList)
  • 步骤2:然后通过mapper读取数据文件,因为它将逐行扫描,然后将此值与列表中已存储的质心进行比较
  • 步骤3:将相应的质心和数据输出到减速器
  • 步骤4:Reducer将处理新的质心并将其与数据一起发出
我的问题
  • 我的流程正确吗
  • 将质心文件先存储在某个集合中,然后再继续存储,这是正确的方法吗
  • 如果我使用方法(2),那么我的问题是如何将该质心文件存储在某个集合中,因为as map函数将逐行扫描文件,所以如何在对数据文件运行映射程序之前先扫描该质心文件
  • 处理此形心文件功能的更好方法是什么

  • Hadoop并不是K-means的最佳选择,因为您需要运行几个map reduces来获得结果。也就是说,ApacheMahout包含了一个用于Hadoop的应用程序,您可以使用它(或者查看它的实现)

    它是Hadoop之上的一个大容量同步并行处理框架,更适合于此,因为它允许在参与的组件之间进行消息传递,并且具有k-means实现[3]。在Hadoop 2上看到这样的解决方案在测试版之外时会更常见

  • 在我看来,你的流量几乎正常。您不应该“读取”数据文件,而应该将其指定为hadoop程序的输入。此外,虽然并不总是理想的MapReduce/Hadoop系统可以很好地执行迭代算法。只需确保将减速器的输出链接到映射器的输入即可

  • 是的,这是正确的,您可以使用分布式缓存,也可以只将文件存储在hdfs路径中。在映射器开始时读取质心文件可以在“设置”方法内完成

    公共类MyMapper扩展了Mapper{ @凌驾 受保护的无效设置(上下文){ //设置代码。读取质心文件 } }
  • 请参阅上面的代码,使用“设置”方法

  • 我认为质心文件很好,因为它的大小很小,所以传递该文件很简单(除非您尝试拥有数百万个集群…)


  • 是的,Arnon…但我更倾向于学习,所以我正在尝试实现它,以了解k-means在MapReduce上的实际工作方式。@Anon Hama在主干中有一个kmeans版本已经有很多年了,所以不需要链接到这些旧的实现。@ThomasJungblut我记得它,但在早上(早上6点:)找不到它。我编辑了答案。JackSparrow-您仍然可以查看实现并从中学习(代码是开源的)谢谢Arnon..我会这样做:)这里是:是的,这就是我所想的,但由于我使用的是旧Api,“configure”方法的功能与“setup”的功能相同吗?是的,MapReduceBase.configure(JobConf),是Mapper.setup的旧Api版本(Context)@greybuddha:hadoop中的分布式缓存将只保存一次迭代的文件,对吗?在第二次迭代中,文件将自动删除,否则我必须处理?因此分布式缓存使用“绝对路径#文件名”,它驻留在hdfs上。因此,除非您删除包含缓存的文件夹,否则它将保持不变。例如,如果您查看TeraSort,它会将DistributedCache文件放在输出文件夹中,而输出文件夹肯定不会被删除。因此,我不确定这里的内容。因此,假设在每次迭代中,我都会根据您的注释创建一个新的JobConf在上一次迭代中缓存的文件将在下一次迭代(或下一次新JobConf)中保持?我认为它将只缓存一个作业配置(map和reduce的一次迭代)…但不确定。 public class MyMapper extends Mapper{ @Override protected void setup(Context context){ //setup code. Read in centroid file } }