分类算法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))

在这里插入图片描述

相关内容

热门资讯

同学会联欢会主持词 同学会联欢会主持词  借鉴诗词和散文诗是主持词的一种写作手法。在一步步向前发展的社会中,越来越多的活...
搞笑脱口秀台词脱口秀台词 搞笑脱口秀台词脱口秀台词1100字校园脱口秀台词每天,当我的双脚迈入合肥七中的大门,强相互作用会把我...
学生会换届大会主持词 学生会换届大会主持词  主持词的内容  主持词一般由开场白、中间部分与结束语组成。  开场白 演出或...
教研活动公开课主持稿   教研活动公开课主持稿  篇一:数学教研活动主持词  各位领导、各位老师,大家好!  在这样一个春...
《花木兰》感人台词 《花木兰》感人台词  壹 孝,替父从军父女情  感人段落:军令如山,花弧爱国心切,无奈年老气衰,百病...
红歌赛主持词 红歌赛主持词  由主持人于节目进行过程中串联节目的串联词。如今的各种演出活动和集会中,主持人往往成了...
联欢晚会主持词 联欢晚会主持词3篇  主持词可以采用和历史文化有关的表述方法去写作以提升活动的文化内涵。在如今这个时...
金榜题名主持词 金榜题名主持词(精选23篇)  主持词要根据活动对象的不同去设置不同的主持词。随着社会一步步向前发展...
光荣退休领导致辞 光荣退休领导致辞范文(通用5篇)  在学习、工作或生活中,要用到致辞的情况还是蛮多的,致辞是指在仪式...
大学迎新晚会主持词 大学迎新晚会主持词  迎新,全称迎接新春,又叫迎接新年。迎新是中国的传统节日形式。或者欢迎、迎接新来...
教师节校长简短致辞 教师节校长简短致辞(通用10篇)  在日常学习、工作抑或是生活中,大家或多或少都用到过致辞吧,在各种...
张国荣经典台词 关于张国荣经典台词  1、哭,我为了感动谁,笑,又为了碰着谁。  ——《路过蜻蜓》  2、虽然我很喜...
新郎婚礼简短致辞 新郎婚礼简短致辞(精选10篇)  在平平淡淡的学习、工作、生活中,大家都经常接触到致辞吧,致辞是指在...
美剧经典台词截图 美剧经典台词截图  在社会发展不断提速的今天,用到台词的地方越来越多,台词是一种特殊的文学语言,必须...
女朋友撒娇的经典台词 女朋友撒娇的经典台词  1、这种被朋友的情况让我很失落,因为我喜欢他。  2、“她就是躲着我我该怎么...
会主持词开场白 会主持词开场白  篇一  尊敬的各位领导、各位来宾  各位公司同仁:  大家下午好!  非常高兴和大...
中国人寿保险公司晨会主持词 中国人寿保险公司晨会主持词  主持词由主持人于节目进行过程中串联节目的串联词。以下是小编整理的中国人...
公司中秋晚会主持词 关于公司中秋晚会主持词  主持词分为会议主持词、晚会主持词、活动主持词、婚庆主持词等。在当今不断发展...
小学生职位竞选词 小学生职位竞选词  个人觉得竞选中队长,你已经很清楚中队长需要做的事情了,那么就从每一个任务来发展一...
在结婚典礼上的精彩幽默主持词 在结婚典礼上的精彩幽默主持词各位来宾:大家好!奉新郎新娘之命,我来主持今天的婚礼。为什么新郎新娘一定...