K近邻算法(手写代码+图像识别实践)

news2024/10/6 1:47:08

        k近邻算法作为一个分类算法,他通过计算不同特征值之间的距离来进行分类,它的工作原理是存在一个样本集合作为训练样本集,且每个样本都存在一个标签,此时,输入一个新的样本不存在标签,我们通过计算这个新样本到这些训练样本集的距离,找出k个最靠近的样本,再对这些样本的标签进行统计,数量最多的则为新样本的标签。

        这里的距离可以有很多,曼哈顿距离,欧式距离等等,后面的代码都使用欧氏距离,K-NN的伪代码如下:

(1)计算所有已知类别的数据集中的点到新的点的距离。

(2)按照距离进行排序。

(3)选取k个与新的点距离最小的k个点。

(4)计算k个点所在类别的频率。

(5)返回k个点出现频率最高的类别作为当前点的预测分类

下面进行实现:

def distance(target,dataset):
    length =dataset.shape[0]
    distances=[]
    for i in range(length):
        diff=0
        for j in range(dataset[i].shape[0]):
            diff += (dataset[i][j]-target[j])**2
            distance =diff**0.5
        distances.append(distance)
    return distances
            

        这里是计算了目标点target到数据集内所有点的距离,并保存在distances的列表中。

def sort_choose_k(distance,labels,k):
    index =distance.argsort()##选取从小到大排序的索引值
    class_count={}
    for i in range(k):
        vote =labels[index[i]]
        class_count[vote] =class_count.get(vote,0)+1##这里使用了get方法,利用键来获取值,然后get()方法两个参数,第一个为键,第二个为初值
    sorted_class_count = sorted(class_count.items(),key=operator.itemgetter(1),reverse=True)
    return sorted_class_count[0][0]
        

        这里是对距离集进行排序,并选择出前k个。这里得argsort()函数作用于array类型,效果是将数组类型的数据进行升序排序后的索引值进行返回。这里的get()函数适用于dict类型,其中第一个参数为输入的键,后面那个参数为给键的初值。这里的itemgetter()方法是operator运算符模块自带的方法,这里是按照第二个元素的次序对元祖进行排序。

        这样子就完成了K-NN算法建立,下面看一下例子。

        这里例子是通过k临近算法来改进约会网站的配对效果。

        (1)从文本文件中解析数据

        这里是从txt文件转换成numpy类型

def turn_to_numpy(file):
    returnmat=[]
    labels=[]
    with open(file=file) as f:
        for line in f.readlines():
            line=line.strip()
            line=line.split('\t')
            returnmat.append(line[0:3])
            labels.append(line[-1])
    returnmat=np.array(returnmat)
    labels =np.array(labels)
    return returnmat,labels
returnmat=returnmat.astype('float')

        这里是通过readlines()方法读取每一行的数据,然后去除空格和左右两边的分隔符,存储在returnmat以及labels中。

        这里我们观看数据会发现数据的差异很大,这里需要使用归一化来使数据大小变得统一。其公式为\frac{(target-min)}{max-min}。有了公式就方便我们用代码所实现。

def guiyihua(dataset,target):
    min_set =dataset.min(axis=0)
    max_set=dataset.max(axis=0)
    diff = max_set-min_set
    num = dataset.shape[0]
    diff_set =np.tile(diff,(num,1))
    min_num_set =np.tile(min_set,(num,1))
    norm_returnmat =(target-min_num_set)/diff
    return norm_returnmat,diff,min_num_set

        然后针对数据进行测试。

def datingclasstest():
    hoRadio=0.1
    datingDataMat,datingLabels =turn_to_numpy(file)
    datingDataMat =datingDataMat.astype('float')
    normmat,ranges,diff =guiyihua(datingDataMat,datingDataMat)
    m=normmat.shape[0]
    numtestvecs =int(m*hoRadio)
    errorCount=0.0
    for i in range(numtestvecs):
        classifierresult =sort_choose_k(np.array(distance(normmat[i,:],normmat[numtestvecs:m,:])),datingLabels[numtestvecs:m],3)
        print("the classifieer came back with {} ,the real answer is :{}".format(classifierresult,datingLabels[i]))
        if (classifierresult !=datingLabels[i]):
            errorCount+=1.0
        print("the total error rate is;{}".format(errorCount/float(numtestvecs)))

        这里显示错误率为0.05,其实还不错,然后我们用手写数据再来测试一下。

        数据的预处理

