數據挖掘聚合算法K-Means
阿新 • • 發佈:2017-12-29
隨機 [] 代碼 date style 初始 .com clust show
目錄
- 基本信息
- 工作原理
- 算法優缺點
- 算法實現
基本信息
K-means算法是很典型的基於距離的聚類算法,采用距離作為相似性的評價指標,即認為兩個對象的距離越近,其相似度就越大。該算法認為簇是由距離靠近的對象組成的,因此把得到緊湊且獨立的簇作為最終目標。
工作原理
從n個數據對象任意選擇 k 個對象作為初始聚類中心;而對於所剩下其它對象,則根據它們與這些聚類中心的相似度(距離),分別將它們分配給與其最相似的(聚類中心所代表的)聚類;然 後再計算每個所獲新聚類的聚類中心(該聚類中所有對象的均值);不斷重復這一過程直到聚類中心K個對象不在更換為止。k個聚類具有以下特點:各聚類本身盡可能的緊湊,而各聚類之間盡可能的分開。
算法優缺點
K-Means聚類算法的優點主要集中在:
- 算法快速、簡單
- 對大數據集有較高的效率並且是可伸縮性的
- 時間復雜度接近於線性,而且適合挖掘大規模數據集,K-Means聚類算法的時間復雜度是O(nkt),其中n代表數據集中對象的數量,t代表著算法叠代的次數,k代表著簇的數目。
K-Means算法的缺點
- 很多時候,事先並不知道給定的數據集應該分成多少個類才最合適。在算法中K是事先給定的,對聚類結果有較大的影響,一旦初始值選擇不好,可能得到有效的聚類結果,對於該問題的解決,許多算法采用遺傳算法,對於數據是密集的,簇與簇之間區別較明顯,得到的聚類結果較為有效。
- 該算法需要不斷地進行樣本分類調整,不斷地計算調整後的新的聚類中心,因此當數據量非常大時,算法的時間開銷是非常大的。所以需要對算法的時間復雜度進行分析、改進,提高算法應用範圍
算法實現
例如:如下隨機生成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 }
數據挖掘聚合算法K-Means