1、K-近邻算法(Knn)

其原理为在一个样本空间中,有一些已知分类的样本,当出现一个未知分类的样本,则根据距离这个未知样本最近的k个样本来决定。

举例:爱情电影和动作电影,它们中都存在吻戏和动作,出现一个未知分类的电影,将根据以吻戏数量和动作数量建立的坐标系中距离未知分类所在点的最近的k个点来决定。

2、算法实现步骤

(1)计算所有点距离未知点的欧式距离

(2)对所有点进行排序

(3)找到距离未知点最近的k个点

(4)计算这k个点所在分类出现的频率

(5)选择频率最大的分类即为未知点的分类

3、java实现

Point类

  1. public class Point {
  2. private long id;
  3. private double x;
  4. private double y;
  5. private String type;
  6.  
  7. public Point(long id,double x, double y) {
  8. this.x = x;
  9. this.y = y;
  10. this.id = id;
  11. }
  12.  
  13. public Point(long id,double x, double y, String type) {
  14. this.x = x;
  15. this.y = y;
  16. this.type = type;
  17. this.id = id;
  18. }
  19.  
  20. //get、set方法省略
  21. }

Distance类

  1. public class Distance {
  2. // 已知点id
  3. private long id;
  4. // 未知点id
  5. private long nid;
  6. // 二者之间的距离
  7. private double disatance;
  8.  
  9. public Distance(long id, long nid, double disatance) {
  10. this.id = id;
  11. this.nid = nid;
  12. this.disatance = disatance;
  13. }
  14.  
  15. //get、set方法省略
  16.  
  17. }

比较器CompareClass类

  1. import java.util.Comparator;
  2. //比较器类
  3. public class CompareClass implements Comparator<Distance>{
  4.  
  5. public int compare(Distance d1, Distance d2) {
  6. return d1.getDisatance()>d2.getDisatance()?20 : -1;
  7. }
  8.  
  9. }

KNN主类

  1. /**
  2. *
  3. 1、输入所有已知点
  4. 2、输入未知点
  5. 3、计算所有已知点到未知点的欧式距离
  6. 4、根据距离对所有已知点排序
  7. 5、选出距离未知点最近的k个点
  8. 6、计算k个点所在分类出现的频率
  9. 7、选择频率最大的类别即为未知点的类别
  10. *
  11. * @author fzj
  12. *
  13. */
  14. public class KNN {
  15.  
  16. public static void main(String[] args) {
  17.  
  18. // 一、输入所有已知点
  19. List<Point> dataList = creatDataSet();
  20. // 二、输入未知点
  21. Point x = new Point(5, 1.2, 1.2);
  22. // 三、计算所有已知点到未知点的欧式距离,并根据距离对所有已知点排序
  23. CompareClass compare = new CompareClass();
  24. Set<Distance> distanceSet = new TreeSet<Distance>(compare);
  25. for (Point point : dataList) {
  26. distanceSet.add(new Distance(point.getId(), x.getId(), oudistance(point,
  27. x)));
  28. }
  29. // 四、选取最近的k个点
  30. double k = 5;
  31.  
  32. /**
  33. * 五、计算k个点所在分类出现的频率
  34. */
  35. // 1、计算每个分类所包含的点的个数
  36. List<Distance> distanceList= new ArrayList<Distance>(distanceSet);
  37. Map<String, Integer> map = getNumberOfType(distanceList, dataList, k);
  38.  
  39. // 2、计算频率
  40. Map<String, Double> p = computeP(map, k);
  41.  
  42. x.setType(maxP(p));
  43. System.out.println("未知点的类型为:"+x.getType());
  44. }
  45.  
  46. // 欧式距离计算
  47. public static double oudistance(Point point1, Point point2) {
  48. double temp = Math.pow(point1.getX() - point2.getX(), 2)
  49. + Math.pow(point1.getY() - point2.getY(), 2);
  50. return Math.sqrt(temp);
  51. }
  52.  
  53. // 找出最大频率
  54. public static String maxP(Map<String, Double> map) {
  55. String key = null;
  56. double value = 0.0;
  57. for (Map.Entry<String, Double> entry : map.entrySet()) {
  58. if (entry.getValue() > value) {
  59. key = entry.getKey();
  60. value = entry.getValue();
  61. }
  62. }
  63. return key;
  64. }
  65.  
  66. // 计算频率
  67. public static Map<String, Double> computeP(Map<String, Integer> map,
  68. double k) {
  69. Map<String, Double> p = new HashMap<String, Double>();
  70. for (Map.Entry<String, Integer> entry : map.entrySet()) {
  71. p.put(entry.getKey(), entry.getValue() / k);
  72. }
  73. return p;
  74. }
  75.  
  76. // 计算每个分类包含的点的个数
  77. public static Map<String, Integer> getNumberOfType(
  78. List<Distance> listDistance, List<Point> listPoint, double k) {
  79. Map<String, Integer> map = new HashMap<String, Integer>();
  80. int i = 0;
  81. System.out.println("选取的k个点,由近及远依次为:");
  82. for (Distance distance : listDistance) {
  83. System.out.println("id为" + distance.getId() + ",距离为:"
  84. + distance.getDisatance());
  85. long id = distance.getId();
  86. // 通过id找到所属类型,并存储到HashMap中
  87. for (Point point : listPoint) {
  88. if (point.getId() == id) {
  89. if (map.get(point.getType()) != null)
  90. map.put(point.getType(), map.get(point.getType()) + 1);
  91. else {
  92. map.put(point.getType(), 1);
  93. }
  94. }
  95. }
  96. i++;
  97. if (i >= k)
  98. break;
  99. }
  100. return map;
  101. }
  102.  
  103. public static ArrayList<Point> creatDataSet(){
  104.  
  105. Point point1 = new Point(1, 1.0, 1.1, "A");
  106. Point point2 = new Point(2, 1.0, 1.0, "A");
  107. Point point3 = new Point(3, 1.0, 1.2, "A");
  108. Point point4 = new Point(4, 0, 0, "B");
  109. Point point5 = new Point(5, 0, 0.1, "B");
  110. Point point6 = new Point(6, 0, 0.2, "B");
  111.  
  112. ArrayList<Point> dataList = new ArrayList<Point>();
  113. dataList.add(point1);
  114. dataList.add(point2);
  115. dataList.add(point3);
  116. dataList.add(point4);
  117. dataList.add(point5);
  118. dataList.add(point6);
  119.  
  120. return dataList;
  121. }
  122. }