import numpy as np
def img2vector(filename):
    returnvect =np.zeros((1,1024))
    fr =open(filename)
    for i in range(32):
        linestr =fr.readline()
        for j in range(32):
            returnvect[0,32*i+j] =int(linestr[j])
    return returnvect

         这一步将32×32的数据转换为1×1024,这样子就可以让分类器进行处理。

        然后进行测试。

import os
import operator
def handwritingtest():
    hwlabels=[]
    trainingfilelist=os.listdir('trainingDigits')
    m=len(trainingfilelist)
    trainingmat=np.zeros((m,1024))
    for i in range(m):
        filenamestr=trainingfilelist[i]
        filestr=filenamestr.split('.')[0]
        classnumstr =int(filestr.split('_')[0])
        hwlabels.append(classnumstr)
        trainingmat[i,:] =img2vector(r'trainingDigits\{}'.format(filenamestr))
    testfilelist =os.listdir('testDigits')
    errorCount=0.0
    mtest=len(testfilelist)
    for i in range(mtest):
        filenamestr=testfilelist[i]
        filestr=filenamestr.split('.')[0]
        classnumstr =int(filestr.split('_')[0])
        vectorundertest=img2vector(r'testDigits\{}'.format(filenamestr))
        classifierresult=classify0(vectorundertest,trainingmat,hwlabels,3)
        print("the classifier came back with:{},the real answer is:{}".format(classifierresult,classnumstr))
        if(classifierresult!=classnumstr):
            errorCount+=1.0
    print("the total error rate is:{}".format(errorCount/float(mtest)))

        这样子就完成了K近邻算法的手写以及测试

 

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

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

相关文章

【Android车载系列】第10章 系统服务-SystemServer源码分析(API28)

