KNN算法原理及应用

理解KNN 算法原理

KNN是监督学习分类算法,主要解决现实生活中分类问题。

根据目标的不同将监督学习任务分为了分类学习及回归预测问题。

监督学习任务的基本流程和架构:

(1)首先准备数据,可以是视频、音频、文本、图片等等

(2)抽取所需要的一些列特征,形成特征向量(Feature Vectors)。

(3)将这些特征向量连同标记一并送入机器学习算法中,训练出一个预测模型。

(4)然后,采用同样的特征提取方法作用于新数据,得到用于测试的特征向量。

(5)最后,使用预测模型对这些待测的特征向量进行预测并得到结果(Expected Model)。

KNN(K-Nearest Neihbor,KNN)K近邻是机器学习算法中理论最简单,最好理解的算法,是一个非常适合入门的算法,拥有如下特性:

  • 思想极度简单,应用数学知识少(近乎为零),对于很多不擅长数学的小伙伴十分友好

  • 虽然算法简单,但效果也不错

如果要了解一个人的经济水平,只需要知道他最好的5个朋友的经济能力, 对他的这五个人的经济水平求平均就是这个人的经济水平。这句话里面就包含着kNN的算法思想。 

如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

类别的判定

①投票决定,少数服从多数。取类别最多的为测试样本类别。

②加权投票法,依据计算得出距离的远近,对近邻的投票进行加权,距离越近则权重越大,设定权重为距离平方的倒数。

KNN 算法原理简单,不需要训练,属于监督学习算法,常用来解决分类问题

KNN原理:先确定K值, 再计算距离,最后挑选K个最近的邻居进行投票

 KNN的应用 

KNN即能做分类又能做回归, 还能用来做数据预处理的缺失值填充。由于KNN模型具有很好的解释性,对于每一个预测结果,我们可以很好的进行解释。文章推荐系统中, 对于一个用户A,我们可以把和A最相近的k个用户,浏览过的文章推送给A。

算法的思想:通过K个最近的已知分类的样本来判断未知样本的类别。

KNN三要素:

  • 距离度量
  • K值选择
  • 分类决策准则

 鸢尾花数据集

鸢尾花Iris Dataset数据集是机器学习领域经典数据集,鸢尾花数据集包含了150条鸢尾花信息,每50条取自三个鸢尾花中之一:Versicolour、Setosa和Virginica

from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifieriris = load_iris() #通过iris.data 获取数据集中的特征值  iris.target获取目标值
# 数据标准化
transformer = StandardScaler()
x_ = transformer.fit_transform(iris.data) # iris.data 数据的特征值#  模型训练
estimator = KNeighborsClassifier(n_neighbors=3) # n_neighbors 邻居的数量,也就是Knn中的K值
estimator.fit(x_, iris.target) # 调用fit方法 传入特征和目标进行模型训练
# 利用模型预测
result = estimator.predict(x_)
print(result)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 11 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 1 2 2 2 22 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 22 2]

sklearn中自带了几个学习数据集,都封装在sklearn.datasets 这个包中,加载数据后,通过data属性可以获取特征值,通过target属性可以获取目标值。

Demo数据集--kNN分类

1: 库函数导入

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets

2: 数据导入

iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target

3: 模型训练

k_list = [1, 3, 5, 8, 10, 15]
h = .02
# 创建不同颜色画布
cmap_light = ListedColormap(['orange', 'cyan', 'cornflowerblue'])
cmap_bold = ListedColormap(['darkorange', 'c', 'darkblue'])plt.figure(figsize=(15,14))
# 根据不同的k值进行可视化
for ind,k in enumerate(k_list):clf = KNeighborsClassifier(k)clf.fit(X, y)x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1xx, yy = np.meshgrid(np.arange(x_min, x_max, h),np.arange(y_min, y_max, h))Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])Z = Z.reshape(xx.shape)plt.subplot(321+ind)  plt.pcolormesh(xx, yy, Z, cmap=cmap_light)plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold,edgecolor='k', s=20)plt.xlim(xx.min(), xx.max())plt.ylim(yy.min(), yy.max())plt.title("3-Class classification (k = %i)"% k)plt.show()

当k=1的时候,在分界点位置的数据很容易受到局部的影响,图中蓝色的部分中还有部分绿色块,主要是数据太局部敏感。当k=15的时候,不同的数据基本根据颜色分开,当时进行预测的时候,会直接落到对应的区域。

数据集划分 

不能将所有数据集全部用于训练,为了能够评估模型的泛化能力,可以通过实验测试对学习器的泛化能力进行评估,进而做出选择。因此需要使用一个测试集来测试学习器对新样本的判别能力。

测试集要代表整个数据集、与训练集互斥、测试集与训练集建议比例: 2比8、3比7。

数据集划分的方法

1.将数据集划分成两个互斥的集合:训练集,测试集。

  • 训练集用于模型训练
  • 测试集用于模型验证

