[机器学习]--KNN算法(K邻近算法)

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

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

KNN算法原理

上图是每一个点都是一个肿瘤病例

  • 横轴表示肿瘤的大小, 纵轴表示肿瘤发现的时间
  • 红色表示肿瘤是良性, 蓝色表示肿瘤是恶性

现在新来了一个病人, 用绿色表示, 那么如何判断他是良性还是恶性

 简单来说, K邻近算法就是通过K个最佳的样本来判断未知样本的类别

从上面的例子可以总结出K邻近算法的原理:

  1. 保存所有已知算法的样本点
  2. 输入未知样本点
  3. 选择参数K
  4. 计算未知样本与所有已知样本的距离
  5. 选择最近的K个样本进行投票, 未知样本归于票数最多的类别

影响KNN算法的三要素:

  1. K值的选择
  2. 距离的度量方法
  3. 分类决策准则

距离度量的方法

1. 欧式距离

欧式距离

这是最常见的距离计算方法, 在中学的数学中就已经使用这种方法来计算, 不过多赘述

2.曼哈顿距离

                                                 $L = |x_2 - x_1| + |y_2-y_1|$

样本中有多个特征,每一个特征都有自己的定义域和取值范围,他们对距离计算也是不同的,如取
值较大的影响力会盖过取值较小的参数。因此,为了公平,样本参数必须做一些归一化处理,将不
同的特征都缩放到相同的区间或者分布内。

        归一化:

将一列数据变化到某个固定区间(范围)中,通常,这个区间是[0, 1],广义的讲,可以是各种区间,比如映射到[0,1]一样可以继续映射到其他范围,图像中可能会映射到[0,255],其他情况可能映射到[-1,1]

在sklearn中已经有了归一化的API

from sklearn.preprocessing import MinMaxScalerdef test01():data = [[20,30,90],[80,60,10],[50,45,40]]print(data)tranformer = MinMaxScaler()data = tranformer.fit_transform(data)print(data)if __name__ == '__main__':test01()

        标准化

将数据变换为均值为0,标准差为1的分布切记,并非一定是正态的

from sklearn.preprocessing import StandardScalerdef test01():data = [[20,30,90],[80,60,10],[50,45,40]]print(data)tranformer = StandardScaler()data = tranformer.fit_transform(data)print(data)if __name__ == '__main__':test01()

KNN算法api

        数据集的划分

1.留出法

将数据集划分为训练集和测试集, 比例一般为:0.8:0.2

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from collections import Counter
# 导入鸢尾花数据集
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,random_state=42,stratify=y)
print(Counter(y_train),Counter(y_test))

 sklearn库提供相关的api, 可以直接使用train_test_split()来划分

参数:

数据的特征X

数据的标签y

test_size: 测试集的比例

random_state: 随机数种子, 设置随机数种子可以确保每次运行划分相同, 结论可以复现

stratify: 若设置stratify=y, 确保训练集和测试集在目标变量(标签)上的分布相同

shuffle:参数控制数据在分割之前是否需要打乱顺序。默认值是 True,这意味着在将数据划分为训练集和测试集之前,会先随机打乱数据。这可以防止由于数据的原始顺序(例如,如果数据是按照某种规则排列的)导致的偏差

返回结果:四个数据集, X_train, X_test, y_train, y_test

没设置stratify
设置stratify=y

 2.交叉验证法

 

spliter = StratifiedShuffleSplit(n_splits=5,test_size=0.2,random_state=42)
for train,test in spliter.split(X,y):print(Counter(y[test]))

 

模型的评估

        评估指标

sklearn库提供了许多相关的评估指标, 在这里介绍accuracy_score准确度, 传入预测y_test, y_pred即可获得准确率

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from collections import Counter
from sklearn.metrics import accuracy_score
# 导入鸢尾花数据集
X,y = load_iris(return_X_y=True)# 数据标准化
Scaler = StandardScaler()
X = Scaler.fit_transform(X)# 划分数据集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42,stratify=y)# 训练模型
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(X_train,y_train)y_pred = estimator.predict(X_test)
print(accuracy_score(y_test,y_pred))

 

        网格搜索最佳参数

了解KNN算法的原理后, 我们知道K值对模型训练的影响非常大, 应该如何选择K值, 才能让我们的准确率更高?

sklearn提供了网格搜索工具GridSearchCV, 可以帮助我们找到最佳参数, 

param_grid 为一个字典, 包括你要搜索的参数的不同值

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
# 导入鸢尾花数据集
X,y = load_iris(return_X_y=True)# 数据标准化
Scaler = StandardScaler()
X = Scaler.fit_transform(X)# 划分数据集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42,stratify=y)# 训练模型
estimator = KNeighborsClassifier(n_neighbors=3)
param_grid = {'n_neighbors':[1,3,5,7,9]
}
estimator = GridSearchCV(estimator, param_grid=param_grid,cv=5)
estimator.fit(X_train,y_train)
print('最佳参数:',estimator.best_estimator_, '最佳得分',estimator.best_score_)

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

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

相关文章

Sakana.ai 迈向完全自动化的开放式科学发现

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

从零开始搭建k8s集群详细步骤

声明:本文仅作为个人记录学习k8s过程的笔记。 节点规划: 两台节点为阿里云ECS云服务器,操作系统为centos7.9,master为2v4GB,node为2v2GB,硬盘空间均为40GB。(节点基础配置不低于2V2GB) 主机名节点ip角色部…

Docker最佳实践进阶(一):Dockerfile介绍使用