1 SystemServer启动 &emps;&emps;SystemServer进程启动,首先从SystemServer.java文件的main()方法开始。 290 /** 291 * The main entry point from zygote. 292 */ 293 public static void main(String[] args) { 294 new SystemSe…

S32K3系列单片机开发笔记(SIUL是什么/配置引脚复用的功能·)

前言 今天花时间看了一下,SIUL2模块的相关内容,并参照文档,以及例程作了一些小记录,知道该如何使用这个外设,包括引脚的配置,中断配置,以及常用函数的使用等,但对其中的一些细节还需…

如何利用代码快速生成mapper.xml的<resultMap>

一,问题引入 当我们开发 mapper.xml ---->dao接层 ---->service接口---->serviceImp ---->controller层, 其中在mapper.xml编写查询语句的sql时会遇到sql查询到的结果 涉及到多张表的字段,或者单张表的字段过多时, 这…

Python文件处理

文章目录 1️⃣基本语法2️⃣读取文件⚜️读取整个文件read()⚜️with 关键词⚜️逐行读取 3️⃣写入文件⚜️写入文件write()⚜️写入数字⚜️追加内容到文件 4️⃣读取和写入二进制文件 简介 读完本篇你将学会文件的创建、读取、写入等。 1️⃣基本语法 在Python中使用文件的…

ThreadLocal机制解读和源码分析

目录 线程数据共享和安全 -ThreadLocal 什么是 ThreadLocal 代码演示 创建Dog.java 创建Pig.java T2DAO.java T2DAO T1解读set T1Service 解读 get ThreadLocalTest这个是换一种法 ThreadLocal 原理分析图 1. ThreadLocal 原理分析图(重点 set 和 get) 线程数据共…

Go Fuzzing:发现你未曾发现的漏洞

文章目录 Fuzzing(模糊测试)要求示例模拟crash 总结参考资料 Fuzzing(模糊测试) go fuzz文档 对于软件开发者而言,一项重要的任务就是确保程序的安全性。而其中一种风险就是软件中可能存在的漏洞。传统的测试方法往往需要耗费大量的时间和人力,而使用F…

【C++: 模块二 ---运算符、流程控制语句】

C: 模块二 ---运算符、流程控制语句 一、运算符:1.1算数运算符:1.2赋值运算符:1.3比较运算符:1.4逻辑运算符:1.5三目运算符: 二、程序流程结构2.1顺序结构:2.2选择结构:&…

ChatGPT免费第一版本

最近利用空余时间做了一个供大家免费体验的chatgpt国内可直接访问的版本 输入12345gpt.com可直接访问 贴上GPT给我回复的内容,😀 当今社会,交流已经成为人们日常不可或缺的一部分。然而,随着技术的发展,人们对于交流工…

【Linux 裸机篇(七)】I.MX6U 中断系统

目录 一、中断向量表1. 中断向量偏移 二、中断系统简介1. 创建中断向量表 三、GIC 控制器简介1. 中断 ID 四、GIC 逻辑分块1. Distributor(分发器端)2. CPU Interface(CPU 接口端) 五、CP15 协处理器六、中断使能1. IRQ 和 FIQ 总中断使能2. ID0~ID1019 中断使能和禁止 七、中断…

【PXE高效的批量网络装机】

目录 一、PXE的概述1.1、PXE批量部署的优点1.2、搭建PXE满足的以下的前提条件1.3、搭建PXE远程安装 二、搭建PXE远程安装服务器1、安装并启动 TFTP 服务2、安装并启用 DHCP 服务3、准备 Linux 内核、初始化镜像文件4、准备PXE 引导程序5、安装FTP服务,准备CentOS 7 …

SpringMVC使用域对象共享数据

1、SpringMVC中的域对象 此处只有request、session、servletContext被使用,而page是jsp页面的域,不使用jsp。 request:一次请求的范围内session:一次会话的范围内servletContext:整个web的应用范围内 2、向request域…

MySQL高级第十七篇:数据库主从复制原理及保证数据一致性

MySQL高级第十七篇:数据库主从复制原理及保证数据一致性 一、概述1. 提升数据库的并发能力2. 主从复制的作用? 二、主从复制原理三、搭建一主一从环境四、如何解决数据一致性问题?1. 方案一、异步复制2. 方案二、半同步复制3. 方案三、组复制…

3.黑马Springboot原理篇自己修改笔记

原理篇 1.自动配置的工作流程 1.1 bean的加载方式 方式一&#xff1a;配置文件<bean/>标签 缺点&#xff1a;配置bean太繁琐 方式二&#xff1a;配置文件扫描注解定义bean⭐️ 获取bean方式 ①通过配置文件&#xff0c;扫描指定包&#xff0c;加载bean ②通过注解声…

C++ STL之string容器的模拟实现

目录 一、经典的string类问题 1.出现的问题 2.浅拷贝 3.深拷贝 二、string类的模拟实现 1.传统版的string类 2.现代版的string类&#xff08;采用移动语义&#xff09; 3.相关习题* 习题一 习题二 4.写时拷贝 5.完整版string类的模拟实现[注意重定义] MyString.h…

磁珠的工作原理

磁珠是一个耗能元器件&#xff0c;他能把频率相对较高的信号以热量的形式耗散掉&#xff0c;保留频率相对较低的信号。 主要有这种插件的磁珠&#xff0c;还有这种贴片的磁珠。 下面我们来看下磁珠具体工作原理。 磁珠的构造我们可以简单的看成一个导线穿过环形铁氧体的磁性材…

[渗透教程]-015-网络与系统渗透

文章目录 1.0基本概念2.0 网络与系统渗透基本原理2.1 渗透测试2.2 入侵和预防2.3 案例一:从信息收集到入侵提权2.3.1 从域名到ip2.3.2 从IP获取旁站2.3.3 收集系统与⽹络配置详细信息2.3.4 踩点2.3.5发现漏洞2.3.6漏洞利用2.3.7维持系统控制权2.3.8清理访问痕迹2.4 案例二:Goo…

TryHackMe-Jeff(boot2root | Hard?)

Jeff 你能破解杰夫的网络服务器吗&#xff1f; 如果你发现自己在暴力破解SSH&#xff0c;你就做错了。 端口扫描 循例nmap 进80&#xff0c;是一个空页面&#xff0c;查看源代码 将jeff.thm加入hosts 上gobuster /admin是空页面&#xff0c;/backups也没东西&#xff0c;/up…

Centos安全加固策略

目录 密码安全策略 设置密码的有效期和最小长度 设置用户密码的复杂度 登录安全策略 设置用户远程登录的安全策略 安全的远程管理方式 访问控制 限制root用户登录 修改ssh 22端口 设置登录超时时间 限制IP访问 安全审计 审核策略开启 日志属性设置 查看系统登录…

基础巩固、探寻Java装箱和拆箱的奥妙!

前言 今天在逛某知名论坛的时候&#xff0c;看到一篇"请不要使用包装类型&#xff0c;避免造成性能损失"的文章。一下子就吸引了我的注意。大意就是&#xff0c;能用基本数据类型就尽量用基本数据类型&#xff0c;因为包装类型自动拆箱、装箱会带来性能损失尤其是循环…

函数式编程#3纯函数的概念

纯函数的概念 文章目录 纯函数的概念纯函数的两种形式&#xff1a;调用目标本身,不会改变函数内部,不受函数外部影响 函数的副作用如何理解"相同的输入得到相同的输出"不是纯函数的映射关系是纯函数的映射关系 纯函数的两种形式&#xff1a; 调用目标本身,不会改变 …