2.将数据集划分为训练集,验证集,测试集

  • 训练集用于模型训练
  • 验证集用于参数调整
  • 测试集用于模型验证

 1:将数据集 D 划分为两个互斥的集合,其中一个集合作为训练集 S,另一个作为测试集 T。

from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_irisdef te1():# 1. 加载数据集x, y = load_iris(return_X_y=True)print('原始类别比例:', Counter(y))x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)print('随机类别分割:', Counter(y_train), Counter(y_test))x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y)print('分层类别分割:', Counter(y_train), Counter(y_test))def te2():# 1. 加载数据集x, y = load_iris(return_X_y=True)print('原始类别比例:', Counter(y))print('*' * 40)# 2. 多次划分spliter = ShuffleSplit(n_splits=5, test_size=0.2, random_state=0)for train, test in spliter.split(x, y):print('随机多次分割:', Counter(y[test]))spliter = StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0)for train, test in spliter.split(x, y):print('分层多次分割:', Counter(y[test]))if __name__ == '__main__':te1()te2()# 随机类别分割: Counter({0: 43, 2: 40, 1: 37}) Counter({1: 13, 2: 10, 0: 7})
# 分层类别分割: Counter({1: 40, 2: 40, 0: 40}) Counter({2: 10, 1: 10, 0: 10})
随机多次分割: Counter({1: 13, 0: 11, 2: 6})
随机多次分割: Counter({1: 12, 2: 10, 0: 8})
随机多次分割: Counter({1: 11, 0: 10, 2: 9})
随机多次分割: Counter({2: 14, 1: 9, 0: 7})
随机多次分割: Counter({2: 13, 0: 12, 1: 5})分层多次分割: Counter({0: 10, 1: 10, 2: 10})
分层多次分割: Counter({2: 10, 0: 10, 1: 10})
分层多次分割: Counter({0: 10, 1: 10, 2: 10})
分层多次分割: Counter({1: 10, 2: 10, 0: 10})
分层多次分割: Counter({1: 10, 2: 10, 0: 10})

 K-Fold交叉验证,将数据随机且均匀地分成k分

 

  • 第一次使用标号为0-8的共9份数据来做训练,而使用标号为9的这一份数据来进行测试,得到一个准确率
  • 第二次使用标记为1-9的共9份数据进行训练,而使用标号为0的这份数据进行测试,得到第二个准确率
  • 共进行10次训练,最后模型的准确率为10次准确率的平均值,避免了数据划分而造成的评估不准确。
from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from collections import Counter
from sklearn.datasets import load_irisdef test():# 1. 加载数据集x, y = load_iris(return_X_y=True)print('原始类别比例:', Counter(y))print('*' * 30)# 2. 随机交叉验证spliter = KFold(n_splits=5, shuffle=True, random_state=0)for train, test in spliter.split(x, y):print('随机交叉验证:', Counter(y[test]))print('*' * 30)# 3. 分层交叉验证spliter = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)for train, test in spliter.split(x, y):print('分层交叉验证:', Counter(y[test]))test()

数据划分结果:

随机交叉验证: Counter({1: 13, 0: 11, 2: 6})
随机交叉验证: Counter({2: 15, 1: 10, 0: 5})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 14, 2: 10, 1: 6})
随机交叉验证: Counter({1: 11, 0: 10, 2: 9})
****************************************
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})
分层交叉验证: Counter({0: 10, 1: 10, 2: 10})

留一法:每次抽取一个样本做为测试集。

from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import LeavePOut
from sklearn.datasets import load_iris
from collections import Counterdef test01():# 1. 加载数据集x, y = load_iris(return_X_y=True)print('原始类别比例:', Counter(y))print('*' * 40)spliter = LeaveOneOut()for train, test in spliter.split(x, y):print('训练集:', len(train), '测试集:', len(test), test)test01()

分类算法的评估

  • 利用训练好的模型使用测试集的特征值进行预测

  • 将预测结果和测试集的目标值比较,计算预测正确的百分比

  • 百分比就是准确率, 准确率越高说明模型效果越好

确定合适的K值 

K值过小:容易受到异常点的影响

k值过大:受到样本均衡的问题,K一般取一个较小的数值。

使用 scikit-learn 提供的 GridSearchCV 工具, 配合交叉验证法可以搜索参数组合

x, y = load_iris(return_X_y=True)# 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y, random_state=0)estimator = KNeighborsClassifier()
grid = {'n_neighbors': [1, 3, 5]}
estimator = GridSearchCV(estimator, param_grid=grid, cv=5)
estimator.fit(x_train, y_train)

K近邻算法的优缺点:

  • 优点:简单,易于理解,容易实现
  • 缺点:算法复杂度高,结果对K取值敏感,容易受数据分布影响

knn算法中我们最需要关注两个问题:k值的选择和距离的计算。

