zoukankan      html  css  js  c++  java
  • 数据挖掘之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部电影正确地归为了爱情片。

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



  • 相关阅读:
    网络通信协议八之(传输层)TCP协议详解
    MongoDB数据库连接失败
    Flask web开发之路十四
    Flask web开发之路十三
    Flask web开发之路十二
    Flask web开发之路十一
    Flask web开发之路十
    NEERC 1999 Advertisement /// oj22646
    upper_bound() lower_bound() 用法
    palindrome 回文 /// Manacher算法
  • 原文地址:https://www.cnblogs.com/HeYanjie/p/5817330.html
Copyright © 2011-2022 走看看