首页 > 代码库 > 数据挖掘之KNN算法(C#实现)

数据挖掘之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 = dist27                     .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 Program10     {11         static void Main(string[] args)12         {13             var data = http://www.mamicode.com/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,124             };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部电影正确地归为了爱情片。

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



数据挖掘之KNN算法(C#实现)