一 理论基础

  • \(k\)近邻法是一种基本地分类与回归算法,属于判别模型。没有学习策略,不具备显式学习过程。本文主要讨论分类问题。
  • 原理:给定一个训练数据集,对于新的输入实例,在训练数据集中找到与该实例最邻近的\(k\)个点,这\(k\)个点的多数属于某个类,就把输入实例归为这个类。
  • 三个基本要素:\(k\)值得选择,距离度量以及分类决策规则
    1.超参数k:选择较小的k值,对噪声比较敏感。意味着整体模型变得复杂,容易过拟合;选择较大的k值,较远的实例也会对预测起作用,使预测发生错误。意味着模型变得简单。
    2.距离度量:距离是空间两个实力点相似程度的反映。\(\mathbf{x}_i=(x_i^{(1)},x_i^{(2)},...,x_i^{(n)})^T,\mathbf{x}_j=(x_j^{(1)},x_j^{(2)},...,x_j^{(n)})^T\),距离定义如下:\[\mathit{L_p}=(\sum_{l=1}^{n}|x_i^{(l)}-x_j^{(l)}|^p)^{\frac{1}{p}}\]
     p=1时称为曼哈顿距离,p=2时称为欧氏距离。
    3.分类决策规则:一般采用多数表决。

二 代码实现

  • 编写的分类器实现功能:超参数k,超参数p,拟合训练集,对新的数据进行分类,对分类结果计算精度。感兴趣的还可以加入超参数距离的权重以及kd树,球树等实现方法。这里不再赘述。
  • KNN算法实现代码如下
class KNNClassify():def __init__(self,k=5, p=2):self.k = kself.p = pself._X_train = Noneself._y_train = Nonedef fit(self, X_train, y_train):self._X_train = X_trainself._y_train = y_trainreturn selfdef predict_y(self, X_test):m = self._X_train.shape[0]y_pre = []for intX in X_test:minus_mat = np.fabs(np.tile(intX, (m, 1)) - self._X_train)       # 将新的实例复制成m行1列,并进行相减sq_minus_mat = minus_mat ** self.psq_distance = sq_minus_mat.sum(axis=1)diff_sq_distance = sq_distance ** float(1/self.p)sorted_distance_index = diff_sq_distance.argsort()               # 记录距离最近的k个点的索引class_count = {}vola = []for i in range(self.k):vola = self._y_train[sorted_distance_index[i]]class_count[vola] = class_count.get(vola, 0) + 1             # 统计k个点中所属各个类别的实例数目sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)    # 返回列表,元素为元组。每个类别以及对应的实例数目y_pre.append((sorted_class_count[0][0]))return (np.array(y_pre))def score(self, X_test, y_test):j = 0for i in range(len(self.predict_y(X_test))):if self.predict_y(X_test)[i] == y_test[i]:j += 1return ('accuracy: {:.10%}'.format(j / len(y_test)))
  • 下面以鸢尾花数据集来评估编写的分类器效果
