K-近邻算法(k-Nearest Neighbor,简称kNN)采用测量不同特征值之间的距离方法进行分类,是一种常用的监督学习方法,其工作机制很简单:给定测试样本,基于某种距离亮度找出训练集中与其靠近的k个训练样本,然后基于这k个“邻居”的信息进行预测。kNN算法属于懒惰学习,此类学习技术在训练阶段仅仅是把样本保存起来,训练时间靠小为零,在收到测试样本后在进行处理,所以可知kNN算法的缺点是计算复杂度高、空间复杂度高。但其也有优点,精度高、对异常值不敏感、无数据输入设定。

  借张图来说:

当k = 1时目标点有一个class2邻居,根据kNN算法的原理,目标点也为class2。

当k = 5时目标点有两个class2邻居,有三个class1的邻居,根据其原理,目标点的类别为class2。

算法流程

总体来说,KNN分类算法包括以下4个步骤:

①准备数据,对数据进行预处理 。

②计算测试样本点(也就是待分类点)到其他每个样本点的距离。

③对每个距离进行排序,然后选择出距离最小的K个点 。

④对K个点所属的类别进行比较,根据少数服从多数的原则,将测试样本点归入在K个点中占比最高的那一类 。

算法代码

package com.top.knn;

import com.top.constants.OrderEnum;
import com.top.matrix.Matrix;
import com.top.utils.MatrixUtil; import java.util.*; /**
* @program: top-algorithm-set
* @description: KNN k-临近算法进行分类
* @author: Mr.Zhao
* @create: 2020-10-13 22:03
**/
public class KNN {
public static Matrix classify(Matrix input, Matrix dataSet, Matrix labels, int k) throws Exception {
if (dataSet.getMatrixRowCount() != labels.getMatrixRowCount()) {
throw new IllegalArgumentException("矩阵训练集与标签维度不一致");
}
if (input.getMatrixColCount() != dataSet.getMatrixColCount()) {
throw new IllegalArgumentException("待分类矩阵列数与训练集列数不一致");
}
if (dataSet.getMatrixRowCount() < k) {
throw new IllegalArgumentException("训练集样本数小于k");
}
// 归一化
int trainCount = dataSet.getMatrixRowCount();
int testCount = input.getMatrixRowCount();
Matrix trainAndTest = dataSet.splice(2, input);
Map<String, Object> normalize = MatrixUtil.normalize(trainAndTest, 0, 1);
trainAndTest = (Matrix) normalize.get("res");
dataSet = trainAndTest.subMatrix(0, trainCount, 0, trainAndTest.getMatrixColCount());
input = trainAndTest.subMatrix(0, testCount, 0, trainAndTest.getMatrixColCount()); // 获取标签信息
List<Double> labelList = new ArrayList<>();
for (int i = 0; i < labels.getMatrixRowCount(); i++) {
if (!labelList.contains(labels.getValOfIdx(i, 0))) {
labelList.add(labels.getValOfIdx(i, 0));
}
} Matrix result = new Matrix(new double[input.getMatrixRowCount()][1]);
for (int i = 0; i < input.getMatrixRowCount(); i++) {
// 求向量间的欧式距离
Matrix var1 = input.getRowOfIdx(i).extend(2, dataSet.getMatrixRowCount());
Matrix var2 = dataSet.subtract(var1);
Matrix var3 = var2.square();
Matrix var4 = var3.sumRow();
Matrix var5 = var4.pow(0.5);
// 距离矩阵合并上labels矩阵
Matrix var6 = var5.splice(1, labels);
// 将计算出的距离矩阵按照距离升序排序
var6.sort(0, OrderEnum.ASC);
// 遍历最近的k个变量
Map<Double, Integer> map = new HashMap<>();
for (int j = 0; j < k; j++) {
// 遍历标签种类数
for (Double label : labelList) {
if (var6.getValOfIdx(j, 1) == label) {
map.put(label, map.getOrDefault(label, 0) + 1);
}
}
}
result.setValue(i, 0, getKeyOfMaxValue(map));
}
return result;
} /**
* 取map中值最大的key
*
* @param map
* @return
*/
private static Double getKeyOfMaxValue(Map<Double, Integer> map) {
if (map == null)
return null;
Double keyOfMaxValue = 0.0;
Integer maxValue = 0;
for (Double key : map.keySet()) {
if (map.get(key) > maxValue) {
keyOfMaxValue = key;
maxValue = map.get(key);
}
}
return keyOfMaxValue;
} }

KNN

注:其中的矩阵方法请参考https://github.com/ineedahouse/top-algorithm-set/blob/dev/src/main/java/com/top/matrix/Matrix.java

  升降序枚举类参考https://github.com/ineedahouse/top-algorithm-set/blob/dev/src/main/java/com/top/constants/OrderEnum.java

该算法为本人github项目中的一部分,地址为https://github.com/ineedahouse/top-algorithm-set

如果对你有帮助可以点个star~

参考

《机器学习》-周志华

《机器学习实战》-Peter Harrington

最新文章

  1. 在CDH5.5.0上安装Kudu6.0
  2. 享元模式(Flyweight Pattern)
  3. Sql Server 添加外部程序集基本操作
  4. js的隐含参数(arguments,callee,caller)使用方法
  5. 建议Javascript以后都用严格模式
  6. Big Event in HDU[HDU1171]
  7. HTML5全球普及加速:有望终结iOS与安卓界限【转】
  8. Using zend-paginator in your Album Module
  9. django1.6之创建用户
  10. Boost.Build 简明教程
  11. 把 Eclipse 中的工程 Push 到 Github(适用 Windows 平台)
  12. 由MyEclipse内存不足谈谈JVM内存设置
  13. 提升Boolean和out相结合的用户体验
  14. swift-var/let定义变量和常量
  15. JNDI-j2ee
  16. oracle数据库一些用户管理语句
  17. 什么是MVC ?
  18. IBM SPSS 实习总结
  19. WinForm打包或部署
  20. [工作积累] UE4 并行渲染的同步 - Sync between FParallelCommandListSet &amp; FRHICommandListImmediate calls

热门文章

  1. 机器学习:集成学习:随机森林.GBDT
  2. 【博弈论】CF 1215D Ticket Game
  3. Privileged Permission开机授权时序图 SourceCode android-10.0.0_r36
  4. kinaba 安装踩坑: FATAL Error: [elasticsearch.url]: definition for this key is missing 转
  5. Spring Boot 整合多点套路,少走点弯路~
  6. 想买保时捷的运维李先生学Java性能之 JIT即时编译器
  7. 深入理解Java的抽象类和接口
  8. git学习(六) git reset操作
  9. MongoDB添加认证
  10. python坐标获取经纬度或经纬度获取坐标免费模块--geopy