分类算法KNN的python实现

news2024/11/18 5:32:58

作者:刘凡

KNN算法介绍

KNN算法是有监督学习中的分类算法,它是一种非参的,惰性的算法模型。非参的意思并不是说这个算法不需要参数,而是意味着这个模型不会对数据做出任何的假设,与之相对的是线性回归(我们总会假设线性回归是一条直线)。也就是说KNN建立的模型结构是根据数据来决定的,这也比较符合现实的情况,毕竟在现实中的情况往往与理论上的假设是不相符的。惰性的意思是指模型在使用前不会被训练,只有当使用的时候才会被训练。

KNN算法优点: 简单易用,相比其他算法,KNN算是比较简洁明了的算法。即使没有很高的数学基础也能搞清楚它的原理。可以处理多分类问题;还可以处理回归问题。

KNN算法缺点: 对内存要求较高,因为该算法存储了所有训练数据,预测阶段可能很慢;对训练数据依赖度特别大,虽然所有机器学习的算法对数据的依赖度很高,但是KNN尤其严重,因为如果我们的训练数据集中,有一两个数据是错误的,刚刚好又在我们需要分类的数值的旁边,这样就会直接导致预测的数据的不准确,对训练数据的容错性太差;维数灾难。

自编函数实现

#欧氏距离
def distance(a,b):
    return np.sqrt(np.sum((a-b)**2,axis=1))
# 分类器实现
class kNN(object):
    # 定义初始化方法,初始化kNN需要的参数
    def __init__(self,n_neighbors = 1,dist_func = distance):
        self.n_neighbors = n_neighbors
        self.dist_func = dist_func

    # 训练模型方法
    def fit(self,x,y):
        # 将x,y传进来即可
        self.x = x
        self.y = y
    
    # 模型预测方法
    def predict(self,x):
        # 初始化预测分类数组
        y_pred = np.zeros((x.shape[0],1),dtype = self.y.dtype)
        
        # 遍历输入的x数据点,取出每一个数据点的i和数据x_test
        for i,x_test in enumerate(x):
            # x_test跟所有的训练数据计算距离
            distances = self.dist_func(self.x,x_test)
            
            # 得到的距离按照由近到远排序
            nn_index = np.argsort(distances)
            
            # 选取最近的k个点,保存其类别
            nn_y = self.y[nn_index[:self.n_neighbors]].ravel()
            
            # 统计类别中频率最高的那个,赋给y_pred[i]
            y_pred[i] = np.argmax(np.bincount(nn_y))
        return y_pred   

测试

import numpy as np 
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

iris = load_iris()
# 划分训练集和测试集
x = iris.data
y = iris.target.reshape(-1,1)#将iris.target 行向量,转换成列
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3)

knn = kNN(n_neighbors = 3)
knn.fit(x_train,y_train)
# 传入测试数据,做预测
y_pred = knn.predict(x_test)

# 求准确率
accuracy = accuracy_score(y_test,y_pred)
print('预测准确率:',accuracy)
'''预测准确率: 0.9777777777777777'''

调参

knn = kNN()
# 训练模型
knn.fit(x_train,y_train)

# 创建一个列表保存不同的准确率
result_list = []
knn.dist_func = distance
   # 考虑不同的k值
for k in range(1,10,1):
    knn.n_neighbors = k
    # 传入测试数据,做预测
    y_pred = knn.predict(x_test)
    # 求出预测准确率
    accuracy = accuracy_score(y_test,y_pred)
    result_list.append([k,accuracy])

df  = pd.DataFrame(result_list,columns = ['k','预测准确率'])
df 

在这里插入图片描述

sklearn模块的实现

参数介绍

sklearn.neighbors 模块中的KNeighborsClassifier类可以实现KNN算法。

