Java实现聚类算法k-means
java简单实现聚类算法
第一个版本有一些问题,,(一段废话biubiu。。。),,我其实每次迭代之后(就是达不到收敛标准之前,聚类中心的误差达不到指定小的时候),虽然重新算了聚类中心,但是其实我的那些点并没有变,可是这个程序不知道咋回事每次都把我原先随机指定的聚类中心给变成了我算的聚类中心;怎么用,按照指示来就行了,不用读文件(源码全都是可以运行,不足之处还望批评指正)输出的结果有一堆小数的那是新聚类中心和老的的误差值,在没有达到指定小的时候,是不会停的。
////////////////////
重新看看。。终于改好了。。。。。。Java对象直接赋值属于浅拷贝
修改后为创建一个对象,值来源于随机点,但是跟随机点已经没有任何关系了。。。。。
A a=b;浅拷贝
..............................
A a=new A();
a.x=b.x;
a.y=b.y;
a并没有引用b
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
题目如下:、


初始,有问题版本:
import java.sql.Array;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner; class point {
public float x = 0;
public float y = 0;
public int flage = -1; public float getX() {
return x;
} public void setX(float x) {
this.x = x;
} public float getY() {
return y;
} public void setY(float y) {
this.y = y;
}
} public class Kcluster { point[] ypo;// 点集
point[] pacore = null;// old聚类中心
point[] pacoren = null;// new聚类中心 // 初试聚类中心,点集
public void productpoint() {
Scanner cina = new Scanner(System.in);
System.out.print("请输入聚类中点的个数(随机产生):");
int num = cina.nextInt(); ypo = new point[num];
// 随机产生点
for (int i = 0; i < num; i++) { float x = (int) (new Random().nextInt(10));
float y = (int) (new Random().nextInt(10)); ypo[i] = new point();// 对象创建
ypo[i].setX(x);
ypo[i].setY(y); } // 初始化聚类中心位置
System.out.print("请输入初始化聚类中心个数(随机产生):");
int core = cina.nextInt();
this.pacore = new point[core];// 存放聚类中心
this.pacoren = new point[core]; Random rand = new Random();
int temp[] = new int[core];
temp[0] = rand.nextInt(num);
pacore[0] = new point();
pacore[0] = ypo[temp[0]];
// 避免产生重复的中心
for (int i = 1; i < core; i++) {
int flage = 0;
int thistemp = rand.nextInt(num);
for (int j = 0; j < i; j++) {
if (temp[j] == thistemp) {
flage = 1;// 有重复
break; }
}
if (flage == 1) {
i--;
} else {
pacore[i] = new point();
pacore[i] = ypo[thistemp];
pacore[i].flage = 0;// 0表示聚类中心
} }
System.out.println("初始聚类中心:");
for (int i = 0; i < pacore.length; i++) {
System.out.println(pacore[i].x + " " + pacore[i].y);
} } // ///找出每个点属于哪个聚类中心
public void searchbelong()// 找出每个点属于哪个聚类中心
{ for (int i = 0; i < ypo.length; i++) {
double dist = 999;
int lable = -1;
for (int j = 0; j < pacore.length; j++) { double distance = distpoint(ypo[i], pacore[j]);
if (distance < dist) {
dist = distance;
lable = j;
// po[i].flage = j + 1;// 1,2,3...... }
}
ypo[i].flage = lable + 1; } } // 更新聚类中心
public void calaverage() { for (int i = 0; i < pacore.length; i++) {
System.out.println("以<" + pacore[i].x + "," + pacore[i].y
+ ">为中心的点:");
int numc = 0;
point newcore = new point();
for (int j = 0; j < ypo.length; j++) { if (ypo[j].flage == (i + 1)) {
numc += 1;
newcore.x += ypo[j].x;
newcore.y += ypo[j].y;
System.out.println(ypo[j].x + "," + ypo[j].y);
}
}
// 新的聚类中心
pacoren[i] = new point();
pacoren[i].x = newcore.x / numc;
pacoren[i].y = newcore.y / numc;
pacoren[i].flage = 0;
System.out.println("新的聚类中心:" + pacoren[i].x + "," + pacoren[i].y); }
} public double distpoint(point px, point py) { return Math.sqrt(Math.pow((px.x - py.x), 2)
+ Math.pow((px.y - py.y), 2)); } public void change_oldtonew(point[] old, point[] news) {
for (int i = 0; i < old.length; i++) {
old[i].x = news[i].x;
old[i].y = news[i].y;
old[i].flage = 0;// 表示为聚类中心的标志。
}
} public void movecore() {
// this.productpoint();//初始化,样本集,聚类中心,
this.searchbelong();
this.calaverage();//
double movedistance = 0;
int biao = -1;//标志,聚类中心点的移动是否符合最小距离
for (int i = 0; i < pacore.length; i++) {
movedistance = distpoint(pacore[i], pacoren[i]);
System.out.println("distcore:" + movedistance);//聚类中心的移动距离
if (movedistance < 0.01) {
biao = 0; } else { biao=1;
break; }
}
if (biao == 0) {
System.out.print("迭代完毕!!!!!");
} else {
change_oldtonew(pacore, pacoren);
movecore();
} } public static void main(String[] args) {
// TODO Auto-generated method stub Kcluster kmean = new Kcluster();
kmean.productpoint();
kmean.movecore();
} }
修稿版:在初始化聚类中心那里。有一些改动。。。。。。。。。。。嘤嘤嘤
import java.sql.Array;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner; class point {
public float x = 0;
public float y = 0;
public int flage = -1; public float getX() {
return x;
} public void setX(float x) {
this.x = x;
} public float getY() {
return y;
} public void setY(float y) {
this.y = y;
}
} public class Kcluster { point[] ypo;// 点集
point[] pacore = null;// old聚类中心
point[] pacoren = null;// new聚类中心 // 初试聚类中心,点集
public void productpoint() {
Scanner cina = new Scanner(System.in);
System.out.print("请输入聚类中点的个数(随机产生):");
int num = cina.nextInt(); ypo = new point[num];
// 随机产生点
for (int i = 0; i < num; i++) { float x = (int) (new Random().nextInt(10));
float y = (int) (new Random().nextInt(10)); ypo[i] = new point();// 对象创建
ypo[i].setX(x);
ypo[i].setY(y); } // 初始化聚类中心位置
System.out.print("请输入初始化聚类中心个数(随机产生):");
int core = cina.nextInt();
this.pacore = new point[core];// 存放聚类中心
this.pacoren = new point[core]; Random rand = new Random();
int temp[] = new int[core];
temp[0] = rand.nextInt(num);
pacore[0] = new point();
pacore[0].x = ypo[temp[0]].x;
pacore[0].y = ypo[temp[0]].y;
pacore[0].flage=0 ;
// 避免产生重复的中心
for (int i = 1; i < core; i++) {
int flage = 0;
int thistemp = rand.nextInt(num);
for (int j = 0; j < i; j++) {
if (temp[j] == thistemp) {
flage = 1;// 有重复
break; }
}
if (flage == 1) {
i--;
} else {
pacore[i] = new point();
pacore[i].x= ypo[thistemp].x;
pacore[i].y = ypo[thistemp].y;
pacore[i].flage = 0;// 0表示聚类中心
} }
System.out.println("初始聚类中心:");
for (int i = 0; i < pacore.length; i++) {
System.out.println(pacore[i].x + " " + pacore[i].y);
} } // ///找出每个点属于哪个聚类中心
public void searchbelong()// 找出每个点属于哪个聚类中心
{ for (int i = 0; i < ypo.length; i++) {
double dist = 999;
int lable = -1;
for (int j = 0; j < pacore.length; j++) { double distance = distpoint(ypo[i], pacore[j]);
if (distance < dist) {
dist = distance;
lable = j;
// po[i].flage = j + 1;// 1,2,3...... }
}
ypo[i].flage = lable + 1; } } // 更新聚类中心
public void calaverage() { for (int i = 0; i < pacore.length; i++) {
System.out.println("以<" + pacore[i].x + "," + pacore[i].y
+ ">为中心的点:");
int numc = 0;
point newcore = new point();
for (int j = 0; j < ypo.length; j++) { if (ypo[j].flage == (i + 1)) {
System.out.println(ypo[j].x + "," + ypo[j].y);
numc += 1;
newcore.x += ypo[j].x;
newcore.y += ypo[j].y; }
}
// 新的聚类中心
pacoren[i] = new point();
pacoren[i].x = newcore.x / numc;
pacoren[i].y = newcore.y / numc;
pacoren[i].flage = 0;
System.out.println("新的聚类中心:" + pacoren[i].x + "," + pacoren[i].y); }
} public double distpoint(point px, point py) { return Math.sqrt(Math.pow((px.x - py.x), 2)
+ Math.pow((px.y - py.y), 2)); } public void change_oldtonew(point[] old, point[] news) {
for (int i = 0; i < old.length; i++) {
old[i].x = news[i].x;
old[i].y = news[i].y;
old[i].flage = 0;// 表示为聚类中心的标志。
}
} public void movecore() {
// this.productpoint();//初始化,样本集,聚类中心,
this.searchbelong();
this.calaverage();//
double movedistance = 0;
int biao = -1;//标志,聚类中心点的移动是否符合最小距离
for (int i = 0; i < pacore.length; i++) {
movedistance = distpoint(pacore[i], pacoren[i]);
System.out.println("distcore:" + movedistance);//聚类中心的移动距离
if (movedistance < 0.01) {
biao = 0; } else { biao=1;//需要继续迭代,
break; }
}
if (biao == 0) {
System.out.print("迭代完毕!!!!!");
} else {
change_oldtonew(pacore, pacoren);
movecore();
} } public static void main(String[] args) {
// TODO Auto-generated method stub Kcluster kmean = new Kcluster();
kmean.productpoint();
kmean.movecore();
} }
Java实现聚类算法k-means的更多相关文章
- ML: 聚类算法-K均值聚类
基于划分方法聚类算法R包: K-均值聚类(K-means) stats::kmeans().fpc::kmeansruns() K-中心点聚类(K-Medoids) ...
- 聚类算法:K均值、凝聚层次聚类和DBSCAN
聚类分析就仅根据在数据中发现的描述对象及其关系的信息,将数据对象分组(簇).其目标是,组内的对象相互之间是相似的,而不同组中的对象是不同的.组内相似性越大,组间差别越大,聚类就越好. 先介绍下聚类的不 ...
- 常见聚类算法——K均值、凝聚层次聚类和DBSCAN比较
聚类分析就仅根据在数据中发现的描述对象及其关系的信息,将数据对象分组(簇).其目标是,组内的对象相互之间是相似的,而不同组中的对象是不同的.组内相似性越大,组间差别越大,聚类就越好. 先介绍下聚类的不 ...
- 软件——机器学习与Python,聚类,K——means
K-means是一种聚类算法: 这里运用k-means进行31个城市的分类 城市的数据保存在city.txt文件中,内容如下: BJ,2959.19,730.79,749.41,513.34,467. ...
- 【机器学习】聚类算法——K均值算法(k-means)
一.聚类 1.基于划分的聚类:k-means.k-medoids(每个类别找一个样本来代表).Clarans 2.基于层次的聚类:(1)自底向上的凝聚方法,比如Agnes (2)自上而下的分裂方法,比 ...
- 数据挖掘十大算法--K-均值聚类算法
一.相异度计算 在正式讨论聚类前,我们要先弄清楚一个问题:怎样定量计算两个可比較元素间的相异度.用通俗的话说.相异度就是两个东西区别有多大.比如人类与章鱼的相异度明显大于人类与黑猩猩的相异度,这是能 ...
- 第十三篇:K-Means 聚类算法原理分析与代码实现
前言 在前面的文章中,涉及到的机器学习算法均为监督学习算法. 所谓监督学习,就是有训练过程的学习.再确切点,就是有 "分类标签集" 的学习. 现在开始,将进入到非监督学习领域.从经 ...
- 机器学习六--K-means聚类算法
机器学习六--K-means聚类算法 想想常见的分类算法有决策树.Logistic回归.SVM.贝叶斯等.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别 ...
- k-means均值聚类算法(转)
4.1.摘要 在前面的文章中,介绍了三种常见的分类算法.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应.但是很多时候上述条件得不到满足,尤其是在 ...
随机推荐
- IE浏览器中overflow:hidden无效,内层元素超出外层div的解决方法
原文地址:http://www.xin126.cn/show.asp?id=2624 在用css布局的时候,用IE浏览器(ie6.ie7.ie8)预览,有时候会出现内层元素(内部DIV.图片等)超出外 ...
- CentOs7安装gitlab(转!)
沧浪之水清兮,可以濯吾缨; 沧浪之水浊兮,可以濯吾足. ...
- 捷通华声TTS在Aster+中的安装过程
1)挂载TTS光碟 2)安装如下5个rpm软件包 [asterisk@TTS78:/mnt]$ls *.rpmjTTS-5.0.1.0-3.i386.rpm VocLib_Xi ...
- Spring bean注解配置(1)
Spring自带的@Component注解及扩展@Repository.@Service.@Controller,如图 在使用注解方式配置bean时,需要引进一个包: 使用方法: 1.为需要使用注解方 ...
- 用Dockerfile生成docker image
在docker的官方php镜像中,有独立的php和apache版本的,这里尝试用php-fpm7.2.1(alpine3.7)作为基础镜像,在把nginx1.13.8加进去. 第一步:拉取php镜像: ...
- 微软SMB 3.0文件共享协议新特性介绍
SMB(*nix平台和Win NT4.0又称CIFS)协议是Windows平台标准文件共享协议.Linux平台通过samba来支持.SMB最新版本v3.0,在v2.0基础上针对WAN和分布式有改进.详 ...
- SQL SERVER回滚恢复误操作的数据
在生产数据库做CURD操作时,可能会有执行某条语句误操作的情况发生,针对这个种情况有两点建议: 1. 在SQL SERVER上开启事务确认功能,当执行完语句后确认无误,再提交事务.(开启方法见附件图片 ...
- jar包双击执行引用外部包问题
大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar包的程序入口. 具体的方法是修改jar包内目录META-INF下的MANIF ...
- centos7.3 快速安装 mariadb(mysql)
从最新版本的linux系统开始,默认的是 Mariadb而不是mysql! 使用系统自带的repos安装很简单: yum install mariadb mariadb-server systemct ...
- PHP Token(令牌)设计 避免重复提交
设计目标: 避免重复提交数据. 检查来路,是否是外部提交 匹配要执行的动作(如果有多个逻辑在同一个页面实现,比如新增,删除,修改放到一个PHP文件里操作) 这里所说的token是在页面显示的时候,写到 ...