分类算法KNN的python实现
创始人
2024-05-02 12:14:54
0

作者:刘凡

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_neighborsself.dist_func = dist_func# 训练模型方法def fit(self,x,y):# 将x,y传进来即可self.x = xself.y = y# 模型预测方法def predict(self,x):# 初始化预测分类数组y_pred = np.zeros((x.shape[0],1),dtype = self.y.dtype)# 遍历输入的x数据点,取出每一个数据点的i和数据x_testfor 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_scoreiris = 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 KNeighborsClassifieriris = 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))

在这里插入图片描述

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...