數據挖掘聚合算法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("\nEnter the total number of data you want to divide and The number of divisions\nFor 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("\nShow 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("\n*************************************************************************");
42             Console.WriteLine("\nShow 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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM