[C#]K均值聚类

原创 2011年01月24日 18:01:00

写完了怕丢了,放在这里。不过写的不是很好,没有进行过优化~~

 

 

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Collections;

 

namespace Similarity

{

    class myClusterFun

    {

        public static int[][] CluEntran(int[][] HashArr, int NumberOfCenter)//聚类的函数的入口

        {

            //程序的初始化及参数的设定

            int LoopTimesThres = 300;//设置最大的循环次数

            int LoopTimes = 0;//循环次数

            int JudgeConverg = 1;//记录是否收敛

            int NumberOfDoc = HashArr.Length;//待比较的对象的数量

            int AveCenterGap=0;

            int LastAveCenterGap = 0;

            int ConverCount = 0;

            ArrayList ClusterResult = new ArrayList();//存储每次聚类结果

            ArrayList NewCenter = new ArrayList();//存储每次聚类的新中心

            ArrayList CenterGap = new ArrayList();//存储每次聚类中心的偏差

            int[][] SingleClusterResult = new int[NumberOfCenter][];//暂存每次聚类的结果

            int[][] SingleNewCenter = new int[NumberOfCenter][];//暂存每次聚类后形成的新的中心

            int[][] SingleLastCenter = new int[NumberOfCenter][];//暂存每次聚类后形成的新的中心

            int[] SingleCenterGap = new int[NumberOfCenter];//暂存每次聚类后中心的偏差情况

            //初始化:确定初始中心

            for (int i = 0; i < NumberOfCenter; i++)

            {

                SingleLastCenter[i] = new int[HashArr[0].Length];

                SingleNewCenter[i] = new int[HashArr[0].Length];

            }

            int[] TempRec = new int[NumberOfCenter];

            TempRec=InitialFunc(NumberOfCenter, NumberOfDoc);

            for (int i = 0; i < NumberOfCenter; i++)

            {

                for (int j = 0; j < HashArr[0].Length; j++)

                    SingleNewCenter[i][j] = HashArr[TempRec[i]][j];

            }

            NewCenter.Add(SingleNewCenter);

            while (JudgeConverg == 1)//记录的收敛情况

            {

                //对每个中心进行聚类

                for (int i = 0; i < NumberOfCenter; i++)

                {

                    for (int j = 0; j < HashArr[0].Length; j++)

                        SingleLastCenter[i][j] = SingleNewCenter[i][j];

                }

                SingleClusterResult = GatherToCenter(ref SingleNewCenter, HashArr, NumberOfCenter);

                LoopTimes++;

                //记录每次聚类的结果、以及新中心

                NewCenter.Add(SingleNewCenter);

                ClusterResult.Add(SingleClusterResult);

                //判断是否收敛

                SingleCenterGap = JudgeConverge(SingleNewCenter, SingleLastCenter, NumberOfCenter);//收敛的结果

                CenterGap.Add(SingleCenterGap);//记录收敛结果

                for (int i = 0; i < NumberOfCenter; i++)

                    AveCenterGap += SingleCenterGap[i];

                AveCenterGap = AveCenterGap / NumberOfCenter;

                if (AveCenterGap == LastAveCenterGap)

                    ConverCount++;

                if (ConverCount>20||(LoopTimes==LoopTimesThres))

                    JudgeConverg = 0;

                LastAveCenterGap = AveCenterGap;

                AveCenterGap = 0;

            }  

            if (LoopTimes == LoopTimesThres)

                Console.WriteLine("Converge failed!!");

            return SingleClusterResult;//返回结果

        }

        public static int[] InitialFunc(int NumberOfCenter, int NumberOfDoc)//确定几个起始点的位置

        {

            int[] Res = new int[NumberOfCenter];

            int step = NumberOfDoc / NumberOfCenter;

            int RandomStep = 0;

            Random ran = new Random();

            RandomStep = ran.Next(NumberOfDoc)+1;

            for (int i = 0; i < NumberOfCenter; i++)

            {

                Res[i] = (step * i + RandomStep) % NumberOfDoc;

            }

            return Res;

        }

        public static int[][] GatherToCenter(ref int[][] SingleNewCenter, int[][] HashArr,int NumberOfCenter)//对给定的点进行聚类,同时得到新的中心

        {       

            int dis;//中间变量,记录距离

            int rec = 0;//中间变量,记录属于的类号

            int NumberOfDoc = HashArr.Length;

            int[] ClusterNum = new int[NumberOfCenter];//记录每一个类的数量

            int[] LoopTemp = new int[NumberOfDoc];//记录类号的中间数组,数组元素的值是类号,数组下标表示元素        

            int[][] ResRecord = new int[NumberOfCenter][];//记录聚类结果

            int[][] CenterSum = new int[NumberOfCenter][];//求中心时的中间变量,对各元素做和

            //分类的过程

            for (int i = 0; i < NumberOfDoc; i++)

            {

                dis = 0;

                for (int j = 0; j < NumberOfCenter; j++)

                {

                    if (CosComp(HashArr[i], SingleNewCenter[j]) > dis)

                    {

                        dis = CosComp(HashArr[i], SingleNewCenter[j]);

                        rec = j;

                    }

                }

                LoopTemp[i] = rec;

                ClusterNum[rec]++;

            }

            //将分类的结果进行记录

            for(int i=0;i<NumberOfCenter;i++)

               ResRecord[i]=new int[ClusterNum[i]];

            int ClusterTemp;

            int[] ClusterIndexTemp = new int[NumberOfCenter];

            for (int i = 0; i < NumberOfDoc; i++)

            {

                ClusterTemp = LoopTemp[i];

                ResRecord[ClusterTemp][ClusterIndexTemp[ClusterTemp]] = i;

                ClusterIndexTemp[ClusterTemp]++;

            }

            //计算新的中心

            for (int i = 0; i < NumberOfCenter; i++)

            {

                CenterSum[i] = new int[HashArr[0].Length];

                if (ClusterNum[i] == 0) //对于类成员数为零的,直接用上一个中心

                {

                    for (int k = 0; k < HashArr[0].Length; k++)

                    {

                        CenterSum[i][k] += SingleNewCenter[i][k];                        

                    }

                    ClusterNum[i]++;

                }

                else

                {

                    for (int j = 0; j < ResRecord[i].Length; j++)

                    {

                        int t = ResRecord[i][j];

                        for (int k = 0; k < HashArr[0].Length; k++)

                            CenterSum[i][k] = HashArr[t][k] + CenterSum[i][k];

                    }

                }

            }

            for (int i = 0; i < NumberOfCenter; i++)

            {

                for (int j = 0; j < HashArr[0].Length; j++)

                {

                    SingleNewCenter[i][j] = CenterSum[i][j] / ClusterNum[i];

                }

            }           

            return ResRecord;

        }

        public static int[] JudgeConverge(int[][] SingleNewCenter, int[][] LastNewCenter,int NumberOfCenter)//比较前后的中心点

        {

            int[] Result = new int[NumberOfCenter];

            for (int i = 0; i < NumberOfCenter; i++)

                Result[i] = CosComp(SingleNewCenter[i], LastNewCenter[i]);

            return Result;

        }

        public static int CosComp(int[] HashArr1, int[] HashArr2)//求向量的Cos距离

        {

            double Vdot = VecDot(HashArr1, HashArr2);

            double l1 = VecMod(HashArr1);

            double l2 = VecMod(HashArr2);

            double doubleresult = (Vdot / (l1 * l2)) * 100;

            int result = (int)Math.Floor(doubleresult);//将结果近似为整数

            return result;

        }

        public static double VecDot(int[] a, int[] b)//求向量的点积

        {

            double sum = 0;

            for (int i = 0; i < a.Length; i++)

            {

                sum += a[i] * b[i];

            }

            return sum;

        }

        public static double VecMod(int[] a)//求向量的模

        {

            double sum = 0;

            for (int i = 0; i < a.Length; i++)

            {

                sum += a[i] * a[i];

            }

            sum = Math.Sqrt(sum);

            return sum;

        }

    }

}

 

经典聚类算法——K-Means算法实现(C#,适用于初学者)

  • 2010年01月06日 11:04
  • 26KB
  • 下载

K-均值聚类算法

在此之前子丰发表的机器学习算法的博文都是监督学习算法。如果大家感兴趣的话,可以查看相关博文,如:k-近邻算法、决策树、朴素贝叶斯、Logistic回归、AdaBoost元算法、回归和树回归等。 ...
  • softimite_zifeng
  • softimite_zifeng
  • 2016年11月16日 10:26
  • 620

Win8 Metro(C#)数字图像处理--2.52图像K均值聚类

 [函数名称]   图像KMeans聚类      KMeansCluster(WriteableBitmap src,int k) /// /// KMeans Cl...
  • Trent1985
  • Trent1985
  • 2015年04月18日 09:33
  • 1191

C#实现简单的K-means聚类算法

namespace K_means{    public class Kmeans    {        double[,] inPut;//数据        int k;//类别数       ...
  • tighuntliu
  • tighuntliu
  • 2009年05月05日 16:45
  • 2251

C#---聚类

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Wellcomm...
  • u012319493
  • u012319493
  • 2017年09月07日 17:42
  • 234

K均值聚类以及matlab实现

K均值聚类是最基础的一种聚类方法。K均值聚类,就是把看起来最集中、最不分散的簇标签分配到输入训练样本里。具体而言,通过下式计算簇y的分散情况。在这里,表示的是满足的y的和。上式的为簇y的中心,为属于簇...
  • lfdanding
  • lfdanding
  • 2016年02月27日 11:19
  • 2200

机器学习练习(七)—— K-均值聚类与主成分分析

作者:John Wittenauer 翻译:GreatX 源:Machine Learning Exercises In Python, Part 7这篇文章是一系列 Andrew Ng 在 Co...
  • And_w
  • And_w
  • 2017年02月13日 15:38
  • 1249

K-均值聚类算法的原理与实现

K-均值聚类算法的原理与实现
  • xiaolewennofollow
  • xiaolewennofollow
  • 2015年05月06日 21:01
  • 4095

通过K-均值聚类算法对图像进行分割

一.实验目的 通过K-均值聚类算法对图像进行分割。 二.算法概要 图像分割是一种重要的图像分析技术。在对图像的研究和应用中,人们往往仅对图像中的某些部分感兴趣。这些部分常称为目标或前景(其他部分称为...
  • a350203223
  • a350203223
  • 2014年07月07日 17:21
  • 1448

K均值聚类(K-means)算法及应用(matlab)

一、定义: K-means算法是硬聚类算法,以欧式距离作为相似度测度,它是求对应某一初始聚类中心向量V最优分类,使得评价指标J最小。算法采用误差平方和准则函数作为聚类准则函数。 ...
  • xingyanxiao
  • xingyanxiao
  • 2015年06月04日 09:30
  • 5412
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[C#]K均值聚类
举报原因:
原因补充:

(最多只允许输入30个字)