KNeighborsClassifier(n_neighbors=5, *, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None)
  • n_neighbors: int, 可选参数(默认为 5)用于kneighbors查询的默认邻居的数量

  • weights(权重): str or callable(自定义类型), 可选参数(默认为 ‘uniform’)用于预测的权重函数。可选参数如下:

    • ‘uniform’ : 统一的权重. 在每一个邻居区域里的点的权重都是一样的。
    • ‘distance’ : 权重点等于他们距离的倒数。使用此函数,更近的邻居对于所预测的点的影响更大。
    • ‘callable’ : 一个用户自定义的方法,此方法接收一个距离的数组,然后返回一个相同形状并且包含权重的数组。
  • algorithm(算法): {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, 可选参数(默认为 ‘auto’)
    计算最近邻居用的算法:

    • ‘ball_tree’是为了克服kd树高纬失效而发明的,其构造过程是以质心C和半径r分割样本空间,每个节点是一个超球体。 ball-tree按超球面进行划分。球树:找到一个中心点,使所有样本点到这个中心点的距离最短。对于每一个节点的子节点的选择,方式如下:选择当前超球体区域离中心最远的点作为左子节点选择距离左子节点距离最远的点作为右子节点对于其他的样本点,计算到左子节点和右子节点对应样本点的欧式距离,并分配到距离较近的那一个对所有子节点做相同的操作
    • ‘kd_tree’ 构造kd树存储数据以便对其进行快速检索的树形数据结构,kd树也就是数据结构中的二叉树。以中值切分构造的树,每个结点是一个超矩形,在维数小于20时效率高。
    • Kd-tree按维度逐次划分kd 树是一个二叉树,每一个内部的节点都代表了一个超矩形空间,并且它的子树包含在这个超矩形空间内部的所有样本点。但是 kd 树对于一些样本分布情况而言效率并不高,比如当大量样本落在一个超矩形的角落的情况,此时使用球树的效率会更高
    • ‘brute’ 使用暴力搜索.也就是线性扫描,当训练集很大时,计算非常耗时
    • ‘auto’ 会基于传入fit方法的内容,选择最合适的算法。
  • leaf_size(叶子数量): int, 可选参数(默认为 30)。传入BallTree或者KDTree算法的叶子数量。此参数会影响构建、查询BallTree或者KDTree的速度,以及存储BallTree或者KDTree所需要的内存大小。 此可选参数根据是否是问题所需选择性使用

  • p: integer, 可选参数(默认为 2)。 用于Minkowski metric(闵可夫斯基空间)的超参数。p = 1, 相当于使用曼哈顿距离 (l1),p = 2, 相当于使用欧几里得距离(l2) 对于任何 p ,使用的是闵可夫斯基空间(l_p)

  • metric(矩阵): string or callable, 默认为 ‘minkowski’用于树的距离矩阵。默认为闵可夫斯基空间,如果和p=2一块使用相当于使用标准欧几里得矩阵. 所有可用的矩阵列表请查询 DistanceMetric 的文档。

  • metric_params(矩阵参数): dict, 可选参数(默认为 None)给矩阵方法使用的其他的关键词参数。

  • n_jobs: int, 可选参数(默认为 1), 用于搜索邻居的,可并行运行的任务数量。设定工作的core数量,如果为-1, 任务数量设置为CPU核的数量。不会影响fit方法。

测试

#测试
import numpy as np 
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
# 划分训练集和测试集
x = iris.data
y = iris.target.reshape(-1,1)#将iris.target 行向量,转换成列
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3)


knn = KNeighborsClassifier(n_neighbors=3,weights='uniform',algorithm='auto')

knn.fit(x_train,y_train)
# 传入测试数据,做预测
y_pred = knn.predict(x_test)

# 求准确率
accuracy = accuracy_score(y_test,y_pred)
print('预测准确率:',accuracy)
'''预测准确率: 0.9555555555555556'''

计算混淆矩阵

sklearn.metrics模块中的confusion_matrix和classification_report 函数可以计算出混淆矩阵和预测正确率等指标。

from sklearn.metrics import confusion_matrix,classification_report 
print(confusion_matrix(y_test, y_pre))
print(classification_report(y_test, y_pre))

在这里插入图片描述

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

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

相关文章

隐语任务调度

隐语目前暂定支持的设备列表: 一 PYU 数据所有者是SecretFlow中的PYU设备,明文并成为PYU Objects一个PYU object(明文)可以被转化为秘密分享,被叫做SPU Object。Python函数可以被发送至SPU设备执行,背后是…

人工智能:图像数字化相关的知识介绍

❤️作者主页:IT技术分享社区 ❤️作者简介:大家好,我是IT技术分享社区的博主,从事C#、Java开发九年,对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉: 数据库领域优质创作者🏆&#x…

只从 2022 年算起,谷歌就向社会输送了至少 26 位高端 AI 人才。

2022 年,人工智能在 AIGC、AI for science 等领域持续发展,一些工作也在知识型模型方面做出了探索。除了这些研究成果,我们还会发现这一年人工智能从业者的工作情况也有比较大的变化。 例如,Meta 等大型科技公司进行了大规模的裁…

【 shell 编程 】第1篇 变量

变量 文章目录变量一、前言二、变量1.变量的类型2.变量的运算一、前言 1.什么是 shell 简介: SHELL是UNIX系统的用户与操作系统之间的一种接口。它既是UNIX系统的命令解释程序,又是一种高级的命令程序设计语言。 作为命令解释程序,SHELL接收…

Windows/Mac/Ubuntu环境下安装Dokcer

前提概要: 注意:安装虚拟环境的步骤我放到另外一个文章里面啦,有需要的可以看看哦 Docker介绍:1、Docker 并⾮是⼀个通⽤的容器⼯具,它依赖于已存在并运⾏的 Linux 内核环境。2、Docker 实质上是在已经运⾏的 Linux 下…

智慧养老系统(社区+居家+机构养老)

智慧养老是一个新的养老模式,信息化医疗服务,不仅能够提高养老产业的质量,提高养老成本降低,而且能够提高老人的身体健康,提高养老人的老年生活质量。 智慧养老系统解决方案提供完整的机构养老系统、社区养老系统&…

