数据挖掘之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 }

 以电影数据为例:

电影打斗镜头接吻镜头电影类型
13104爱情片
22100爱情片
3181爱情片
410110动作片
5995动作片
6982动作片
71890未知

该数据有两个维度,一个是打斗镜头的次数,另一个是接吻镜头的次数,我们需要根据前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算法(C#实现)》

 可以看到,KNN分类器将第7部电影正确地归为了爱情片。

注:作者本人也在学习中,能力有限,如有错漏还请不吝指正。转载请注明作者。

    原文作者:何燕杰
    原文地址: https://www.cnblogs.com/HeYanjie/p/5817330.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