k-means聚类JAVA实例
2024-10-19 01:26:52
《mahout in action》第六章。
datafile/cluster/simple_k-means.txt数据集例如以下:
1 1
2 1
1 2
2 2
3 3
8 8
8 9
9 8
9 9
1. k-means聚类算法原理
1、从D中随机取k个元素。作为k个簇的各自的中心。
2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
3、依据聚类结果。又一次计算k个簇各自的中心,计算方法是取簇中全部元素各自维度的算术平均数。
4、将D中所有元素依照新的中心又一次聚类。
5、反复第4步,直到聚类结果不再变化。
6、将结果输出。
2. 举例说明
2.1 从D中随机取k个元素,作为k个簇的各自的中心。
private final static Integer K=2; //选K=2,也就是估算有两个簇。
以下选1 1,2,1两个点。
C0:1 1
C1:2 1
C1:2 1
2.2 分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
结果为:
C0 : 1 1
C0:的点为:1.0,2.0
C1: 2 1
C1:的点为:2.0,2.0
C1:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
2.3 依据2.2的聚类结果。又一次计算k个簇各自的中心,计算方法是取簇中全部元素各自维度的算术平均数。
採取欧区距离公式。
C0 新的簇心为:1.0,1.5
C1 新的簇心为:5.857142857142857,5.714285714285714
C1 新的簇心为:5.857142857142857,5.714285714285714
2.4 将D中所有元素依照新的中心又一次聚类。
第2次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
2.5 反复第4步,直到聚类结果不再变化。
当距离小于某个值的时候。就觉得聚类已经聚类了。不须要再迭代,这里的值选0.001
private final static Double converge=0.001;
------------------------------------------------
C0的簇心为:1.6666666666666667,1.75
C1的簇心为:7.971428571428572,7.942857142857143
各个簇心移动中最小的距离为,move=0.7120003121097943
第3次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.777777777777778,1.7916666666666667
C1的簇心为:8.394285714285715,8.388571428571428
各个簇心移动中最小的距离为。move=0.11866671868496578
第4次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.7962962962962965,1.7986111111111114
C1的簇心为:8.478857142857143,8.477714285714285
各个簇心移动中最小的距离为,move=0.019777786447494432
第5次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.799382716049383,1.7997685185185184
C1的簇心为:8.495771428571429,8.495542857142857
各个簇心移动中最小的距离为。move=0.003296297741248916
第6次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.7998971193415638,1.7999614197530864
C1的簇心为:8.499154285714287,8.499108571428572
各个簇心移动中最小的距离为。move=5.49382956874724E-4
3. JAVA实现
package mysequence.machineleaning.clustering.kmeans; import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector; import mysequence.machineleaning.clustering.canopy.Point; public class MyKmeans { static Vector<Point> li=new Vector<Point>();
//static List<Point> li=new ArrayList<Point>();
static List<Vector<Point>> list=new ArrayList<Vector<Point>>(); //每次迭代保存结果,一个vector代表一个簇
private final static Integer K=2; //选K=2,也就是估算有两个簇。
private final static Double converge=0.001; //当距离小于某个值的时候。就觉得聚类已经聚类了,不须要再迭代,这里的值选0.001 //读取数据
public static final void readF1() throws IOException {
String filePath="datafile/cluster/simple_k-means.txt";
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(filePath)));
for (String line = br.readLine(); line != null; line = br.readLine()) {
if(line.length()==0||"".equals(line))continue;
String[] str=line.split(" ");
Point p0=new Point();
p0.setX(Double.valueOf(str[0]));
p0.setY(Double.valueOf(str[1]));
li.add(p0);
//System.out.println(line);
}
br.close();
}
//math.sqrt(double n)
//扩展下。假设要给m开n次方就用java.lang.StrictMath.pow(m,1.0/n);
//採用欧氏距离
public static Double DistanceMeasure(Point p1,Point p2){ Double tmp=StrictMath.pow(p2.getX()-p1.getX(), 2)+StrictMath.pow(p2.getY()-p1.getY(), 2);
return Math.sqrt(tmp);
} //计算新的簇心
public static Double CalCentroid(){
System.out.println("------------------------------------------------");
Double movedist=Double.MAX_VALUE;
for(int i=0;i<list.size();i++){
Vector<Point> subli=list.get(i);
Point po=new Point();
Double sumX=0.0;
Double sumY=0.0;
Double Clusterlen=Double.valueOf(subli.size());
for(int j=0;j<Clusterlen;j++){
Point nextp=subli.get(j);
sumX=sumX+nextp.getX();
sumY=sumY+nextp.getY();
}
po.setX(sumX/Clusterlen);
po.setY(sumY/Clusterlen);
//新的点与旧点之间的距离
Double dist=DistanceMeasure(subli.get(0),po);
//在多个簇心移动的过程中,返回移动距离最小的值
if(dist<movedist)movedist=dist;
list.get(i).clear();
list.get(i).add(po);
System.out.println("C"+i+"的簇心为:"+po.getX()+","+po.getY());
}
String test="ll";
return movedist;
}
//本次的簇心
//下一次移动的簇心 private static Double move=Double.MAX_VALUE;//移动距离
//不断地迭代,直到收敛
public static void RecursionKluster(){
for(int times=2;move>converge;times++){
System.out.println("第"+times+"次迭代");
//默认每个list里的Vector第0个元素是质心
for(int i=0;i<li.size();i++){
Point p=new Point();
p=li.get(i);
int index = -1; double neardist = Double.MAX_VALUE;
for(int k=0;k<K;k++){
Point centre=list.get(k).get(0);
double currentdist=DistanceMeasure(p,centre);
if(currentdist<neardist){
neardist=currentdist;
index=k;
}
} System.out.println("C"+index+":的点为:"+p.getX()+","+p.getY());
list.get(index).add(p); }
//又一次计算簇心,并返回移动的距离,最小的那个距离 move=CalCentroid();
System.out.println("各个簇心移动中最小的距离为。move="+move);
}
} public static void Kluster(){ for(int k=0;k<K;k++){
Vector<Point> vect=new Vector<Point>();
Point p=new Point();
p=li.get(k);
vect.add(p);
list.add(vect);
}
System.out.println("第1次迭代");
//默认每个list里的Vector第0个元素是质心
for(int i=K;i<li.size();i++){
Point p=new Point();
p=li.get(i);
int index = -1; double neardist = Double.MAX_VALUE;
for(int k=0;k<K;k++){
Point centre=list.get(k).get(0);
double currentdist=DistanceMeasure(p,centre);
if(currentdist<neardist){
neardist=currentdist;
index=k;
}
} System.out.println("C"+index+":的点为:"+p.getX()+","+p.getY());
list.get(index).add(p); } } public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//读取数据
readF1();
//第一次迭代
Kluster();
//第一次迭代后计算簇心
CalCentroid();
//不断迭代,直到收敛
RecursionKluster();
} }
4.执行结果:
C0:1 1
C1:2 1
C1:2 1
第1次迭代
C0:的点为:1.0,2.0
C1:的点为:2.0,2.0
C1:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.0,1.5
C1的簇心为:5.857142857142857,5.714285714285714
第2次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.6666666666666667,1.75
C1的簇心为:7.971428571428572,7.942857142857143
各个簇心移动中最小的距离为,move=0.7120003121097943
第3次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.777777777777778,1.7916666666666667
C1的簇心为:8.394285714285715,8.388571428571428
各个簇心移动中最小的距离为。move=0.11866671868496578
第4次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.7962962962962965,1.7986111111111114
C1的簇心为:8.478857142857143,8.477714285714285
各个簇心移动中最小的距离为。move=0.019777786447494432
第5次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.799382716049383,1.7997685185185184
C1的簇心为:8.495771428571429,8.495542857142857
各个簇心移动中最小的距离为。move=0.003296297741248916
第6次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.7998971193415638,1.7999614197530864
C1的簇心为:8.499154285714287,8.499108571428572
各个簇心移动中最小的距离为。move=5.49382956874724E-4
C0:的点为:1.0,2.0
C1:的点为:2.0,2.0
C1:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.0,1.5
C1的簇心为:5.857142857142857,5.714285714285714
第2次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.6666666666666667,1.75
C1的簇心为:7.971428571428572,7.942857142857143
各个簇心移动中最小的距离为,move=0.7120003121097943
第3次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.777777777777778,1.7916666666666667
C1的簇心为:8.394285714285715,8.388571428571428
各个簇心移动中最小的距离为。move=0.11866671868496578
第4次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.7962962962962965,1.7986111111111114
C1的簇心为:8.478857142857143,8.477714285714285
各个簇心移动中最小的距离为。move=0.019777786447494432
第5次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.799382716049383,1.7997685185185184
C1的簇心为:8.495771428571429,8.495542857142857
各个簇心移动中最小的距离为。move=0.003296297741248916
第6次迭代
C0:的点为:1.0,1.0
C0:的点为:2.0,1.0
C0:的点为:1.0,2.0
C0:的点为:2.0,2.0
C0:的点为:3.0,3.0
C1:的点为:8.0,8.0
C1:的点为:8.0,9.0
C1:的点为:9.0,8.0
C1:的点为:9.0,9.0
------------------------------------------------
C0的簇心为:1.7998971193415638,1.7999614197530864
C1的簇心为:8.499154285714287,8.499108571428572
各个簇心移动中最小的距离为。move=5.49382956874724E-4
最新文章
- c语言第12次作业
- Windows Azure Virtual Machine (29) 修改Azure VM 数据磁盘容量
- 初学Memcached安装及使用(CentOS7)
- java命令行参数
- 解决前端浏览器传JSON对像到服务端后全部变成string类型的方法
- Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路
- 找呀志_通过开源框架引AsyncHttpClient处理get/post要求
- js的几大数据类型
- 一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx、supervisor、mysql环境搭建
- echart
- linux服务器 jboss-7安装
- 当使用xmapp时session序列化生成的文件的路径
- 算法(第四版)C# 习题题解——2.4
- 利用搜狐新闻语料库训练100维的word2vec——使用python中的gensim模块
- python appium 有道云笔记分享文章到qq
- 零拷贝Zero-Copy(NIO)
- ftp--vsftp\pureftpd
- 生产消费模式:多线程读写队列ConcurrentQueue
- 创建Fragment和传递数值
- Jquery Mobile 常用参数