在项目中使用——newFixedThreadPool线程池

newFixedThreadPool线程池前言newFixedThreadPool的介绍使用newFixedThreadPool的步骤实例化一个固定线程大小线程池创建一个用于启动新线程的类使用submit提交线程最后关闭关闭线程池CountDownLatch配合线程池使用构造CountDownLatch计数器减一使调用该方法的线程处于等待状态…

推荐 12 月 yyds 的开源项目

本期推荐开源项目目录:1. 面向 API 的低代码平台2. 京东抢购自动下单助手3. 开发人员使用的低代码平台4. 好用又强大的开源建站工具5. OCR 图片转文字识别软件6. 互联网仍有记忆01面向 API 的低代码平台APITable 一个面向 API 的低代码平台,用于构建协作…

推荐系统从入门到入门(2)——简单推荐系统构建(无框架、Tensorflow)

本系列博客总结了不同框架、不同算法、不同界面的推荐系统,完整阅读需要大量时间(又臭又长),建议根据目录选择需要的内容查看,欢迎讨论与指出问题。 系列文章梗概 本次大作业主要是以电影推荐系统为例,介绍…

GIC V3 V4 逻辑组件

GIC V3 & V4 逻辑组件1 GIC V3逻辑组件2 GIC 各组件的介绍2.1 Distributor2.2 Interrupt translation service, ITS2.3 Redistributor2.4 CPU interface1 GIC V3逻辑组件 The GICv3 architecture consists of a set of logical components: • A Distributor.• A Redist…

C++ 实现Manacher算法

前言 Manacher算法是一种回文串查找算法,专门用于处理查找字符串中的回文子串操作。虽然这个算法本身只是用于查找回文子串,但是它的查找思想还是非常值得学习的。由于Manacher算法是基于暴力解法优化而来的,所以在阅读正式的算法之前&#…

arthes—线上debug好帮手

arthes简介 以下是arthes官网原文: 通常,本地开发环境无法访问生产环境。如果在生产环境中遇到问题,则无法使用 IDE 远程调试。更糟糕的是,在生产环境中调试是不可接受的,因为它会暂停所有线程,导致服务暂…

粒子滤波原理和MATLAB代码实现

理论基础1: (a) Prediction Use the transition equation to propagate the particles: (b) Update Use the measurement equation to obtain measurements of the propagated particles and their standard deviations: (in the case of our program, ym is obt…

如何在 Manjaro Linux 上安装 ONLYOFFICE 桌面编辑器

ONLYOFFICE 桌面编辑器是一款免费开源办公套件,其中包括适用于文本文档、电子表格与演示文稿的离线编辑器。同时,您还可将应用程序连接至云端(ONLYOFFICE、Nextcloud 等)以便在线开展文档协作。该应用的源代码已根据 AGPL v.3.0 许…

业务中台10讲2.0合辑(推荐收藏)

目录V3.0迭代内容: 增加最近更新的中台系列文章至本目录;根据最新热点修订并调整部分未更新内容方向;为各文章标注《中台产品经理宝典》书中原文出处;本目录使用方法: 本目录推文为中台内容系列中的业务中台子类新原…

华润微功放CS3850EO,2×40W D 类音频功率放大电路,替换:智浦芯CS8673,TI的TAS5780、TAS5754,国产功放

1、概述 CS3850EO 是一款典型输出功率为 40W 立体声的 D 类音频功率放大电路,适用于拉杆音箱、高级桌面音响等场合。 特点 ● 工作电压范围:8V~26V ● 典型输出功率:30W2 20V、8Ω、THD10% 40W2 18V、4Ω、THD10% 50W2 26.5V、8Ω、…

你以为Shell只是命令行?读懂这篇文,给你的工作赋能

可以使用adb tcpip 端口在Android设备上启动一个指定的端口,然后使用adb connect Android设备ip:端口远程连接Android设备。 uiautomator 是一个 java 库,包含用于创建自定义功能UI测试的API,以及用于自动执行和运行测试的执行引擎。使用uiau…

Transformer与看图说话

🏅🏅🏅🏅🏅🏅🏅🏅🏅🏅🏅🏅🏅🏅🏅🏅 一年一度的【博客之星】评选活动已开始啦 作为第一…

Redis的持久化技术

1. 前言 今天呢,我们来了解下Redis的持久化技术。都知道Redis是内存型key-value型数据库。其实叫缓存中间件更合适。既然是内存性数据库就知道存入磁盘的必要性了。所以就需要持久化技术来支持了 2. 合适人群 对Redis 持久化技术不了解的人 3. RDB RDB 其实就是Re…

推荐三款 Mac 上的理财神器 iCompta、Rublik、UctoX

推荐三款 Mac 上的理财神器 iCompta、Rublik、UctoX 今天推荐三款理财神器,像个人的话可以使用 iCompta(个人财务管理)一款软件就好了,但有些朋友可能有关注汇率的需求,可以使用 Rublik(汇率动态&#xff…