距离/相似度的计算:

样本之间的距离的计算,我们一般使用对于一般使用Lp距离进行计算。当p=1时候,称为曼哈顿距离,当p=2时候,称为欧氏距离,当p=∞时候,称为极大距离。一般采用欧式距离较多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/412748.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聚类模型评估指标

聚类模型评估指标-轮廓系数 计算样本i到同簇其它样本到平均距离ai,ai越小,说明样本i越应该被聚类到该簇(将ai称为样本i到簇内不相似度);计算样本i到其它某簇Cj的所有样本的平均距离bij,称为样本i与簇Cj的…

分享用is_sorted()解决单调数列问题

题目名称 896. 单调数列 目录 题目名称 896. 单调数列 1.题目 2.题目分析 3.题目知识 3.1 is_sorted() 3.2.迭代器与反向迭代器 3.2.1理解迭代器 3.2.2正向迭代器 3.2.3反向迭代器 最后🍨 推荐阅读顺序: 1.题目->2.题目分析->3.题目知识点 1.题目 如…

使用docker部署RStudio容器并结合内网穿透实现公网访问

文章目录 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. 公网远程访问RStudio6. 固定RStudio公网地址 前言 RStudio Server 使你能够在 Linux 服务器上运行你所熟悉和喜爱的 RStudio IDE,并通过 Web 浏览器进行访问…

汽车用螺纹紧固件的拧紧力矩规范主要考虑哪些方面——SunTorque智能扭矩系统

在汽车制造过程中,螺纹紧固件是连接和固定各个零部件的重要元件。为了保证汽车的可靠性和安全性,对于螺纹紧固件的拧紧力矩有着严格的规定和规范。SunTorque智能扭矩系统和大家一起掌握这一重要知识点。 拧紧力矩是指将螺纹紧固件拧紧到预定位置所需的力…

【前沿技术杂谈:人工智能与种族主义 】谷歌在其视觉人工智能产生种族主义结果后道歉

【前沿技术杂谈:人工智能与种族主义 】谷歌在其视觉人工智能产生种族主义结果后道歉 背景调查现实世界的后果渐进式改变 一项自动标记图像的谷歌服务会根据给定图像的肤色产生截然不同的结果。该公司解决了这个问题,但问题可能更广泛。 为抗击新冠病毒&…

android 自定义八边形进度条

自定义八边形动画效果图如下 绘制步骤: 1.先绘制橙色底部八边形实心 2.黑色画笔绘制第二层,让最外层显示一条线条宽度即可 3.再用黄色画笔绘制黄色部分 4.使用渐变画笔根据当前进度绘制覆盖黄色部分 5.使用黑色画笔根据当前进度绘制刻度条 6.黑色画笔绘制…

Qt SDL2播放Wav音频

这里介绍两种方法来实现Qt播放Wav音频数据。 方法一&#xff1a;使用QAudioOutput pro文件中加入multimedia模块。 #include <QApplication> #include <QFile> #include <QAudioFormat> #include <QAudioOutput>int main(int argc, char *argv[]) {…

《如何制作类mnist的金融数据集》——1.数据集制作思路

1&#xff0e;数据集制作思路&#xff08;生成用于拟合金融趋势图像的分段线性函数&#xff09; 那么如何去制作这样的一个类minist的金融趋势曲线数据集呢&#xff1f; 还是如上图所示&#xff0c;为了使类别平均分布&#xff0c;因此可以选取三种“buy”的曲线、三种“sell”…

Spring+SpringMVC+Mybatis进行项目的整合

Spring SpringMVCM Mybatis 整合 一、 通过idea创建maven工程 二、 引入依赖项以及导入mybatis逆向工程的插件 将如下的文件替换所在工程的pom文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4…

LabVIEW图像识别检测机械零件故障

项目背景&#xff1a; 在工业生产中&#xff0c;零件尺寸的准确检测对保证产品质量至关重要。传统的人工测量方法不仅耗时费力&#xff0c;精度低&#xff0c;还容易导致零件的接触磨损。为了解决这些问题&#xff0c;开发了一套基于LabVIEW和机器视觉的机械零件检测系统。该系…

Kubernetes增加master节点

一. 新增节点 无论是node节点还是master节点&#xff0c;kubelet、kubeadm、kubectl、CRI需要部署好&#xff0c; ### 新增node, 重新生成token, 复制加入即可, 前提是需要装上面的 kubectl kubeadm kubelet containerd 等 kubeadm token create --print-join-command### 新增 …

5-微信小程序语法参考

1. 数据绑定 官网传送门 WXML 中的动态数据均来自对应 Page 的 data。 数据绑定使用 Mustache 语法&#xff08;双大括号&#xff09;将变量包起来 ts Page({data: {info: hello wechart!,msgList: [{ msg: hello }, { msg: wechart }]}, })WXML <view class"vie…