kNN也就是k-NearestNeighbour的缩写。从命名上也可大体了解到这个算法的精髓了。用一句话归纳而言,kNN分类算法就是‘近朱者赤,近墨者黑’。说得准确一点就是若是一个样本在特征空间中的k个最相邻的样本大多数属于某一类别,则该样本也属于此类别,并具备相应类别的特征python
下面这个例子出如今无数讲解kNN的文章中,可见其的表明性:算法
咱们把数据样本在一个平面上表示出来,相同类别的使用相同颜色和记号。绿色的圆形表明一个新的样本,咱们使用kNN来判断它的类别。方法以下:以绿色圆形为圆心,开始作不一样半径的同心圆,从实心线的同心圆来看,绿色圆形属于红色三角,从虚线同心圆来看,绿色圆形属于蓝色正方形,以此类推......ide
从上面的例子中不难发现问题,一方面,不一样的半径会有不一样的分类结果。能够说从图像上来看未知样本属于红色三角的可能性要比属于蓝色正方形的可能性大,也就是实线的同心圆范围内是合理的结果。反应在算法设计方面就是k值的选择。从另外一方面看,距离测试样本近的数据所占的权重要更大,距离远的占的权重应该小,从而能够部分避免k值选取不当而形成的判断错误。oop
k越小,分类边界曲线越光滑,误差越小,方差越大;K越大,分类边界曲线越平坦,误差越大,方差越小。因此即便简单如kNN,一样要考虑误差和方差的权衡问题,表现为k的选取。测试
k过小,分类结果易受噪声点影响;idea
k太大,近邻中又可能包含太多的其它类别的点。(对距离加权,能够下降k值设定的影响)k值一般是采用交叉检验来肯定(以k=1为基准)设计
经验规则:k通常低于训练样本数的平方根rest
而所谓的交叉验证就是把数据样本分红训练集和测试集,而后k=1开始,使用验证集来更新k的值。code
投票决定:少数服从多数,近邻中哪一个类别的点最多就分为该类。对象
加权投票法:根据距离的远近,对近邻的投票进行加权,距离越近则权重越大(权重为距离平方的倒数)
距离衡量包括欧式距离、夹角余弦等。
对于文本分类来讲,使用余弦(cosine)来计算类似度就比欧式(Euclidean)距离更合适
对minist数据集使用kNN算法 python3.5版本能够运行:
import tensorflow as tf import numpy as np import tensorflow.examples.tutorials.mnist.input_data as input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) #下载并加载mnist数据 train_X, train_Y = mnist.train.next_batch(5000) # 5000 for training (nn candidates) test_X, test_Y = mnist.test.next_batch(100) # 200 for testing tra_X = tf.placeholder("float", [None, 784]) te_X = tf.placeholder("float", [784]) # Nearest Neighbor calculation using L1 Distance # Calculate L1 Distance distance = tf.reduce_sum(tf.abs(tf.add(tra_X, tf.neg(te_X))), reduction_indices=1) # Prediction: Get min distance index (Nearest neighbor) pred = tf.arg_min(distance, 0) accuracy = 0. # Initializing the variables init = tf.initialize_all_variables() # Launch the graph with tf.Session() as sess: sess.run(init) # loop over test data for i in range(len(test_X)): # Get nearest neighbor nn_index = sess.run(pred, feed_dict={tra_X: train_X, te_X: test_X[i, :]}) # Get nearest neighbor class label and compare it to its true label print("Test", i, "Prediction:", np.argmax(train_Y[nn_index]), \ "True Class:", np.argmax(test_Y[i])) # Calculate accuracy if np.argmax(train_Y[nn_index]) == np.argmax(test_Y[i]): accuracy += 1./len(test_X) print("Done!") print("Accuracy:", accuracy)
##优势
分类效率:事先对样本属性进行约简,删除对分类结果影响较小的属性,快速的得出待分类样本的类别。该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
分类效果:采用权值的方法(和该样本距离小的邻居权值大)来改进,Han等人于2002年尝试利用贪心法,针对文件分类实作可调整权重的k最近邻居法WAkNN (weighted adjusted k nearest neighbor),以促进分类效果;而Li等人于2004年提出因为不一样分类的文件自己有数量上有差别,所以也应该依照训练集合中各类分类的文件数量,选取不一样数目的最近邻居,来参与分类