knn算法的基本原理,KNN算法实现
机器学习基础算法的Python代码实现可以参考:zlxy9892/ml_code1原理knn是机器学习领域非常基础的算法,可以解决分类或者回归问题。如果你刚开始学习机器学习,knn是一个非常好的入门选择。很好理解,也很容易实现,下面介绍一下它的算法原理。
首先,knn算法的基本规则是同一类别的样本应该在特征空间中聚类在一起。
如下图所示,假设我们的红绿蓝点分布在一个二维空间,对应的是分类任务中的训练样本包含三个类别,特征个数为2。现在,如果我们要猜图中空心圆的点属于那个类别,那么knn算法会计算出待猜点与所有训练点之间的距离,选择距离最小的k个点(这里设定k=4),然后将图中相连的四个点作为猜测空心点(待猜点)类别的参考。显然,由于这四个点都在红色范畴内,所以要推测的点被推定为红色范畴。
knn的图1显示了另一种情况。如果要猜测的点在中间的某个地方(如下图所示),也会计算出最近的四个样本点,这四个样本点包括三类(1红1蓝2绿)。针对这种情况,knn算法通常采用投票法来猜测类别,即在K个样本点中找出类别出现频率最高的类别,即待猜测点
Knn说明了2knn的原理就是这么简单,这么简单,所以有人会说,相比现在流行的其他更复杂的机器学习算法,比如神经网络,随机森林等。这么简单的算法有什么价值?
要回答这个问题,我们不妨回忆一下机器学习中著名的没有免费的午餐定理。任何问题(学习任务)都没有最佳模型。相反,它只是提醒我们,对于一个具体的学习任务,需要考虑最适合该问题的学习者,即具体问题具体分析的哲学真理。
那么,knn一定有它存在的价值。比如现在我们有一个学习任务,需要选择一个学习装置来解决问题,这个问题的研究没有先例。那么,我们应该从哪里开始呢?通常情况下,我们不需要使用神经网络模型或强大的集成学习模型来完成。而是可以先用一个简单的模型做一个“试验”。比如knn就是个不错的选择。这样的“试验”有什么好处?我们知道,knn本质上是懒学习的代表,也就是说,它根本不使用训练数据来拟合一个模型,而是直接使用top-k个相邻样本点进行投票来完成分类任务。那么,如果这样的懒惰模型已经能够在当前问题上获得更高的准确率,我们就可以认为当前的学习任务是相对简单的。不同类型的样本点在特征空间的分布是清晰的,因此不需要采用复杂的模型。相反,如果knn得到的准确率低,传达给我们的信息就是学习任务有点复杂,当前问题中不同类型的样本点在特征空间的分布不明确,通常是非线性可分的,需要调用更强的学习者。所以一个简单的knn机器学习算法正好可以帮助建模者对问题的复杂程度有一个大致的判断,帮助我们做进一步的工作:继续挖掘特征工程,或者替换复杂的模型等等。
2算法的实现下面用python自己实现一个knn分类器。
代码:3359github.com/zlxy9892/ml _代码/树/主/基本_算法/KNN
首先,创建一个名为knn.py的文件,该文件用于构建由knn实现的类。代码如下。
# -*-编码:utf-8-*-import numpy as NP导入运算符类KNN(object):def _ _ init _ _(self,k=3): self.k=k def fit(self,x,y):self。x=x自我。y=y def _ square _ distance(self,v1,v2):返回NP。sum(NP。square(v1-v2))def _ vote(self):ys _ unique=NP。unique(ys)vote_dict={ } for y in ys:如果y不在投票_字典中_square_distance(x[i],self。x[j])对于范围内的j(len(self。x))]sorted _ index=NP。arg sort(dist _ arr)top _ k _ index=sorted _ index[:self。k]y _ pred。追加(自我。_vote(ys=self.y[top_k_index])返回np.array(y_pred) def score(self,y_true=None,y_pred=None):如果y_true为没有人且y_pred为无:y _ pred=self。预测(自我。x)y _ true=self。范围内I的y score=0.0(len(y _ true)):if y _ true[I]==y _ pred[I]:score=1 score/=len(y _ true)返回接下来创建train.py文件,用于生成随机的训练样本数据,并调用近邻算法类完成分类任务,并计算推测精度。
# -*-编码:utf-8-*-import numpy as NP import matplotlib。从KNN导入的py绘图为PLT * #数据生成NP。随机的。种子(314)data _ size _ 1=300 x1 _ 1=NP。随机的。正常(loc=5.0,scale=1.0,size=data _ size _ 1)x2 _ 1=NP。随机的。normal(loc=4.0,scale=1.0,size=data _ size _ 1)y _ 1=[0]PLT . show()PLT . scatter(x_test[:0],x _ test[:1],c=y_test,marker= . )PLT。show()#数据预处理x _ train=(x _ train-NP。min(x _ train,axis=0))/(np.max(x_train,axis=0) - np.min(x_train,axis=0))x _ test=(x _ test-NP。min(x _ test,axis=0))/(np.max(x_test,axis=0) - np.min(x_test,axis=0))# KNN分类器clf=KNN(k=3)clfformat(clf。score()))y _ test _ pred=clf。预测(x _ test)打印(测试精度:{:3} 。格式(clf.score(y_test,y_test_pred)))至此,knn算法原理阐述与代码实现介绍完毕。