knn邻近算法例题,简述knn算法
KNN回归和分类的主要区别在于最后预测时的决策方式不同。KNN在进行分类预测时,一般选择多数投票法,即将训练集中与预测样本特征最接近的K个样本预测为类别数最多的类别。KNN在进行回归时,通常选择平均法,即最近k个样本的样本输出的平均值作为回归预测值。
一 KNN算法概述
KNN(K近邻)工作原理:有一个样本数据集,也叫训练样本集,样本集中的每一个数据都有一个标签,即我们知道样本集中每一个数据与其分类的对应关系。输入未标记数据后,将新数据中的每个特征与样本集中对应的特征进行比较,提取样本集中与该特征最相似(最近邻)的数据的分类标签。一般来说,我们只选取样本数据集中最相似的前K个数据,这就是K近邻算法中K的由来。通常,K是不大于20的整数。最后,在K个最相似数据中出现最频繁的分类被选为新数据的分类。
KNN算法的一般流程:
1)计算测试数据和每个训练数据之间的距离;
2)按照距离的递增关系排序;
3)选择距离最小的k个点;
4)确定前k个点的类别的出现频率;
5)返回前k个点中出现频率最高的类别作为测试数据的预测分类。
二 KNN算法
1不用库函数实现手写数字识别
* *将numpy作为NP从OS导入listdirimport运算符# K-最近邻算法,使用清晰的铅笔距离def classify0 (inx,dataset,labels,K): #计算距离datasetsize=dataset . shape[0]diff mat=NP . tile(inx,(dataset size,1)-dataset sqdiff mat=diff mat * * 2 sq distances=sqdiff mat . sum(axis=1)distances=sq distances * * 0.5 #排序, 并选择k最小距离sorted distance=distance . arg sort()discount={ } for I in range(k):votelLabel=labels[sorted distance[I]]discount[votelLabel]=discount . get(votelLabel,0)1 sorted class count=sorted(discount . items(),key=operator.itemgetter(1),Reverse=True) #返回最高频率标签return sortedClassCount[0][0]#将32的二进制图片转换为1*1024 def的矢量img2vex(文件名):返回矢量=np 2 * I j]=int(linestr[j])RETURN VECT #手写数字识别系统的测试代码DEF handwriting class():HW Labels=[]train listdir=list dir(r d: Python 机器学习实用代码 machinelinginactivation Ch02 digits training digits )m=len(training listdir)training max=NP . zeros((m,024))for I in range(m):filenamestr=train listdir[I]#以。取第一个filestr=filenamestr.split(。)[0]classnumstr=int(fileStr . split( _ )[0])HW labels . append(classnumstr)training max[I,]=img 2 vex(r d: python Machine learning practice code Machine learning action Ch02 digits training digits % s . txt % fileStr)# test listdir=list dir(r d: python Machine learning practice code Ch02 digits test digits )mTest=len(test listdir)error count=len)[0] Classnumstr=int (filestr。split( _ )[0])VectorUndertest=img 2 vex(r d: Python Machine Learning Practical Code Machine Learning action CH02 digits test digits % s . txt % fileStr)classify result=classif y0(training max,VectorUndertest,hwLabels,3) print(分类器带回来;%d,实际结果是:% d“%(classify result,classNumStr)) if(classifyResult!=classNumStr):error count=1.0 print(总错误数为:% d % error count print(总错误率为:% f %(error count/float(mTest)))def main():hand writing class()if _ _ name _ _= _ _ main _ :main()* *输出结果:总错误数为:10总错误率为:0.010571
基于2 sklearn的KNN算法的虹膜分类
从sklearn.datasets导入load _ iris from sk learn . model _ selection导入train_test_splitfrom sklearn .预处理导入标准Scalerfrom sklearn。邻居导入KNeighborsClassifierdef get _ iris_data():Iris=load _ Iris()Iris _ data=Iris . data iris_target=Iris . target返回Iris _ data,Iris _ target def run (): iris _ data,iris _ target=get _ iris _ data () #拆分验证集和测试集x _ train,x _ test,y _ train,y _ Test=train _ Test _ split(Iris _ data,Iris _ target,Test_size=0.25) #归一化STD=standard scaler()x _ train=STD . fit _ transform(中FIT (x _ train,y _ train)y _ predict=KNN . predict(x _ test)print(y _ predict)labels=[ Iris Iris , iris mallow ,Iris discolored ]for I in range(len(y _ predict)):print( test % d:实值:% s t预测值:% s% ((i 1),labels [y _ predict [i]],labels [y _ test [i
准确率:0.9988.00000000004
三 K-近邻算法优缺点
优势:
1)简单易用,易于理解,精度高,理论成熟,既可用于分类,也可用于回归;
2)可用于数值型数据和离散型数据;
3)训练时间复杂度为O(n);无数据输入假设;
4)对异常值不敏感。
缺点:
1)高计算复杂度;
2)必须保存所有数据,空间复杂度高;
3)样本不平衡的问题(即有的类别样本数量多,有的类别样本数量少),此时预测偏差会比较大。
四 K-近邻算法的优化
KNN算法的缺陷(1)样本不平衡
通过KNN算法,我们明显可以得出X应该属于红点,但是对于样本Y,我们似乎通过KNN算法得出了Y应该属于蓝点的结论,这在直观上是没有说服力的。
解决方法
:1)距离加权
离样本距离小的邻居权重大,离样本距离大的邻居权重相对小。所以也考虑了距离的因素,避免样本过多造成误判。
权重加权:给每个点的距离加上一个权重,让距离近的点得到更大的权重。在这里,如何加权是描述。
A.反函数
这种方法最简单的形式就是返回距离的倒数,比如距离d,权重为1/d,有时候完全相同或者非常接近的商品重量会非常大,甚至无穷大。因此,当距离倒置时,在距离上加上一个常数:
重量=1 /(距离常数)
这种方法的潜在问题是,它给邻居分配了很大的权重,而那些较远的邻居会迅速衰减。虽然这种情况是我们想要的,但它有时会使算法对噪声数据更加敏感。
B.高斯函数
高斯函数更复杂,但它克服了前述函数的缺点。它的形式是:
高斯函数的图形在形状上像一个倒置的时钟。a是曲线的高度,B是曲线中心线在X轴上的偏移量,C是半峰处的宽度(函数半峰处的宽度)。
def gaussian(距离,a=1,b=0,c=0.3):
return a * math . e * *(-(dist-b)* * 2/(2 * c * * 2))
当距离为0时,上面的高斯函数的权重为1。随着距离的增加,权重减小,但不会变成0。下图显示了高斯函数与其他函数的区别。当其他函数的距离增加到一定程度时,其他函数的权重都降到0或以下。
加权kNN首先获取排序后的距离值,然后取最近的k个元素。
1.在处理离散数据时,按权重对这k个数据区别对待,预测结果与第n个数据的标签相同的概率:
2.在处理数值型数据时,我们并不是简单的对这k个数据进行平均,而是做加权平均:将每一项的距离值乘以对应的权重,就可以在后面累加出结果。计算出总和后,除以所有权重的总和。
Di表示最近邻I与待预测值X之间的距离,Wi表示其权重,f(x)是预测的数值结果。在预测每个新样本的类别时,将遍历整个样本。可见kNN的效率其实很低。
KNN算法的缺陷(2)计算量太大
第一是需要存储所有的训练样本,
第二是计算量大,因为对于每一个待分类的样本,都要计算它到所有已知样本的距离,这样才能得到它的k个最近邻。
解决办法
构造kd-tree: kd-tree是一种树状数据结构,将实例点存储在K维空间中,以便快速检索。Kd-tree是二叉树,表示K维空间的划分。构造kd-tree相当于用垂直于坐标轴的超平面不断划分K维空间,形成一系列K维超矩形区域。kd树的每个节点对应一个K维超矩形区域。Kd-tree可以节省对大部分数据点的搜索,从而减少搜索的计算量。
构建kd树
输入:立方体
输出:kd树
(1)开始:构造根节点。选取X作为分割坐标轴,以所有实例的X坐标的中值作为分割点,将根节点对应的区域分为左右两个子区域。左边的子节点对应于坐标小于分割点的子区域,右边的子节点对应于坐标大于分割点的子区域。在根节点保存落在分割超平面上的实例点。
(2)重复。对于左右分区,坐标轴交替分段,坐标轴对应坐标的中值继续作为分段点。直到所有的点都被分割。
四 K-近邻算法的使用场景
文本分类,多分类理解,模式识别