数据挖掘-k-means算法实现

<pre name="code" class="java">import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class K_means {
	List<String> data=new ArrayList<String>();
	
	public K_means() throws IOException{//函数作用:数据载入
		BufferedReader br=new BufferedReader(new FileReader("F:/数据挖掘--算法实现/k-means算法/input.txt"));
        String line="";
        while((line=br.readLine())!=null){
        	this.data.add(line);
     	}
	}
	
	public float Distance(float[] m,float[] n){//函数作用:计算两个向量的欧式距离
		float tmp=0;
		for(int i=0;i<m.length;i++){
			tmp=tmp+(m[i]-n[i])*(m[i]-n[i]);
		}
		return (float)Math.sqrt(tmp);
	}
	
	public Map<Integer,List<String>> Cluster(List<String> data,List<String> points){//函数作用:基准点为points,把数据集data中的各个点分到与points最近的点
		Map<Integer,List<String>> map=new HashMap<Integer,List<String>>();
		float[][] points_=new float[points.size()][points.get(0).split(" ").length];
		float[][] data_=new float[data.size()][data.get(0).split(" ").length];
		for(int i=0;i<points_.length;i++){
			for(int j=0;j<points_[0].length;j++){
				points_[i][j]=Float.parseFloat(points.get(i).split(" ")[j]);
			}
		}
		for(int i=0;i<data_.length;i++){
			for(int j=0;j<data_[0].length;j++){
				data_[i][j]=Float.parseFloat(data.get(i).split(" ")[j]);
			}
			float min=Distance(data_[i],points_[0]);
			int kind=0;
			for(int k=0;k<points_.length;k++){
			      if(Distance(data_[i],points_[k])<min){
			    	  kind=k;
			    	  min=Distance(data_[i],points_[k]);
			      }
			}
			List<String> tmp=new ArrayList<String>();
			if(map.containsKey(kind))
			  {tmp=map.get(kind); map.remove(kind);}
			tmp.add(data.get(i));
			map.put(kind,tmp);
		}
		return map;
	}
	
	public List<String> Centre_point(Map<Integer,List<String>> map){//函数作用:计算各个数据集中的重心
		List<String> points=new ArrayList<String>();
		float[] tmp=new float[map.get(0).get(0).split(" ").length];
		for(int i=0;i<map.size();i++){
			for(int j=0;j<tmp.length;j++){tmp[j]=0;}
			for(int k=0;k<map.get(i).size();k++){
				for(int l=0;l<map.get(i).get(k).split(" ").length;l++){
					tmp[l]=tmp[l]+Float.parseFloat(map.get(i).get(k).split(" ")[l]);
				}
			}
			String tmp_str="";
			for(int j=0;j<tmp.length;j++)
			  {tmp[j]=tmp[j]/map.get(i).size();
			    tmp_str=tmp_str+" "+String.valueOf(tmp[j]);}
			points.add(i,tmp_str.trim());	
		}
		return points;
	}
	
	public Map<Integer,List<String>> K_means_method(List<String> data,int k){//函数作用:k-means算法
		List<String> points=new ArrayList<String>();
		List<String> points_last=new ArrayList<String>();
		Map<Integer,List<String>> map=new HashMap<Integer,List<String>>();
		for(int i=0;i<k;i++){
			points.add(i, data.get(i));
		}
		while(1==1){
			map=Cluster(data,points);
			points_last=points;
			points=Centre_point(map);
			if(points_change(points,points_last)<0.0001){break;}
		}
		return map;
	}
	
	private float points_change(List<String> points, List<String> points_last) {//函数作用:计算两个点集位置平均偏移量
		float[] m=new float[points.get(0).split(" ").length];
		float[] n=new float[points.get(0).split(" ").length];
		float tmp=0;
		for(int i=0;i<points.size();i++){
			for(int j=0;j<m.length;j++){
			     m[j]=Float.parseFloat(points.get(i).split(" ")[j]);
			     n[j]=Float.parseFloat(points_last.get(i).split(" ")[j]);
			}
			tmp=tmp+Distance(m,n);
		}
		return tmp/points.size();
	}

	public static void main(String[] args) throws IOException{
		K_means a=new K_means();
		System.out.println("把样本聚类,设置分为5类,结果如下:");
		System.out.println("第1类:"+a.K_means_method(a.data,5).get(0));
		System.out.println("第2类:"+a.K_means_method(a.data,5).get(1));
		System.out.println("第3类:"+a.K_means_method(a.data,5).get(2));
		System.out.println("第4类:"+a.K_means_method(a.data,5).get(3));
		System.out.println("第5类:"+a.K_means_method(a.data,5).get(4));
	}

}

 

原始数据:

1.5 1.2 0.3
1.3 1.3 1.0
0.3 2.2 0.3
2.2 1.3 1.0
1.4 1.2 1.3
2.5 0.3 0.0
1.6 1.2 1.9
1.7 1.3 1.0
0.8 0.2 0.3
1.9 3.9 1.0
0.1 1.2 1.3
1.1 0.3 0.0
0.5 1.3 0.3
1.1 1.3 1.0
2.5 0.2 1.3
3.1 1.3 1.0
1.5 1.6 0.3
2.1 1.5 1.0
3.5 1.2 1.3
1.1 2.4 1.0
2.5 1.2 0.3
1.1 0.2 1.0
1.1 1.4 1.0
2.5 1.5 0.6
3.1 1.7 1.4
4.5 1.8 1.3
2.1 2.9 1.8
3.5 1.1 0.4
4.1 0.8 1.2

聚类结果:

把样本聚类,设置分为5类,结果如下:
第1类:[1.5 1.2 0.3, 2.5 0.3 0.0, 0.8 0.2 0.3, 1.1 0.3 0.0, 1.1 0.2 1.0]
第2类:[0.3 2.2 0.3, 0.1 1.2 1.3, 0.5 1.3 0.3, 1.1 1.3 1.0, 1.5 1.6 0.3, 1.1 1.4 1.0]
第3类:[1.9 3.9 1.0, 1.1 2.4 1.0, 2.1 2.9 1.8]
第4类:[2.5 0.2 1.3, 3.1 1.3 1.0, 3.5 1.2 1.3, 2.5 1.2 0.3, 2.5 1.5 0.6, 3.1 1.7 1.4, 4.5 1.8 1.3, 3.5 1.1 0.4, 4.1 0.8 1.2]
第5类:[1.3 1.3 1.0, 2.2 1.3 1.0, 1.4 1.2 1.3, 1.6 1.2 1.9, 1.7 1.3 1.0, 2.1 1.5 1.0]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值