数据挖掘之KMEANS算法

KMeans算法的代码实现。

这是我学习数据挖掘KMEans算法的一个简明版本。

这个代码比较简单。

package cluster;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Cluster {
	private double ClusterCenter;
	private double[] ClusterData;
	private List<Double> listData;
	public Cluster(double ClusterCenter){
		this.ClusterCenter=ClusterCenter;
		init();
	}
	private void init(){
		double[] data=new double[1];
		//data[0]=1e308;
		ClusterData=data;
		listData=new ArrayList<Double>();
	}
	/**
	 * 分配数据给该数据中心函数
	 * */
	public void AssDPToCCenter(double datapoint){
		listData.add(datapoint);
		double datas[]=new double[listData.size()];
		for(int i=0;i<datas.length;i++){
			datas[i]=listData.get(i);
		}
		this.ClusterData=datas;
	}	
	/**
	 * 获得当前聚类的聚类中心与每个数值之间的方差和
	 * */
	public double getVAR(){
		return MathUtil.getVARIANCE(this.ClusterData,this.ClusterCenter);
	}
	/**
	 * 以下方法用来重新计算聚类中心
	 * */
	public double reGetCenter(double eps){
		double center=1e308;
		double d;
		System.out.println("this clusterData="+Arrays.toString(ClusterData));
		d=MathUtil.getMeans(ClusterData);
		double[] data=MathUtil.getDistanceArray(ClusterData, d);
		System.out.println("data="+Arrays.toString(data));
		Integer[] intmarks=MathUtil.getMinValueMarks(data, eps);
		double[] dataArrs=new double[intmarks.length];
		if(intmarks.length==1){
			center=ClusterData[intmarks[0]];
		}
		if(intmarks.length>1){	
			for(int i=0;i<dataArrs.length;i++){
				dataArrs[i]=ClusterData[intmarks[i]];
			}
			if(MathUtil.isDuplicateExist(dataArrs)){
				System.out.println("-------------------------------------------------------------");
				center=MathUtil.getMinValue(dataArrs);
			}else{
				center=dataArrs[0];
			}
			
		}
		System.out.println("intmarks="+Arrays.toString(intmarks));
package K_MEANS;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import Matrix.Matrix;
import cluster.Cluster;
import cluster.MathUtil;

/**
 * @param K为聚类的个数
 * @param data为聚类的数据
 * @param cluster聚类数
 * @param MaxIterateStep最大迭代数
 * */
public class K_MEANS {
	public int K;
	public double[] data;
	public Cluster[] clusters;
	public K_MEANS(int K,double[] data){
		this.K=K;
		if(K>data.length){
			this.K=data.length;
		}
		this.data=data;
		init();
	}
	/***
	 * 初始化
	 * */
	private void init(){
		this.clusters=new Cluster[K];
		int[] intArrs=getTempArrays();
		for(int i=0;i<K;i++){
			clusters[i]=new Cluster(intArrs[i]);
		}
	}
	/**
	 * 以下方法用来获得一个随机数组生成随机中心数据点
	 * */
	private int[] getTempArrays(){
		return genRandom.genRandom.getRandom(data, K);
	}
	/**
	 * 以下方法为地磁分配数据给各个聚类中心
	 * */
	public Cluster[] AssignDataToCenter(double[] datas){
		Cluster[] clusters=this.clusters;
		Matrix DistanceMatrix=getDistance(datas);
		System.out.println("DistanceMatrix"+DistanceMatrix.toString());
		for(int i=0;i<datas.length;i++){
			Integer[] min=DistanceMatrix.getMinValueColsMarks(i+1);
			
				clusters[min[0]].AssDPToCCenter(datas[i]);
			
		}
		return clusters;
	}
	/**
	 * 以下方法用来获得每个中心聚点与每个数据区域的距离
	 * */
	public Matrix getDistance(double[] data){
		double[] centers=getClusterCenter();
		Matrix DistanceMatrix=new Matrix(data.length,K);
		for(int i=1;i<=DistanceMatrix.getRownums();i++){
			for(int j=1;j<=DistanceMatrix.getColnums();j++){
				DistanceMatrix.setMatrixValue(i, j, MathUtil.getDistance(centers[j-1], data[i-1]));
			}
		}
		return DistanceMatrix;
	}
	
	/**
	 * 以下方法用来重新计算聚类中心方法
	 * */
	public Cluster[] reGetCenter(double eps){
		for(int i=0;i<this.clusters.length;i++){
			clusters[i].reGetCenter(eps);
		}
		return clusters;
	}
	
	/**
	 * 以下方法用来获得聚类中心值,返回数组
	 * */
	public double[] getClusterCenter(){
		double[] tmp=new double[K];
		for(int i=0;i<tmp.length;i++){
			tmp[i]=clusters[i].getClusterCenter();
		}
		return tmp;
	}
	/**
	 * 用来处理文本分类的主程序
	 * 将分类完成后的数据写入到硬盘当中
	 * */
	public void ProcessFiles(double eps){
		int i=0;
		List<Double> listVar=new ArrayList<Double>();
		while(true){
			AssignDataToCenter(data);
			double VAR=getTotalVAR();
			listVar.add(VAR);
			if(listVar.size()>2){	
				if(Math.abs(listVar.get(listVar.size()-2)-(listVar.get(listVar.size()-1)))<eps){
					break;
				}
//				if(i>this.MaxIterateSteps){
//					break;
//				}
			}
			reGetCenter(eps);
			clearData();
			i++;
		}
	}
	/**
	 * 获得所有聚类区域的方差和
	 * */
	public double getTotalVAR(){
		double VAR=0;
		for(int i=0;i<this.clusters.length;i++){
			VAR=clusters[i].getVAR()+VAR;
		}
		return VAR;
	}
	private void clearData(){
		for(int i=0;i<this.clusters.length;i++){
			clusters[i].clearData();
		}
	}
	public int getK() {
		return K;
	}
	public void setK(int k) {
		K = k;
	}
	public double[] getData() {
		return data;
	}
	public void setData(double[] data) {
		this.data = data;
	}
	public Cluster[] getClusters() {
		return clusters;
	}
	public void setClusters(Cluster[] clusters) {
		this.clusters = clusters;
	}
	public String toString(){
		return Arrays.toString(clusters)+this.getClusterCenter();
	}
	public static void main(String[] args){
		double[] data={2,3,4,5,20,30,40,50,100,200,300,400,500,600,700,800,900};
		K_MEANS k=new K_MEANS(2,data);
		
		k.ProcessFiles(0.0000005);
		System.out.println(Arrays.toString(k.clusters));
	}
}

package Single_Regression;


public class Regression {
	public static double getArraySUM(double[] data){
		double sum=0;
		for(int i=0;i<data.length;i++){
			sum+=data[i];
		}
		return sum;
	}
	public static double getMeanX(double[] data){
		double d=0;
		double mean=0;
		for(int i=0;i<data.length;i++){
			d+=data[i];
			
		}
		mean=d/(data.length);
		return mean;
	}
	public static double getMeanY(double[] data){
		double d=0;
		double mean=0;
		for(int i=0;i<data.length;i++){
			d+=data[i];
			
		}
		mean=d/(data.length);
		return mean;
	}
	public static double[] getXS(double[] data){
		 double dataSquare[]=new double[data.length];
		 for(int i=0;i<data.length;i++){
			 dataSquare[i]=Math.pow(data[i],2);
		 }
		 return dataSquare;
	}
	public static double[] getYS(double[] data){
		 double dataSquare[]=new double[data.length];
		 for(int i=0;i<data.length;i++){
			 dataSquare[i]=Math.pow(data[i],2);
		 }
		 return dataSquare;
	}
	public static double[] getXY(double[] datax,double[] datay){
		if(initSuccess(datax,datay)==false){
			try{
				throw new Exception("不好意思出现了错误,请检查下数据");
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		double[] dataXY=new double[datax.length];
		for(int i=0;i<datax.length;i++){
			dataXY[i]=datax[i]*datay[i];
		}
		return dataXY;
	}
	private static boolean initSuccess(double[] datax,double[] datay){
		boolean status=true;
		if(datax.length!=datay.length){
			status=false;
		}
		return status;
	}

	public static double getLXX(double[] datax){
		int n=datax.length;
		double LXX;
		LXX=getArraySUM(getXS(datax))-n*(Math.pow(getMeanX(datax), 2));
		return LXX;
	}
	public static double getLXY(double[] datax,double[] datay){
		int n=datax.length;
		double[] data=getXY(datax,datay);
		double LXY;
		LXY=getArraySUM(data)-n*(getMeanX(datax)*getMeanY(datay));
		return LXY;
	}
	public static double getLYY(double[] datay){
		int n=datay.length;
		double LYY;
		LYY=getArraySUM(getXS(datay))-n*(Math.pow(getMeanX(datay), 2));
		return LYY;
	}
	/**
	 * 获得两个数组之间的线性相关性
	 * */
	public static double getR(double[] datax,double[] datay){
		double LXY=getLXY(datax,datay);
		double LXX=getLXX(datax);
		double LYY=getLYY(datay);
		double r;
		r=LXY/((Math.sqrt(LXX))*(Math.sqrt(LYY)));
		return r;
	}
	/**
	 * 获得SSR
	 * */
	public static double getSSR(){
		return 0;
	} 

}    

System.out.println("center="+center);if(center==1e308){try{throw new Exception("不好意思,出了差错");}catch(Exception e){e.printStackTrace();}}this.ClusterCenter=center;return this.ClusterCenter;}public void setClusterData(double[] clusterData) {ClusterData = clusterData;}/** * 获得当前聚类的大小 * */public int getSize(){return this.ClusterData.length;}public double getClusterCenter() {return ClusterCenter;}public void setClusterCenter(double clusterCenter) {ClusterCenter = clusterCenter;}/** * toString方法 * */public String toString(){return "ClusterCenter="+this.ClusterCenter+","+Arrays.toString(ClusterData);}public double[] getClusterData() {return ClusterData;}/** * 清空cluster数据区域 * */public void clearData(){this.listData.clear();}}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值