KNN邻近算法

 1,综述
     1.1 Cover和Hart 1968年提出
     1.2 Classification算法
     1.3 输入基于实例的学习(instance——based learnin), 懒惰学习(lazy learnin)
 2,算法详述
     2.1 步骤
          为了判断未知实例的类别,以所有已知实例的特例作为参照。
          (1)选择参数k
          (2)计算未知实例与已知实例的距离
          (3)选择最近的K个已知实例
               注意:K个最近邻的选择是解决这个算法的难点,若选k近邻的方法不好,则算法复杂度会变的特别大。一种方法是构造kd树
          (4)根据少数服从多数原则,让未知实例归类为k个最邻近样本中多数的类别
     2.2 细节
          (1)关于k,一般选择奇数,偶数有时候会出现,类别一样多
            注意:k的选择很关键,太小(近似误差减小,估计误差增大)太大(近似误差增大,估计误差减小)一般用交叉验证法来确定             k 的选择。
          (2)关于距离的衡量方法
               <1>Euclidean Distance定义(欧式距离)
               <2>余弦值(cos)
               <3>相关度(correlation)
               <4>曼哈顿距离(Mahattan distance): 格子路距离
    
 3, 算法优缺点
     3.1算法优点
          (1)简单
          (2)易于理解
          (3)容易实现
          (4)通过对K的选择可具备丢噪音数据的健壮性
     3.2算法缺点
          (1)需要大量空间存储所有已知实例
          (2)算法复杂度高(需要比较所有已知实例与要分类的实例)
          (3)当样本分布不平衡,比如其中一类样本过大(实例数目过多)占主导的时候,新的未知实例容易被归类为这个主导样本,因为这类样本实例的数目过大,但这个          
               新的未知实例实际并未接近目标样本
 4, 样本改进
     考虑距离,根据距离加上权重
     比如,1/d(d:距离


简单的实现代码:


import math

def Euclean_distance(*p):
    arrow_a, arrow_b = p
    sequare_sum = 0
    for seq_num, num in enumerate(arrow_a):
        sequare_sum += (num - arrow_b[seq_num])**2
    return math.sqrt(sequare_sum)

def K_NN_fit(train_x, test_x, k = 3):
    all_distance = []

    for i, a in enumerate(train_x):
        d1 = Euclean_distance(a[:len(a)-1], test_x)
        all_distance.append([i, d1, a[-1]])
    all_distance.sort(key = lambda dista: dista[1])   
    K_element = all_distance[:k]
    k_element_class = {}
    for i in K_element:
        label = i[2]
        if label in k_element_class:
            k_element_class[label] += 1
        else:
            k_element_class.setdefault(label, 1)
    extreme_num_key = sorted(k_element_class,
                             key = lambda s: k_element_class[s],
                            reverse = True)
    predict_label = extreme_num_key[0]
    print('test_x,predict', predict_label)
    print(k_element_class)
    print(all_distance)



b = [[2, 1, 3], [4, 5, 6]]
c = [3,3]
All_distance(b,c)









    k值的选取是关键,太小近似误差减小,估计误差增大,近邻起作用,但缺点是对近邻太敏感,噪声干扰加强,容易造成过拟合。
    k值选太大,近似误差增大,估计误差减小,这时与实例点较远的点也起作用,容易造成估计错误,对于样本分布不均匀的很容易预测错误。
     实际中,通常采用交叉验证法来选取较小的最优k值





关于交叉验证法:
  

转载]交叉验证(Cross Validation)

已有 12319 次阅读 2013-3-1 08:07 |个人分类:统计学|系统分类:科研笔记|关键词:set prediction training because similar|文章来源:转载

