数据挖掘聚合算法K-Means

目录

基本信息

K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

工作原理

从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然 后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到聚类中心K个对象不在更换为止。k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

算法优缺点

K-Means聚类算法的优点主要集中在:

  1. 算法快速、简单
  2. 对大数据集有较高的效率并且是可伸缩性的
  3. 时间复杂度接近于线性,而且适合挖掘大规模数据集,K-Means聚类算法的时间复杂度是O(nkt),其中n代表数据集中对象的数量,t代表着算法迭代的次数,k代表着簇的数目。

K-Means算法的缺点

  1. 很多时候,事先并不知道给定的数据集应该分成多少个类才最合适。在算法中K是事先给定的,对聚类结果有较大的影响,一旦初始值选择不好,可能得到有效的聚类结果,对于该问题的解决,许多算法采用遗传算法,对于数据是密集的,簇与簇之间区别较明显,得到的聚类结果较为有效。
  2. 该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的。所以需要对算法的时间复杂度进行分析、改进,提高算法应用范围

算法实现

例如:如下随机生成1-100内10个double类型的数,可以看出数据簇与簇之间区别较为明显,得到的聚类较为有效,结果也比较明显。

如下:随机生成100个数

 

 代码:

 1 namespace DataStructure
 2 {
 3     using System;
 4     using System.Collections.Generic;
 5     /// <summary>
 6     /// author yanhf
 7     /// K-Means
 8     /// </summary>
 9     public class K_Means
10     {
11         /// <summary>
12         /// Update index cluster identification based on cluster point key
13         /// </summary>
14         /// <param name="data">Data</param>
15         /// <param name="index">index</param>
16         /// <param name="key">key values</param>
17         public static void _K_Means(double[] data, ref int[] index, int[] key)
18         {
19             bool change = true;
20             int _index = 0;
21             double Length = 0;
22             while (change)
23             {
24                 change = false;
25                 for (int i = 0; i < data.Length; i++)//根据当前的聚簇点更新index聚簇标识数组
26                 {
27                     for (int j = 0; j < key.Length; j++)
28                     {
29                         double currentLength = Math.Abs(data[key[j]] - data[i]);
30                         if (j == 0 || Length > currentLength)
31                         {
32                             Length = Math.Abs(data[key[j]] - data[i]);
33                             _index = j + 1;
34                         }
35                     }
36                     index[i] = _index;
37                     Length = 0;
38                 }
39                 change = _ChangeKey(data, index, ref key);
40             }
41         }
42         /// <summary>
43         /// Judging the current Key needs not to be changed
44         /// </summary>
45         /// <param name="data">Data</param>
46         /// <param name="index">index</param>
47         /// <param name="key">key values</param>
48         /// <returns></returns>
49         public static bool _ChangeKey(double[] data, int[] index, ref int[] key)
50         {
51             bool IsChange = false;
52             int i = 0;
53             List<double> _listData = new List<double>();
54             while (i++ < key.Length)
55             {
56                 _listData.Clear();
57                 for (int j = 0; j < index.Length; j++)
58                 {
59                     if (index[j] == i)
60                     {
61                         _listData.Add(data[j]);
62                     }
63                 }
64                 _listData.Sort();
65                 if (_listData.Count > 1)
66                 {
67                     if (key[i - 1] != _index(data, _listData[_listData.Count / 2]))
68                     {
69                         IsChange = true;
70                         key[i - 1] = _index(data, _listData[_listData.Count / 2]);
71                     }
72                 }
73             }
74             return IsChange;
75         }
76         /// <summary>
77         /// Get the index in the key's data
78         /// </summary>
79         /// <param name="data">Data</param>
80         /// <param name="num">key values</param>
81         /// <returns></returns>
82         public static int _index(double[] data, double num)
83         {
84             List<double> _listData = new List<double>(data);
85             return _listData.IndexOf(num) >= 0 ? _listData.IndexOf(num) : -1;
86         }
87     }
88 }
 1 using DataStructure;
 2 using System;
 3 
 4 namespace ClusterNumeric
 5 {
 6     class ClusterNumProgram
 7     {
 8         public static int dataNumber = 0;
 9         public static int keyNumber = 0;
10         static void Main(string[] args)
11         {
12             start:
13             string[] inputArray = null;
14             {
15                 Console.WriteLine("
Enter the total number of data you want to divide and The number of divisions
For example: 100,3");
16                 string input = Console.ReadLine();
17                 inputArray = input.Split(new char[] { ',' });
18             } while (!int.TryParse(inputArray[0], out dataNumber) || !int.TryParse(inputArray[1], out keyNumber) || keyNumber >= dataNumber) ;
19 
20             Random random = new Random();
21             double[] _data = new double[dataNumber];
22             Console.WriteLine("
Show the total number of  random generated  data");
23             Console.WriteLine("-------------------------------------------------------------------------");
24             int M = 1;
25             for (int i = 0; i < _data.Length; i++)
26             {
27                 _data[i] = Math.Round(random.NextDouble() * (100 < dataNumber ? dataNumber : 100), 2);
28                 Console.Write(_data[i].ToString("F2").PadLeft(7));
29                 if (M++ % 10 == 0)
30                 {
31                     Console.WriteLine();
32                 }
33             }
34             int[] _index = new int[dataNumber];
35             int[] keyData = new int[keyNumber];
36             for (int i = 0; i < keyNumber; i++)
37             {
38                 keyData[i] = random.Next(0, dataNumber);
39             }
40             K_Means._K_Means(_data, ref _index, keyData);
41             Console.WriteLine("
*************************************************************************");
42             Console.WriteLine("
Show the Result");
43             Console.WriteLine("-------------------------------------------------------------------------");
44             for (int i = 0; i < keyData.Length; i++)
45             {
46                 M = 1;
47                 Console.WriteLine("Value values of the " + (i + 1) + " group:key " + _data[keyData[i]].ToString().PadRight(7));
48                 Console.WriteLine();
49                 for (int j = 0; j < _index.Length; j++)
50                 {
51                     if (_index[j] == i + 1)
52                     {
53                         Console.Write(_data[j].ToString("F2").PadLeft(7));
54                         if (M++ % 10 == 0)
55                         {
56                             Console.WriteLine();
57                         }
58                     }
59                 }
60                 Console.WriteLine();
61                 Console.WriteLine("-------------------------------------------------------------------------");
62             }
63             Console.WriteLine("*************************************************************************");
64             goto start;
65         }
66     }
67 }
原文地址:https://www.cnblogs.com/yanhf/p/8136274.html