hadoop下实现kmeans算法——一个mapreduce的实现方法

写mapreduce程序实现kmeans算法,我们的思路可能是这样的

1. 用一个全局变量存放上一次迭代后的质心

2. map里,计算每个质心与样本之间的距离,得到与样本距离最短的质心,以这个质心作为key,样本作为value,输出

3. reduce里,输入的key是质心,value是其他的样本,这时重新计算聚类中心,将聚类中心put到一个全部变量t中。

4. 在main里比较前一次的质心和本次的质心是否发生变化,如果变化,则继续迭代,否则退出。

本文的思路基本上是按照上面的步骤来做的,只不过有几个问题需要解决

1. hadoop是不存在自定义的全局变量的,所以上面定义一个全局变量存放质心的想法是实现不了的,所以一个替代的思路是将质心存放在文件中

2. 存放质心的文件在什么地方读取,如果在map中读取,那么可以肯定我们是不能用一个mapreduce实现一次迭代,所以我们选择在main函数里读取质心,然后将质心set到configuration中,configuration在map和reduce都是可读

3. 如何比较质心是否发生变化,是在main里比较么,读取本次质心和上一次质心的文件然后进行比较,这种方法是可以实现的,但是显得不够高富帅,这个时候我们用到了自定义的counter,counter是全局变量,在map和reduce中可读可写,在上面的思路中,我们看到reduce是有上次迭代的质心和刚刚计算出来的质心的,所以直接在reduce中进行比较就完全可以,如果没发生变化,counter加1。只要在main里比较获取counter的值就行了。

梳理一下,具体的步骤如下

1. main函数读取质心文件

2. 将质心的字符串放到configuration

3. 在mapper类重写setup方法,获取到configuration的质心内容,解析成二维数组的形式,代表质心

4. mapper类中的map方法读取样本文件,跟所有的质心比较,得出每个样本跟哪个质心最近,然后输出<质心,样本>

5. reducer类中重新计算质心,如果重新计算出来的质心跟进来时的质心一致,那么自定义的counter加1

6. main中获取counter的值,看是否等于质心,如果不相等,那么继续迭代,否在退出

具体的实现如下

1. pom依赖

这个要跟集群的一致,因为如果不一致在计算其他问题的时候没有问题,但是在使用counter的时候会出现问题

java.lang.IncompatibleClassChangeError: Found 

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值