Breiman and Spector (1992) demonstrated that leave-one-out cross-validation has high variance if the prediction rule is unstable, because the leave-one-out training sets are too similar to the full data set. 5-fold or 10-fold cross-validation displayed lower variance. Efron and Tibershirani (1997) proposed a 0.632+ bootstrap method, which is a bootstrap smoothing version of cross validation and has less variation.
LOOCV的误差比较大,而bootstrap的误差相对较小。
All of the data being used to select the genes and cross-validation used only for fitting the parameters of the model. 在高维情况下,容易错误的使用交叉验证/
 
In a pilot study, we generated 100 samples with 1000 features for each sample, all coming invariably from the Gaussian distribution N(0,1). We randomly assigned the samples into two classes ("fake-classes"). Since the data set is totally non-informative, the faithful CV error should be around 50% no matter what method is used. But by CV1 scheme we could achieve a CV error as low as 0.025 after recursive feature selection, which shows that the bias caused by the improper cross-validation scheme can be surprisingly large. A more proper approach is to include the feature selection procedure in the cross validation, i.e., to leave the test sample(s) out from the training set before undergoing any feature selection. In this way, not only the classification algorithm, but also the feature selection method is validated. We call this scheme CV2 and use it in all of our investigations throughout. For the above "fakeclass" data, the error rate evaluated by CV2 was always around 50% regardless of the specific method used for feature selection and classification.
 
以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set),首先用训练集对分类器进行训练,在利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标.常见CV的方法如下:
 
1).Hold-Out Method

将原始数据随机分为两组,一组做为训练集,一组做为验证集,利用训练集训练分类器,然后利用验证集验证模型,记录最后的分类准确率为此Hold-OutMethod下分类器的性能指标.此种方法的好处的处理简单,只需随机把原始数据分为两组即可,其实严格意义来说Hold-Out Method并不能算是CV,因为这种方法没有达到交叉的思想,由于是随机的将原始数据分组,所以最后验证集分类准确率的高低与原始数据的分组有很大的关系,所以这种方法得到的结果其实并不具有说服性.

2).K-fold Cross Validation(记为K-CV)

将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型,用这K个模型最终的验证集的分类准确率的平均数作为此K-CV下分类器的性能指标.K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2.K-CV可以有效的避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性.

3).Leave-One-Out Cross Validation(记为LOO-CV)

如果设原始数据有N个样本,那么LOO-CV就是N-CV,即每个样本单独作为验证集,其余的N-1个样本作为训练集,所以LOO-CV会得到N个模型,用这N个模型最终的验证集的分类准确率的平均数作为此下LOO-CV分类器的性能指标.相比于前面的K-CV,LOO-CV有两个明显的优点:

① 每一回合中几乎所有的样本皆用于训练模型,因此最接近原始样本的分布,这样评估所得的结果比较可靠。

② 实验过程中没有随机因素会影响实验数据,确保实验过程是可以被复制的。

但LOO-CV的缺点则是计算成本高,因为需要建立的模型数量与原始数据样本数量相同,当原始数据样本数量相当多时,LOO-CV在实作上便有困难几乎就是不显示,除非每次训练分类器得到模型的速度很快,或是可以用并行化计算减少计算所需的时间. 

  1. Test-set estimator of performance has high variance.
  2. CV涉及到模型评价与选择,获得最有的模型后,使用所有观测训练作为预测模型。whichever model gives the best CV score: train it with all data,and that's the predictive model you'll use.
  3. AIC(AKaike information criterion赤池信息标准) ,BIC( bayesion information criterion)
  4. how can we use cross-validation to find useful subset!
  5. intensive use of cross validation can overfit.
  6. hold out an additional testset before doing any model selection.

在pattern recognition与machine learning的相关研究中,经常会将dataset分为training跟test这两个subsets,前者用以建立model,后者则用来评估该model对未知样本进行预测时的精确度,正规的说法是generalization ability。在往下叙述之前,这边就必须点出一个极为重要的观念:只有training data才可以用在model的训练过程中,test data则必须在model完成之后才被用来评估model优劣的依据。

