机器学习之KNN算法思想及其实现
时间:2022-05-06
本文章向大家介绍机器学习之KNN算法思想及其实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
从一个例子来直观感受KNN思想
如下图 , 绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。
从这个例子中,我们再来看KNN思想:
1, 计算已知类别数据集合中的点与当前点之间的距离(使用欧式距离公司: d =sqrt(pow(x-x1),2)+pow(y-y1),2)
2, 按照距离递增次序排序(由近到远)
3, 选取与当前点距离最小的的K个点(如上题中的 k=3,k=5)
4, 确定前K个点所在类别的出现频率
5, 将频率最高的那组,作为该点的预测分类
实现代码:
1 package com.data.knn;
2
3 /**
4 * *********************************************************
5 * <p/>
6 * Author: XiJun.Gong
7 * Date: 2016-09-06 12:02
8 * Version: default 1.0.0
9 * Class description:
10 * <p/>
11 * *********************************************************
12 */
13 public class Point {
14
15 private double x; //x坐标
16 private double y; //y坐标
17 private double dist; //距离另一个点的距离
18
19
20
21 private String label; //所属类别
22
23 public Point() {
24 this(0d, 0d, "");
25 }
26
27 public Point(double x, double y, String label) {
28 this.x = x;
29 this.y = y;
30 this.label = label;
31 }
32
33 /*计算两点之间的距离*/
34 public double distance(final Point a) {
35 return Math.sqrt((a.x - x) * (a.x - x) + (a.y - y) * (a.y - y));
36 }
37
38 public double getX() {
39 return x;
40 }
41
42 public void setX(double x) {
43 this.x = x;
44 }
45
46 public double getY() {
47 return y;
48 }
49
50 public void setY(double y) {
51 this.y = y;
52 }
53
54 public String getLabel() {
55 return label;
56 }
57
58 public void setLabel(String label) {
59 this.label = label;
60 }
61
62
63 public double getDist() {
64 return dist;
65 }
66
67 public void setDist(double dist) {
68 this.dist = dist;
69 }
70 }
KNN实现
1 package com.data.knn;
2
3 import com.google.common.base.Preconditions;
4 import com.google.common.collect.Maps;
5
6 import java.util.Collections;
7 import java.util.Comparator;
8 import java.util.List;
9 import java.util.Map;
10
11 /**
12 * *********************************************************
13 * <p/>
14 * Author: XiJun.Gong
15 * Date: 2016-09-06 11:59
16 * Version: default 1.0.0
17 * Class description:
18 * <p/>
19 * *********************************************************
20 */
21 public class knn {
22
23 private List<Point> dataSet; //统计频率
24 private Point newPoint; //当前点
25
26
27 //进行KNN分类
28 public String classify(List<Point> dataSet, final Point newPoint, Integer K) {
29
30 Preconditions.checkArgument(K < dataSet.size(), "K的值超过了dataSet的元素");
31 //求解每一个点到新的点的距离
32 for (Point point : dataSet) {
33 point.setDist(newPoint.distance(point));
34 }
35 //进行排序
36 Collections.sort(dataSet, new Comparator<Point>() {
37 @Override
38 public int compare(Point o1, Point o2) {
39 //return o1.distance(newPoint) < o2.distance(newPoint) ? 1 : -1;
40 return o1.getDist() < o2.getDist() ? 1 : -1;
41 }
42 });
43
44 //统计前K个标签的频率
45 Map<String, Integer> map = Maps.newHashMap();
46 Integer maxCnt = -9999; //最高频率
47 String label = ""; //最高频率标签
48 Integer currentCnt = 0; //当前标签的频率
49 Integer times = 0;
50 for (Point point : dataSet) {
51 currentCnt = 1;
52 if (map.containsKey(point.getLabel())) {
53 currentCnt += map.get(point);
54 }
55 if (maxCnt < currentCnt) {
56 maxCnt = currentCnt;
57 label = point.getLabel();
58 }
59 map.put(point.getLabel(), currentCnt);
60 times++;
61 if (times > K) break;
62 }
63 return label;
64 }
65
66
67 }
1 package com.data.knn;
2
3 import com.google.common.collect.Lists;
4
5 import java.util.List;
6
7 /**
8 * *********************************************************
9 * <p/>
10 * Author: XiJun.Gong
11 * Date: 2016-09-06 14:45
12 * Version: default 1.0.0
13 * Class description:
14 * <p/>
15 * *********************************************************
16 */
17 public class Main {
18
19 public static void main(String args[]) {
20 List<Point> list = Lists.newArrayList();
21 list.add(new Point(1., 1.1, "A"));
22 list.add(new Point(1., 1., "A"));
23 list.add(new Point(0., 0., "B"));
24 list.add(new Point(0., 0.1, "B"));
25 Point point = new Point(0.5, 0.5, null);
26 KNN knn = new KNN();
27 System.out.println(knn.classify(list, point, 3));
28 }
29 }
结果:
A
- (26) 剖析包装类 (上) / 计算机程序的思维逻辑
- (25) 异常 (下) / 计算机程序的思维逻辑
- (24) 异常 (上) / 计算机程序的思维逻辑
- Python3.6新特性官方文档中文版
- (23) 枚举的本质 / 计算机程序的思维逻辑
- (22) 代码的组织机制 / 计算机程序的思维逻辑
- Python开发微信公众号后台(系列二)
- (21) 内部类的本质 / 计算机程序的思维逻辑
- (20) 为什么要有抽象类? / 计算机程序的思维逻辑
- Python云计算框架:Openstack源码分析之RabbitMQ(一)
- (38) 剖析ArrayList / 计算机程序的思维逻辑
- 破解验证,让爬取更随心所欲!
- Visual Studio Code v0.9.1 发布
- (39) 剖析LinkedList / 计算机程序的思维逻辑
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Django model 层之事务管理总结
- 如何在 asp.net core 的中间件中返回具体的页面
- Redis过期策略和内存淘汰机制
- 这会是ClickHouse解决数据一致性的新法宝吗?
- 链表:环找到了,那入口呢?
- 线程池的实现原理分析
- 工具系列 | 负载均衡算法 - 平滑加权轮询
- 原子操作类
- 阻塞队列
- 工具系列 | 负载均衡算法 - 轮询算法
- 如何避免用动态语言的思维写Go代码
- Pandas tricks 之 transform的用法
- Springboot + RabbitMQ 用了消息确认机制,感觉掉坑里了!
- 一款功能简约到可怜的SQL 客户端!
- 震惊!ConcurrentHashMap里面也有死循环,作者留的“彩蛋”?