k近邻算法
-  k近邻算法(KNN,K-NearestNeighbor)是一种基本分类和回归方法,监督学习算法,本质上是基于一种数据统计的方法; 
-  核心思想:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类(多数表决规则等价于经验风险最小化),就把该输入实例分类到这个类中(通俗说:一个新的输入实例,我们算出该实例与每一个训练点的距离,然后找到前k个,这k个哪个类别数最多,我们就判断新的输入实例就是哪类) 
-  k值选取:KNN算法唯一的超参数。一般选取一个较小的数值,通常采取交叉验证法来选取最优的k值(李航《统计学习方法》) - k太小(如k=1),模型复杂,学习噪声,导致过拟合;
- k太大(如k=N, N为训练样本的个数),受到样本均衡问题,模型过于简单;
 
-  距离函数: 闵可夫斯基距离,不是一种距离,而是一组距离的定义,是对多个距离公式的概括性表述; -  欧式距离 
-  曼哈顿距离 
-  切比雪夫距离 
 d 12 = m a x ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ∣ ) d_{12}=max(|x_1 - x_2|, |y_1 - y_2|) d12=max(∣x1−x2∣,∣y1−y2∣)
-  标准化欧式距离(standardized EuclideanDistance) 在计算中添加了标准差,对量纲数据进行处理 
-  余弦距离(Cosine Distance) 余弦距离(余弦相似度): 用向量空间中两个向量夹角的余弦值 作为衡量两个个体间差异的大小的度量; 
 c o s ( θ ) = ∑ k = 1 n x 1 k x 2 k ∑ k = 1 n x 1 k 2 ∑ k = 1 n x 2 k 2 cos(\theta) ={{\sum_{k=1}^nx_{1k}x_{2k}}\over \sqrt{\sum_{k=1}^n x_{1k}^2} \sqrt{\sum_{k=1}^n x_{2k}^2}} cos(θ)=∑k=1nx1k2∑k=1nx2k2∑k=1nx1kx2k
 
-  
-  算法优缺点: -  优点: -  KNN方法简单直观,易于实现!只要让预测点分别和训练数据求距离,挑选前k个即可,非常简单直观;既可以用来做分类也可以用来做回归; 
-  没有明显的训练过程(lazy learning),新数据可以直接加入数据集而不必进行重新训练; 
-  由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属的类别,因此对于类域的交叉或重叠较多的待分类样本集来说,KNN方法较其他方法更为适合。 
 
-  
-  缺点及改进: -  当样本不平衡时(比如一个类的样本容量很大,其他类的样本容量很小),输入一个样本的时候,K个邻近值大多数都是大样本容量的那个类,这时可能会导致分类错误。(改进方法:对K邻近点进行加权,也就是距离近的权值大,距离远的点权值小) 
-  计算量较大(复杂度为0(n)),每个待分类的样本都要计算它到全部点的距离,根据距离排序才能求得K个临近点。(改进方法:先对已知样本带你进行裁剪,事先去除分类作用不大的样本,采取kd树(k-dimension tree, 二叉树结构,先构建树,再近邻域搜索)、ballTree(解决KDTree在高维上效率低下的问题)以及其它高级搜索方法BBF等算法减少搜索时间。) 
 
-  
 
-  
-  应用场景 - 用户推荐:用KNN算法做到比较通用的现有用户产品推荐,基于用户的最近邻(长得最像的用户)买了什么产品来推荐,是一种基于电子商务和sns的精确营销,只需要定期维护更新最近邻表就可以
- 文本分类
- 回归问题
 
-  API class sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, *, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None)[source][n_neighbors] 也就是K,默认参数为5。 [weights] str参数,为了降低k值的影响所设置的权重值,即每个拥有投票权的样本是按什么比重投票,'uniform'表示等比重投票,'distance'表示按距离 反比投票,[callable]表示自己定义的一个函数,这个函数接收一个距离数组,返回一个权值数组。默认参数为‘uniform’。 [algorithm] str参数,即内部采用什么数据结构实现。有以下几种选择参:'ball_tree':球树、'kd_tree':kd树、'brute':暴力搜索、'auto':自动根据数据的类型和结构选择合适的算法。默认情况下是‘auto’。暴力搜索就不用说了大家都知道。具体前两种树型数据结构哪种好视情况而定。KD树是依次对K维坐标轴,以中值切分构造的树,每一个节点是一个超矩形,在维数小于20时效率最高。ball tree 是为了克服KD树高维失效而发明的,其构造过程是以质心C和半径r分割样本空间,每一个节点是一个超球体。一般低维数据用kd_tree速度快,用ball_tree相对较慢。超过20维之后的高维数据用kd_tree效果反而不佳,而ball_tree效果要好,具体构造过程及优劣势的理论大家有兴趣可以去具体学习。 [leaf_size] int参数,基于以上介绍的算法,此参数给出了kd_tree或者ball_tree叶节点规模,叶节点的不同规模会影响数的构造和搜索速度,同样会影响用于储存树的内存的大小。具体最优规模是多少视情况而定。 [matric] str或者距离度量对象,即怎样度量距离,前面有具体介绍。默认minkowski。 [p] int参数,就是以上闵氏距离各种不同的距离参数,默认为2,即欧氏距离。p=1代表曼哈顿距离等等。 [metric_params] 距离度量函数的额外关键字参数,一般不用管,默认为None。 [n_jobs] int参数,指并行计算的线程数量,默认为1表示一个线程,为-1的话表示为CPU的内核数,也可以指定为其他数量的线程,这里不是很追求速度的话不用管,需要用到的话去看看多线程。










