二分kmeans代码java_二分Kmeans的java实现

刚刚研究了Kmeans。Kmeans是一种十分简单的聚类算法。可是他十分依赖于用户最初给定的k值。它无法发现随意形状和大小的簇。最适合于发现球状簇。他的时间复杂度为O(tkn)。kmeans算法有两个核心点:计算距离的公式&推断迭代停止的条件。一般距採用欧式距离等能够随意。推断迭代停止的条件能够有:1) 每一个簇的中心点不再变化则停止迭代2)全部簇的点与这个簇的中心点的误差平方和(SSE)...
摘要由CSDN通过智能技术生成

刚刚研究了Kmeans。Kmeans是一种十分简单的聚类算法。可是他十分依赖于用户最初给定的k值。它无法发现随意形状和大小的簇。最适合于发现球状簇。他的时间复杂度为O(tkn)。kmeans算法有两个核心点:计算距离的公式&推断迭代停止的条件。一般距採用欧式距离等能够随意。推断迭代停止的条件能够有:

1) 每一个簇的中心点不再变化则停止迭代

2)全部簇的点与这个簇的中心点的误差平方和(SSE)的全部簇的总和不再变化

3)设定人为的迭代次数。观察实验效果。

当初始簇心选择不好的时候聚类的效果会非常差。

所以后来又有一个人提出了二分k均值(bisectingkmeans),其核心思路是:将初始的一个簇一分为二计算出误差平方和最大的那个簇,对他进行再一次的二分。直至切分的簇的个数为k个停止。

事实上质就是不断的对选中的簇做k=2的kmeans切分。

由于聚类的误差平方和可以衡量聚类性能,该值越小表示数据点月接近于它们的质心。聚类效果就越好。所以我们就须要对误差平方和最大的簇进行再一次的划分。由于误差平方和越大,表示该簇聚类越不好,越有可能是多个簇被当成一个簇了。所以我们首先须要对这个簇进行划分。

以下是代码,kmeans的原始代码来源于http://blog.csdn.net/cyxlzzs/article/details/7416491,我稍作了一些改动。

package org.algorithm;

import java.util.ArrayList;

import java.util.List;

/**

* 二分k均值。实际上是对一个集合做多次的k=2的kmeans划分。 每次划分后会对sse值较大的簇再进行二分。 终于使得或分出来的簇的个数为k个则停止

*

* 这里利用之前别人写好的一个kmeans的java实现作为基础类。

*

* @author l0979365428

*

*/

public class BisectingKmeans {

private int k;// 分成多少簇

private List dataSet;// 当前要被二分的簇

private List cluster; // 簇

/**

* @param args

*/

public static void main(String[] args) {

// 初始化一个Kmean对象,将k置为10

BisectingKmeans bkm = new BisectingKmeans(5);

// 初始化试验集

ArrayList dataSet = new ArrayList();

dataSet.add(new float[] { 1, 2 });

dataSet.add(new float[] { 3, 3 });

dataSet.add(new float[] { 3, 4 });

dataSet.add(new float[] { 5, 6 });

dataSet.add(new float[] { 8, 9 });

dataSet.add(new float[] { 4, 5 });

dataSet.add(new float[] { 6, 4 });

dataSet.add(new float[] { 3, 9 });

dataSet.add(new float[] { 5, 9 });

dataSet.add(new float[] { 4, 2 });

dataSet.add(new float[] { 1, 9 });

dataSet.add(new float[] { 7, 8 });

// 设置原始数据集

bkm.setDataSet(dataSet);

// 运行算法

bkm.execute();

// 得到聚类结果

// ArrayList> cluster = bkm.getCluster();

// 查看结果

// for (int i = 0; i < cluster.size(); i++) {

// bkm.printDataArray(cluster.get(i), "cluster[" + i + "]");

// }

}

public BisectingKmeans(int k) {

// 比2还小有啥要划分的意义么

if (k < 2) {

k = 2;

}

this.k = k;

}

/**

* 设置需分组的原始数据集

*

* @param dataSet

*/

public void setDataSet(ArrayList dataSet) {

this.dataSet = dataSet;

}

/**

* 运行算法

*/

public void execute() {

long startTime = System.currentTimeMillis();

System.out.println("BisectingKmeans begins");

BisectingKmeans();

long endTime = System.currentTimeMillis();

System.out.println("BisectingKmeans running time="

+ (endTime - startTime) + "ms");

System.out.println("BisectingKmeans ends");

System.out.println();

}

/**

* 初始化

*/

private void init() {

int dataSetLength = dataSet.size();

if (k > dataSetLength) {

k = dataSetLength;

}

}

/**

* 初始化簇集合

*

* @return 一个分为k簇的空数据的簇集合

*/

private ArrayList> initCluster() {

ArrayList> cluster = new ArrayList>();

for (int i = 0; i < k; i++) {

cluster.add(new ArrayList());

}

return cluster;

}

/**

* Kmeans算法核心过程方法

*/

private void BisectingKmeans() {

init();

if (k < 2) {

// 小于

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值