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

news/2024/11/8 15:15:37/

        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=0for j in range(dataset[i].shape[0]):diff += (dataset[i][j]-target[j])**2distance =diff**0.5distances.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_setnum = 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)/diffreturn norm_returnmat,diff,min_num_set

        然后针对数据进行测试。

def datingclasstest():hoRadio=0.1datingDataMat,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.0for 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.0print("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.0mtest=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.0print("the total error rate is:{}".format(errorCount/float(mtest)))

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

 


http://www.ppmy.cn/news/53074.html

相关文章

Google Play编写长描述的最佳实践

在我们为应用编写详细说明时,要遵循以下建议: 我们作为应用营销人员,要了解受众群体的需求和顾虑,如果不知道用户关心什么,那么我们可以查看关键词的搜索量、每个关键词的 Google Play 安装报告、当前关键字排名等等。…

选择美国虚拟主机需注意的安全问题

在选择美国虚拟主机时,安全性应该是您首要关注的问题。虚拟主机通常是网站托管的最便宜和最方便的方式之一,但也存在安全问题。在本文中,我们将讨论一些您应该注意的安全问题,并提供一些解决方案来保护您的网站。 一、了解虚拟主机…

我的创作纪念日(划水...)

机缘 提示:可以和大家分享最初成为创作者的初心 例如: 实战项目中的经验分享日常学习过程中的记录通过文章进行技术交流… 收获 提示:在创作的过程中都有哪些收获 例如: 获得了多少粉丝的关注获得了多少正向的反馈&#xff0c…

openCV功能函数

形态学-腐蚀操作 cv2.erode(img, kernel, iterations1) img: 被处理图像 kernel: 处理图像用的盒子nxn大小 iterations: 函数运行次数 形态学-膨胀操作 cv2.dilate(img, kernel, iterations1) 开运算和闭运算 开: 先腐蚀,再膨胀 cv2.morphologyEx(i…

《Left ventricular hypertrophy detection using electrocardiographic signal》阅读笔记

论文的摘要 Left ventricular hypertrophy (LVH) indicates subclinical organ damage, associating with the incidence of cardiovascular diseases. From the medical perspective, electrocardiogram (ECG) is a low-cost, non-invasive, and easily reproducible tool th…

java定时任务schedule

在 Java中,可以使用定时任务(schedule)来实现定时任务。这种定时任务能够根据用户的需求进行时间的控制,让用户可以自由设定每一个任务的开始时间和结束时间。 下面来介绍如何使用 java中的定时任务来实现定时任务。 首先需要在配…

R—读取数据(导入csv,txt,excel文件)

导入CSV、TXT文件 read.table函数:read.table函数以数据框的格式读入数据,所以适合读取混合模式的数据,但是要求每列的数据数据类型相同。read.table读取数据非常方便,通常只需要文件路径、URL或连接对象就可以了,也接…

业界内源码学习第一节

技术主题 业界内的技术研究 技术原理 HashMap是Java中最常用的数据结构之一,它使用键-值对的方式存储和管理数据。下面是Java 11中HashMap的简化版本源代码: java Copy code public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>,…