Canopy集群算法(org.apache.mahout.clustering.canopy.CanopyDriver)(转载)




原创文章,转载请注明: 转载自慢慢的回味

本文链接地址: Canopy集群算法(org.apache.mahout.clustering.canopy.CanopyDriver)

理论分析

集群中心点计算

1 选择T1和T2,T1>T2。其中T1为弱归属距离,T2为强归属距离。
2 对每个点进行到中心点的距离计算。其中,第一点计算时没有中心点,则以第一点为中心创建一个集群。
2.1 当距离小于T1时,标记当前点为弱归属点,对应的集群加入此点
2.2 当小于T2时,标记当前点为强归属点。
2.3 如果当前点不是强归属点,则以当前点为中心创建一个新的集群。
3 对所有的集群中心点,计算新的集群。

集群数据

对所有的点,计算其和每个中心的距离,距离最小者为当前点的集群。

例子

所有数据:[[2,2],[3,3],[4,4],[-2,-2],[-3,-3],[-4,-4]]
1 T1=10 T2=5 距离度量:org.apache.mahout.common.distance.ManhattanDistanceMeasure
2 [ 2, 2] 产生集群{ID:0 中心:[2,2] 归属点:[2,2]}
3 [ 3, 3] 于ID:0距离为2 <T2,强归属点 更新集群{ID:0 中心:[2,2] 归属点:[2,2],[3,3]}
4 [ 4, 4] 于ID:0距离为4 <T2,强归属点 更新集群{ID:0 中心:[2,2] 归属点:[2,2],[3,3],[4,4]}
5 [-2,-2] 于ID:0距离为8 <T1,>T2,弱归属点 更新集群{ID:0 中心:[2,2] 归属点:[2,2],[3,3],[4,4],[-2,-2]} 产生集群{ID:1 中心:[-2,-2] 归属点:[-2,-2]}
6 [-3,-3] 于ID:0距离为10 >T2,弱归属点
          于ID:1距离为2 <T2,强归属点 更新集群{ID:1 中心:[-2,-2] 归属点:[-2,-2],[-3,-3]}
7 [-4,-4] 于ID:0距离为12 >T1,>T2,弱归属点
          于ID:1距离为4 <T2,强归属点 更新集群{ID:1 中心:[-2,-2] 归属点:[-2,-2],[-3,-3],[-4,-4]}
8 重新计算集群中心点:{ID:0 中心:[1.75,1.75] 归属点:[2,2],[3,3],[4,4],[-2,-2]} {ID:1 中心:[-3,-3] 归属点:[-2,-2],[-3,-3],[-4,-4]}
9 对中心点进行集群:[[1.75,1.75],[-3,-3]]
10 [1.75,1.75] 产生集群{ID:A0 中心:[1.75,1.75] 归属点:[1.75,1.75]}
11 [-3,-3]     于ID:A0距离为9.5 <T1,>T2,弱归属点 更新集群{ID:A0 中心:[1.75,1.75] 归属点:[1.75,1.75],[-3,-3]} 产生集群{ID:A1 中心:[-3,-3] 归属点:[-3,-3]}
12 重新计算集群中心点:{ID:A0 中心:[-0.625,-0.625] 归属点:[1.75,1.75],[-3,-3]} 产生集群{ID:A1 中心:[-3,-3] 归属点:[-3,-3]}
对所以数据进行集群计算,易得[2,2],[3,3],[4,4]属于A0,[-2,-2],[-3,-3],[-4,-4]属于A1

代码分析

  /* CanopyMapper.java*/
  @Override
  protected void map(WritableComparable<?> key, VectorWritable point,
      Context context) throws IOException, InterruptedException {
    canopyClusterer.addPointToCanopies(point.get(), canopies);
  }
 
  @Override
  protected void cleanup(Context context) throws IOException,
      InterruptedException {
    for (Canopy canopy : canopies) {
      canopy.computeParameters();
      if (canopy.getNumObservations() > clusterFilter) {
        context.write(new Text("centroid"), new VectorWritable(canopy
            .getCenter()));
      }
    }
    super.cleanup(context);
  }
 
  /* CanopyClusterer.java*/
  public void addPointToCanopies(Vector point, Collection<Canopy> canopies) {
    boolean pointStronglyBound = false;
    for (Canopy canopy : canopies) {
      double dist = measure.distance(canopy.getCenter().getLengthSquared(), canopy.getCenter(), point);
      if (dist < t1) {
        if (log.isDebugEnabled()) {
          log.debug("Added point: {} to canopy: {}", AbstractCluster.formatVector(point, null), canopy.getIdentifier());
        }
        canopy.observe(point);
      }
      pointStronglyBound = pointStronglyBound || dist < t2;
    }
    if (!pointStronglyBound) {
      if (log.isDebugEnabled()) {
        log.debug("Created new Canopy:{} at center:{}", nextCanopyId, AbstractCluster.formatVector(point, null));
      }
      canopies.add(new Canopy(point, nextCanopyId++, measure));
    }
  }
 
  /* CanopyReducer.java */
  @Override
  protected void reduce(Text arg0, Iterable<VectorWritable> values,
      Context context) throws IOException, InterruptedException {
    for (VectorWritable value : values) {
      Vector point = value.get();
      canopyClusterer.addPointToCanopies(point, canopies);
    }
    for (Canopy canopy : canopies) {
      canopy.computeParameters();
      if (canopy.getNumObservations() > clusterFilter) {
        ClusterWritable clusterWritable = new ClusterWritable();
        clusterWritable.setValue(canopy);
        context.write(new Text(canopy.getIdentifier()), clusterWritable);
      }
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值