4、运行结果

参考

[1] 《机器学习实战》

数据挖掘(二)——Knn算法的java实现的更多相关文章

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

    在十大经典数据挖掘算法中,KNN算法算得上是最为简单的一种.该算法是一种惰性学习法(lazy learner),与决策树.朴素贝叶斯这些急切学习法(eager learner)有所区别.惰性学习法仅仅 ...

  2. KNN算法java实现代码注释

    K近邻算法思想非常简单,总结起来就是根据某种距离度量检测未知数据与已知数据的距离,统计其中距离最近的k个已知数据的类别,以多数投票的形式确定未知数据的类别. 一直想自己实现knn的java实现,但限于 ...

  3. KNN算法介绍及源码实现

    一.KNN算法介绍 邻近算法,或者说K最邻近(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它 ...

  4. 深入浅出KNN算法(一) KNN算法原理

    一.KNN算法概述 KNN可以说是最简单的分类算法之一,同时,它也是最常用的分类算法之一,注意KNN算法是有监督学习中的分类算法,它看起来和另一个机器学习算法Kmeans有点像(Kmeans是无监督学 ...

  5. 机器学习——KNN算法(k近邻算法)

    一 KNN算法 1. KNN算法简介 KNN(K-Nearest Neighbor)工作原理:存在一个样本数据集合,也称为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分 ...

  6. KNN算法 - 数据挖掘算法(3)

    (2017-04-10 银河统计) KNN算法即K Nearest Neighbor算法.这个算法是机器学习里面一个比较经典的.相对比较容易理解的算法.其中的K表示最接近自己的K个数据样本.KNN算法 ...

  7. 机器学习之二:K-近邻(KNN)算法

    一.概述 K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中 ...

  8. 深入浅出KNN算法(二) sklearn KNN实践

    姊妹篇: 深入浅出KNN算法(一) 原理介绍 上次介绍了KNN的基本原理,以及KNN的几个窍门,这次就来用sklearn实践一下KNN算法. 一.Skelarn KNN参数概述 要使用sklearnK ...

  9. CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现

    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CR ...

随机推荐

  1. HDU5816 Hearthstone

    Hearthstone                                                                        Time Limit: 2000/ ...

  2. RabbitMQ Routing 消息路由

    上篇文章中,我们构建了一个简单的日志系统.接下来,我们将丰富它:能够使用不同的severity来监听不同等级的log.比如我们希望只有error的log才保存到磁盘上. 1. Bindings绑定 上 ...

  3. Linux下Oracle表空间及用户创建

    记录详细过程以备使用 Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 Connected as sys@i ...

  4. [转]SDN与OpenFlow技术简介

    http://blog.163.com/s_zhchluo/blog/static/15014708201411144727961/ 本文是2012年文章,对Openflow的发展.规范.应用和SDN ...

  5. 对js中闭包,作用域,原型的理解

    前几天,和朋友聊天,聊到一些js的基础的时候,有一种‘好像知道,好像又不不知道怎么讲的感觉’...于是捡起书,自己理一理,欢迎拍砖. 闭包 理解闭包首先要理解,js垃圾回收机制,也就是当一个函数被执行 ...

  6. Ubuntu 16.04下Samba服务器搭建和配置(配截图)

    一.相关介绍 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和 ...

  7. shell脚本执行错误 $'\r':command not found

    shell脚本执行错误 $'\r':command not found Linux下有命令dos2unix 可以用一下命令测试 vi -b filename 我们只要输入dos2unix *.sh就可 ...

  8. HTML学习二_HTML常用的行级标签,常用实体字符及表单标签

    HTML常用的行级标签(行内元素)不独占一行### 有语义的行内元素 #### HTML链接 a标签 ```angular2html<a href="链接地址">链接文 ...

  9. The EntityFramework package is not installed on project

    VS2015 使用EF的code first 报错 Get-Package : 找不到与参数名称“ProjectName”匹配的参数.所在位置 packages\EntityFramework.6.1 ...

  10. [Charles]SSLHandshake: Received fatal alert: certificate_unknown

    ---------------------- 转载请注明出处 http://www.cnblogs.com/dzblog/p/8119712.html --------------------- 今天 ...