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

namespace K_means
{
    public class Kmeans
    {
        double[,] inPut;//数据
        int k;//类别数
        int Num;//文件数
        int sub;//特征值数
        int[] groupNum ;//各组数目
        public Kmeans(double[,] input)
        {
            inPut = input;
            Num = input.GetLength(0);
            sub = input.GetLength(1);
            k = (int)Math.Sqrt(Num) + 1;
            groupNum = new int[k];
        }

        public int[,] GetProcess()
        {
            double[,] tmpCenter = new double[k, sub];
            for (int i = 0; i < k; i++)
                for (int j = 0; j < sub; j++)
                    tmpCenter[i, j] = inPut[i, j];
            double[,] preCenter = new double[k, sub];
            int[,] resultP ;//= new int[k, Num];
            while (true)
            {
                 resultP = new int[k, Num];

                #region //清空各组的数目
                for (int i = 0; i < k; i++)
                {
                    groupNum[i] = 0;
                }
                #endregion

                #region //根据点到质心的距离,将点放到不同的组中

                for (int i = 0; i < Num; i++)
                {
                    double tmpDis = 0.0;
                    int index = 0;
                    for (int j = 0; j < k; j++)
                    {
                        double tmpIn = 0.0;
                        for (int m = 0; m < sub; m++)
                        {
                            tmpIn += Math.Pow((inPut[i, m] - tmpCenter[j, m]), 2);
                        }
                        if (j == 0)
                        {
                            tmpDis = tmpIn;
                            index = 0;
                        }
                        else
                        {
                            if (tmpDis > tmpIn)
                            {
                                tmpDis = tmpIn;
                                index = j;
                            }
                        }
                    }
                    int groupKnum = groupNum[index];
                    resultP[index, groupKnum] = i+1;
                    groupNum[index]++;
                }
                #endregion

                #region //保存质心
                for (int i = 0; i < k; i++)
                    for (int j = 0; j < sub; j++)
                        preCenter[i, j] = tmpCenter[i, j];
                #endregion

                #region //确定新质心
                for (int i = 0; i < k; i++)
                {
                    int kNum=groupNum[i];
                    if (kNum > 0)
                    {
                        for (int j = 0; j < sub; j++)
                        {
                            double tmp = 0.0;
                            for (int m = 0; m < kNum; m++)
                            {
                                int groupIndex = resultP[i,m]-1;
                                tmp += inPut[groupIndex, j];
                            }
                            tmpCenter[i, j] = tmp / kNum;
                        }
                    }
                }
                #endregion

                #region //判断质心是否变化
                bool judge = true;
                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < sub; j++)
                    {
                        judge = judge && (preCenter[i,j]==tmpCenter[i,j]);
                    }
                }
                if (judge)
                {
                    break;
                }
                #endregion
              
            }
            return resultP;
        }

    }
}

你可能感兴趣的:(C#实现简单的K-means聚类算法)