怎么将完整的dataset分为training set与test set也是学问,必须遵守两个要点:

  1. training set中样本数量必须够多,一般至少大于总样本数的50%。
  2. 两组子集必须从完整集合中均匀取样。

其中第2点特别重要,均匀取样的目的是希望减少training/test set与完整集合之间的偏差(bias),但却也不易做到。一般的作法是随机取样,当样本数量足够时,便可达到均匀取样的效果。然而随机也正是此作法的盲点,也是经常是可以在数据上做手脚的地方。举例来说,当辨识率不理想时,便重新取样一组training set与test set,直到test set的辨识率满意为止,但严格来说这样便算是作弊了。

Cross-validation正是为了有效的估测generalization error所设计的实验方法,可以细分为double cross-validation、k-fold cross-validation与leave-one-out cross-validation。Double cross-validation也称2-fold cross-validation(2-CV),作法是将dataset分成两个相等大小的subsets,进行两回合的分类器训练。在第一回合中,一个subset作为training set,另一个便作为test set;在第二回合中,则将training set与test set对换后,再次训练分类器,而其中我们比较关心的是两次test sets的辨识率。不过在实务上2-CV并不常用,主要原因是training set样本数太少,通常不足以代表母体样本的分布,导致test阶段辨识率容易出现明显落差。此外,2-CV中分subset的变异度大,往往无法达到「实验过程必须可以被复制」的要求。

K-fold cross-validation (k-CV)则是double cross-validation的延伸,作法是将dataset切成k个大小相等的subsets,每个subset皆分别作为一次test set,其余样本则作为training set,因此一次k-CV的实验共需要建立k个models,并计算k次test sets的平均辨识率。在实作上,k要够大才能使各回合中的training set样本数够多,一般而言k=10算是相当足够了。

最后是leave-one-out cross-validation (LOOCV),假设dataset中有n个样本,那LOOCV也就是n-CV,意思是每个样本单独作为一次test set,剩余n-1个样本则做为training set,故一次LOOCV共要建立n个models。相较于前面介绍的k-CV,LOOCV有两个明显的优点:

  • 每一回合中几乎所有的样本皆用于训练model,因此最接近母体样本的分布,估测所得的generalization error比较可靠。
  • 实验过程中没有随机因素会影响实验数据,确保实验过程是可以被复制的。

但LOOCV的缺点则是计算成本高,因为需要建立的models数量与总样本数量相同,当总样本数量相当多时,LOOCV在实作上便有困难,除非每次训练model的速度很快,或是可以用平行化计算减少计算所需的时间。

使用Cross-Validation时常犯的错误

由于实验室许多研究都有用到evolutionary algorithms(EA)与classifiers,所使用的fitness function中通常都有用到classifier的辨识率,然而把cross-validation用错的案例还不少。前面说过,只有training data才可以用于model的建构,所以只有training data的辨识率才可以用在fitness function中。而EA是训练过程用来调整model最佳参数的方法,所以只有在EA结束演化后,model参数已经固定了,这时候才可以使用test data。

那EA跟cross-validation要如何搭配呢?Cross-validation的本质是用来估测(estimate)某个classification method对一组dataset的generalization error,不是用来设计classifier的方法,所以cross-validation不能用在EA的fitness function中,因为与fitness function有关的样本都属于training set,那试问哪些样本才是test set呢?如果某个fitness function中用了cross-validation的training或test辨识率,那么这样的实验方法已经不能称为cross-validation了。

EA与k-CV正确的搭配方法,是将dataset分成k等份的subsets后,每次取1份subset作为test set,其余k-1份作为training set,并且将该组training set套用到EA的fitness function计算中(至于该training set如何进一步利用则没有限制)。因此,正确的k-CV 会进行共k次的EA演化,建立k个classifiers。而k-CV的test辨识率,则是k组test sets对应到EA训练所得的k个classifiers辨识率之平均值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值