數據挖掘之KNN算法(C#實現)


在十大經典數據挖掘算法中,KNN算法算得上是最為簡單的一種。該算法是一種惰性學習法(lazy learner),與決策樹、朴素貝葉斯這些急切學習法(eager learner)有所區別。惰性學習法僅僅只是簡單地存儲訓練元組,做一些少量工作,在真正進行分類或預測的時候才開始做更多的工作。有點像是平時不努力學習功課,到了考前才開始臨時抱佛腳的感覺。


KNNk-nearest-neighbor)算法的思想是找到在輸入新數據時,找到與該數據最接近的k個鄰居,在這k個鄰居中,找到出現次數最多的類別,對其進行歸類。


距離的計算有很多種方式,最簡單的就是直接計算歐式距離,但是根據不同的問題,也可以考慮選用不同的距離計算方式,如余弦距離等等。

詳細內容參考:https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm

C#的代碼實現如下,代碼僅供演示,運行效率不高,在大數據集上需要進行更多的優化:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using MachineLearning.UtilityFunctions;
 5 namespace MachineLearning.Classification
 6 {
 7     public class KNN
 8     {
 9         public List<int> Labels;
10         public List<double[]> Features;
11         public int K;
12         public KNN(int k, List<int> labels, List<double[]> features)
13         {
14             K = k;
15             Labels = labels;
16             Features = features;
17         }
18         public void Classify(IEnumerable<double[]> data)
19         {
20             int n = Labels.Count;
21             foreach (var line in data)
22             {
23                 var dist = new Tuple<int, double>[n];
24                 for (int i = 0; i < n; i++)
25                     dist[i] = Tuple.Create(Labels[i], Distance.Euclidean(line, Features[i]));
26                 var maxLabel = dist
27                     .OrderBy(i => i.Item2)
28                     .Take(K).GroupBy(i => i.Item1)
29                     .OrderByDescending(i => i.Count())
30                     .First().Key;
31                 Labels.Add(maxLabel);
32                 Features.Add(line);
33                 n++;
34             }
35         }
36         public void Display()
37         {
38             for (int i = 0; i < Labels.Count; i++)
39                 Console.WriteLine("{0}: {1}", Labels[i], string.Join(",", Features[i]));
40         }
41     }
42 }

 以電影數據為例:

電影 打斗鏡頭 接吻鏡頭 電影類型
1 3 104 愛情片
2 2 100 愛情片
3 1 81 愛情片
4 101 10 動作片
5 99 5 動作片
6 98 2 動作片
7 18 90 未知

該數據有兩個維度,一個是打斗鏡頭的次數,另一個是接吻鏡頭的次數,我們需要根據前6條數據來給第7部電影進行分類,判斷它是愛情片還是動作片。利用KNN算法進行分類的代碼如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using MachineLearning.Classification;
 7 namespace MachineLearning
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             var data = new List<double[]>() {
14                 new double[] {3,104},
15                 new double[] {2,100},
16                 new double[] {1,81},
17                 new double[] {101,10},
18                 new double[] {99,5},
19                 new double[] {98,2},
20             };
21             var labels = new List<int>()
22             {
23                 0,0,0,1,1,1
24             };
25             var knn = new KNN(k: 3, labels: labels, features: data);
26             knn.Display();
27             Console.WriteLine("----------------------------------------");
28             knn.Classify(new double[][] { new double[] { 18, 90 } });
29             knn.Display();
30             Console.ReadKey();
31         }
32     }
33 }

其中類別0代表愛情片,類別1代表動作片。

運行結果如圖所示:

 

 可以看到,KNN分類器將第7部電影正確地歸為了愛情片。

注:作者本人也在學習中,能力有限,如有錯漏還請不吝指正。轉載請注明作者。




免責聲明!

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



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