大家好,上一个系列我们使用docker安装了一系列的基础服务,但在实际开发过程中这样一个个的安装以及繁杂命令不仅仅浪费时间,更是容易遗忘,下面我们进行Docker的进阶教程,帮助我们更快速的部署和演示项目。 一、什么是…

力扣面试经典算法150题:找出字符串中第一个匹配项的下标

找出字符串中第一个匹配项的下标 今天的题目是力扣面试经典150题中的数组的简单题: 找出字符串中第一个匹配项的下标 题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/?envTypestudy-plan-v2&envIdto…

docker compose部署rabbitmq集群,并使用haproxy负载均衡

一、创建rabbitmq的data目录 mkdir data mkdir data/rabbit1 mkdir data/rabbit2 mkdir data/rabbit3 二、创建.erlang.cookie文件(集群cookie用) echo "secretcookie" > .erlang.cookie 三、创建haproxy.cfg配置文件 global log stdout fo…

深度学习基础—正则化

正则化:解决模型过拟合的手段,本质就是减小模型参数取值,从而使模型更简单。常用范数如下: 使用最多的是L2范数正则项,因此加入正则项的损失函数变为: 使用梯度下降法的权重调整公式: 推导后得到…

项目实战:Qt+Opencv相机标定工具v1.3.0(支持打开摄像头、视频文件和网络地址,支持标定过程查看、删除和动态评价误差率,支持追加标定等等)

若该文为原创文章,转载请注明出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/141334834 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、Op…

二十二、状态模式

文章目录 1 基本介绍2 案例2.1 Season 接口2.2 Spring 类2.3 Summer 类2.4 Autumn 类2.5 Winter 类2.6 Person 类2.7 Client 类2.8 Client 类的运行结果2.9 总结 3 各角色之间的关系3.1 角色3.1.1 State ( 状态 )3.1.2 ConcreteState ( 具体的状态 )3.1.3 Context ( 上下文 )3.…

Airtest 的使用

Airtest 介绍 Airtest Project 是网易游戏推出的一款自动化测试框架,其项目由以下几个部分构成 Airtest : 一个跨平台的,基于图像识别的 UI 自动化测试框架,适用于游戏和 App , 支持 Windows, Android 和 iOS 平台&#xff0c…

解决银河麒麟V10登录循环的方法

解决银河麒麟V10登录循环的方法 一:进入命令行二:删除.Xauthority文件三:重启系统 💖The Begin💖点点关注,收藏不迷路💖 在使用银河麒麟桌面操作系统V10时,有时可能会遇到一个令人头…

【题解】—— LeetCode一周小结32

🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 【题解】—— 每日一道题目栏 上接:【题解】—— LeetCode一周小结31 5.不含连续1的非负整数 题目链接:600. 不含连续…

redis列表若干记录

2、列表 ziplist ziplist参数 entry结构 entry-data:节点存储的元素prelen:记录前驱节点长度encoding:当前节点编码格式encoding encoding属性 使用多个子节点存储节点元素长度,这种多字节数据存储在计算机内存中或者进行网络传输的时的字节…

小型超声波清洗机哪个品牌好用?小型超声波清洗机排名前四

第一次见识到超声波清洗机的神奇是在几年前,当时我去眼镜店配眼镜。等待的过程中,店员把旧的眼镜拿去清洁了,30秒,我就看到了到小污渍和油污被震出来了,感觉特别神奇。几分钟后,清洁完毕,擦干镜…

3个常用zip压缩包文件打来密码删除方法

ZIP压缩包作为一种广泛使用的文件压缩格式,常常用于节省存储空间或便于文件传输。一般情况下为保护文件数据的安全我们会给zip压缩文件设置密码安全保护,但如果后续不需要密码保护了,如何删除密码呢?下面小编给大家介绍三种常用的…

java 函数接口Consumer简介与示例【函数式编程】【Stream】

Java 8 中的 消费者接口Consumer 是一个函数接口,它可以接受一个泛型 类型参数,它属于java.util.function包。 accept(T) 方法:是 Consumer 函数式接口的方法,传入单个输入参数,无返回值,可以用于 Lambda 表…

电脑监控软件有哪些,哪款更好用?一网打尽!电脑监控软件大搜罗,总有一款适合你!

甲:哎,您听说了吗?这年头,电脑监控软件那是五花八门,跟变戏法似的! 乙:哦?怎么个五花八门法? 甲:嘿,您还别说,从实时监控到网络追踪…

最佳实践:敏捷需求管理——如何写好用户故事丨IDCF

丁仿,圣略咨询首席敏捷教练,研发效能(DevOps)工程师(中级)课程学员 在敏捷项目管理中,用户故事(User Stories)是需求管理的核心工具。本篇文章将从用户故事的基本概念、编…

复习之 java 锁

裁员在家,没有面试机会,整理整理面试知识点吧! 不得不知道的java 锁 Java 中,提供了两种方式来实现同步互斥访问(也就是锁):synchronized 和 Lock 多线程编程中,有可能会出现多个线…

期权中非常重要的行权!不懂行权先别交易!

今天带你了解期权中非常重要的行权!不懂行权先别交易!期权是金融市场中一种常见的衍生品工具,它给予持有者在特定时间内以特定价格购买或出售某个资产的权利。而“行权”是指期权持有者行使期权权利的行为。 期权行权是指期权持有者选择执行…

超网和无类间路由是什么?

​一、超网概述 超网是将多个连续的网络地址组合成一个增加的网络地址的技术。常用于减少路由器的路由表大小,网络的可扩展性。通过合并连续的子网,超网可以减少路由入侵的数量,从而提高网络的效率。 超网的实现基于合并多个具有连续IP地址…