K-近邻算法

K 近邻算法 是很简单易于实现的一种算法之一  “近朱者赤,近墨者黑”的算法

主要思想:

   给定一个训练数据集,对于新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该实例分为某个类


KNN主要由 训练数据,度量方法,K来决定

   度量方法:1.简单欧式距离的计算  2.如果是文本的话,采用余弦度量 

   确定y的时候,可以选择如下两种方法:1.多数表决投票法 (默认每个数据的权重一样大) 2.采取加权投票法 距离近的权重大


KNN算法优缺点:

优点

简单,易于理解,易于实现,无需估计参数,无需训练
适合对稀有事件进行分类(例如当流失率很低时,比如低于0.5%,构造流失预测模型)
特别适合于多分类问题(multi-modal,对象具有多个类别标签),例如根据基因特征来判断其功能分类,kNN比SVM的表现要好

缺点
懒惰算法,对测试样本分类时的计算量大,内存开销大,评分慢
可解释性较差,无法给出决策树那样的规则。


算法:

   输入:对于训练数据集 T={(x1 , y1) , (x2, y2) , (x3 , y3) ,,,,,,,(xn , yn) } , xi 是n维实数域上的特征向量,yi 属于 {c1 , c2 , c3 ,,,,,,cn}  i = 1.2.3....N ; 实例特征向量 x

   输出:实例x所属的类y

   1. 根据给定的距离度量,对于当前实例 ,计算训练数据集中前k 的点,将涵盖这k个点的邻域表示为Nk(x)

   2. 对于Nk(x)中的点的类别进行统计,找到类数量最大的类,从未确定实例x的类别  


代码的实现如下 :

# -*- coding: utf-8 -*-
"""
Created on Wed Apr 13 14:04:48 2016

@author: CC
"""
from numpy import *
import operator

def createDataSet():
    group = array([[1.0,1.1] , [1.0,1.0] , [0,0] , [0,0.1]])
    labels = ['A' , 'A' , 'B', 'B']
    return group , labels
#验证
#print createDataSet()
    
def classify(inX, dataset , labels, k):
    #距离的计算
    dataSize = dataset.shape[0]
    diff = tile(inX , (dataSize , 1)) - dataset
    sqDiff = diff ** 2
    print sqDiff
    sqDistance = sqDiff.sum(axis = 1)
    distance = sqDistance**0.5
    sortedDistanceIndicies = distance.argsort()
    #进行选择
    countLables = {}
    for i in range(k):
        label = labels[sortedDistanceIndicies[i]]
        countLables[label] = countLables.get(label , 0 ) + 1
    sortedCountLables = sorted(countLables.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedCountLables[0][0]
            

if __name__ == '__main__':
    group,labels = createDataSet();
    print classify([0,0] , group , labels, 3) 



常见问题

1、k值设定为多大?
k太小,分类结果易受噪声点影响;k太大,近邻中又可能包含太多的其它类别的点。
k值通常是采用交叉检验来确定(以k=1为基准)
经验规则:k一般低于训练样本数的平方根

2、类别如何判定最合适?
投票法没有考虑近邻的距离的远近,距离更近的近邻也许更应该决定最终的分类,所以加权投票法更恰当一些。

3、如何选择合适的距离衡量?
高维度对距离衡量的影响:众所周知当变量数越多,欧式距离的区分能力就越差。
变量值域对距离的影响:值域越大的变量常常会在距离计算中占据主导作用,因此应先对变量进行标准化。

4、训练样本是否要一视同仁?
在训练集中,有些样本可能是更值得依赖的。
可以给不同的样本施加不同的权重,加强依赖样本的权重,降低不可信赖样本的影响。

5、性能问题?
KNN是一种懒惰算法,平时不好好学习,考试(对测试样本分类)时才临阵磨枪(临时去找k个近邻)。
懒惰的后果:构造模型很简单,但在对测试样本分类地的系统开销大,因为要扫描全部训练样本并计算距离。
已经有一些方法提高计算的效率,例如压缩训练样本量等。

6、能否大幅减少训练样本量,同时又保持分类精度?
浓缩技术(condensing)
编辑技术(editing)





随着博客数量的提升,希望继续加油,提高博客的质量



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值