import numpy as np
import operatorfrom sklearn import datasets
from sklearn.model_selection import train_test_split
# 获取数据集,并进行8:2切分
iris = datasets.load_iris()
X = iris.data
y = iris.targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)# 定义分类器的实例,并进行拟合预测
f = KNNClassify()
f.fit(X_train, y_train)
y_pre = f.predict_y(X_test)
accuracy = f.score(X_test, y_test)
print(y_test)
print(y_pre)
print(accuracy)
  • 输出结果如下,可以看出分类效果还可以。
    [1 2 2 2 0 1 2 0 0 0 1 2 0 0 2 1 2 0 2 2 2 2 0 2 1 1 0 2 0 1]
    [1 2 2 2 0 1 2 0 0 0 1 2 0 0 2 1 1 0 2 2 2 2 0 2 1 1 0 2 0 1]
    accuracy: 96.6666666667%
  • 需要注意的是KNN由于与距离有关,如果某个特征数值相比其他特征较大大,会对距离产生很大的影响。例如具有实例x1=[1 3 1000 2],x2=[1.5 4 1100 2],计算距离时第三个特征差基本起到了主导作用,弱化了其他特征。为避免这种情况,应先对数据进行预理。
  • 预处理方法。关于标准化与归一化,不同的人有不同看法,这里以sklearn为准,标准化对象为特征,归一化对象为样本,当然两者实质都是对训练集数据的改变。可以参考[http://sklearn.apachecn.org/cn/0.19.0/modules/preprocessing.html#preprocessing-scaler]
    1.标准化(对特征),也称去均值和方差按比例缩放。数据集的标准化对scikit-learn中实现的大多数机器学习算法来说是常见的要求 。(对象为特征,依赖于训练集中所有样本)

    • 如果个别特征或多或少看起来不是很像标准正态分布(具有零均值和单位方差),那么它们的表现力可能会较差。在实际情况中,我们经常忽略特征的分布形状,直接减去均值来对某个特征进行中心化,再通过除以非常量特征(non-constant features)的标准差进行缩放。
      \[x=\frac{x-\bar{x}}{\sigma }\]
    • 将特征缩放到给定的区间,通常为[0,1]。或者也可以将每个特征的最大值转换至单位大小,它通过除以每个特征的最大值将训练数据特征缩放至 [-1, 1] 范围内,这就意味着训练数据应该是已经零中心化或者是稀疏数据。两者分别使用MinMaxScaler和MaxAbsScaler实
      现。对于两者计算公式分别为\[x=\frac{x-min(x)}{max(x)-min(x)},x=\frac{x}{max(x)}\]

    2.归一化(对样本)。归一化 是缩放单个样本以具有单位范数的过程。注意对象为样本而非某个特征!!通常使用 L1 或 L2 范数。例如实例\(\mathbf{x}_1=(1,2,2)^T\),归一化后\(\mathbf{x}_1= (0.33,0.66,0.66)^T\)。不依赖于其他样本特征数值。
    3.二值化。
    4.非线性变换
    5.特征编码L
    6.缺失值插补

  • 由此可以看出,对于kNN而言,当某个特征的差值相比其他特征较大时,可以采用标准化,以避免某个特征对距离影响。如果进行归一化,虽然也是改变了特征取值区间,但是特征间量级关系依然会相差很大。
  • 当我们得出一个算法模型后,如何评判模型的好坏呢?包括许多性能度量方法,例如精度与错误率、查准率查全率与F1、ROC与AUC等等。假如我们选择精度作为衡量指标,我们采用多次留出法或者p次k折交叉验证,然后将各个精度取均值作为此模型的评估指标。
    1.留出法。将数据集分成互斥的训练集与测试集,可以得出一个精度。因为划分方式存在多种方式,因此使用留出法时,采用若干次随机划分,重复进行实验取平均值作为留出法评估结果。
    2.交叉验证。将数据划分成k个互斥大小相似的集合,每次采用k-1个作为训练集,剩下一个作为测试集,总共可进行k次,最终返回k次结果的均值。同样由于划分方式不同,可进行p次划分,每次都进行k折交叉验证,取最后均值作为评估结果,称为p次k折交叉验证。

转载于:https://www.cnblogs.com/lyxML/p/9509059.html

机器学习:kNN算法(一)—— 原理与代码实现(不调用库)相关推荐

  1. 机器学习 —— KNN算法简单入门

    机器学习 -- KNN算法简单入门 第1关:手动实现简单kNN算法 1 KNN算法简介 1.1 kNN 算法的算法流程 1.2 kNN 算法的优缺点 1.3 编程要求+参数解释 2. 代码实现 3. ...

  2. 机器学习——KNN算法

    机器学习--KNN算法 文章目录 机器学习--KNN算法 前言 一.KNN原理基础 二.sklearn的基本建模流程 三.KNN算法调优:选取最优的K值 四.KNN中距离的相关讨论 1. KNN使用的 ...

  3. 机器学习knn算法学习笔记使用sklearn库 ,莺尾花实例

    ** 机器学习knn算法学习笔记使用sklearn库 ,莺尾花实例. 具体knn算法是怎样的我这里就不再详细论述.在这里我注意总结我使用knn算法进行一个分类的分析 ** 分析过程 1.前期准备 引入 ...

  4. 课程设计(毕业设计)—基于机器学习KNN算法手写数字识别系统—计算机专业课程设计(毕业设计)

    机器学习KNN算法手写数字识别系统 下载本文手写数字识别系统完整的代码和课设报告的链接(或者可以联系博主koukou(壹壹23七2五六98),获取源码和报告):https://download.csd ...

  5. 机器学习KNN算法实践:预测城市空气质量

    出品:Python数据之道 作者:叶庭云 整理:Lemon 机器学习KNN算法实践 预测城市空气质量 「Python数据之道」导读: 之前在公众号上分享过 "图解KNN算法" 的内 ...

  6. 岭回归算法的原理和代码实战

    岭回归算法的原理和代码实战 前言 学过吴恩达老师的机器学习入门课程都应该知道,在逻辑回归那一讲,吴老师提到了使用正则化来防止逻辑回归模型过拟合.而岭回归在这里的作用是一样的,同样也是防止模型过拟合.这 ...

  7. 视觉SLAM开源算法ORB-SLAM3 原理与代码解析

    来源:深蓝学院,文稿整理者:何常鑫,审核&修改:刘国庆 本文总结于上交感知与导航研究所科研助理--刘国庆关于[视觉SLAM开源算法ORB-SLAM3 原理与代码解析]的公开课. ORB-SLA ...

  8. 【编程实践】Raft 算法的原理 go代码实例

    文章目录 Raft 算法的原理 & go代码实例 Raft 算法的原理 使用 Go 语言实现的简单 Raft 算法示例 Raft 算法的原理 & go代码实例 Raft 算法的原理 R ...

  9. ICCV2017跟踪算法BACF原理及代码解析

    文章和代码下载地址: Galoogahi H K, Fagg A, Lucey S. Learning Background-Aware Correlation Filters for Visual ...

  10. TPAMI2015跟踪算法KCF原理及代码解析

    文章和代码下载地址: http://www.robots.ox.ac.uk/~joao/circulant/ 一.基础公式的由来 相关滤波跟踪器可以表示为最小化的岭回归问题: 表示期望相应,表示正则系 ...

最新文章

  1. HTML5 Geolocation
  2. 干货|六维力和力矩传感器的技术与应用
  3. laravel authorize(授权)
  4. 如果用编程语言参加战争,哪门语言才是程序员的最强武器?
  5. 机器学习(二)Logistic回归(Logistic regression)算法
  6. 基础IO(文件接口、安装内核源码超详细步骤图解、静态库与动态库)
  7. [OpenJudge 3066]随机序列
  8. python基础整数和浮点数(一)
  9. 马化腾、李彦宏、雷军,程序员国服三强谁的编程能力最牛?
  10. Java Spring-事务管理
  11. oracle to date mysql_mysql中怎么实现oracle中的to_char和to_date
  12. Android调试wifi使用wpa_supplicant和wpa_cli总结
  13. 分类算法学习(四)——决策树算法的原理及简单实现
  14. OpenStack创业“五虎将”分化
  15. 好程序员分享html图片绝对路径改相对路径
  16. Java 垃圾回收机制(GC)简述
  17. Unity的超大开放世界解决方案
  18. “四大神兽”拆机指北
  19. 如何利用领英快速开发客户?
  20. 双击打开Excel2016文件后无法直接显示文件内容的解决办法

热门文章

  1. 安卓模拟器的使用--皇室战争免费快速成长之路
  2. django线上环境配置
  3. 邂逅APP + 网站平台的产品设想
  4. gradle尚硅谷笔记
  5. 分析与思考 黄奇帆的复旦经济课 读书笔记
  6. 盘点谷歌浏览器中的一些神级插件
  7. C++ 编程练习——猴子吃桃问题
  8. RISC-V MCU应用教程之PWR睡眠模式
  9. 滴滴在HBase性能与可用性上的探索与实践
  10. 微信这个设置你们关闭了吗?