机器学习之三:Knn

1、原理
    给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。
2、步骤
(1).计算新实例和训练样本中每个样本点的距离(常见的距离度量有欧式距离,马氏距离,曼哈顿距离等);
(2)对上面所有的距离值进行排序;
(3)选前k个最小距离的样本;
(4)根据这k个样本的标签进行投票,得到最后的分类类别;
      如何选择一个最佳的K值,这取决于数据。一般情况下,在分类时较大的K值能够减小噪声的影响。但会使类别之间的界限变得模糊。一个较好的K值可通过各种启发式技术来获取,比如,交叉验证。另外噪声和非相关性特征向量的存在会使K近邻算法的准确性减小。
3、公式描述
输入:训练数据集

T={(x1,y1),(x2,y2),...,(xn,yn)}

  其中, xiRn 为实例的特征向量, yi{c1,c2,c3,...,ck} 为实例的类别,i=1,2,3..,n
输出:实例x所属的类y
(1)根据给定的距离度量,在训练集T中找出与x最临近的k个点,涵盖这k个点的x的邻域记做 Nk(x)
(2)在 Nk(x) 中根据分类决策规则(如多数表决)决定x的类别y:
y=argmaxxiNk(x)I(yi=cj),i=1,2,3...,n,j=1,2,3...,n

    其中 I 为指示函数,即当yi=cj I 为1,否则I为0。
KNN算法的优点:
  1. 思想简单,理论成熟,既可以用来做分类也可以用来做回归;
  2. 可用于非线性分类;
  3. 训练时间复杂度为O(n);
  4. 准确度高,对数据没有假设,对outlier不敏感;
缺点:
  1. 计算量大;
  2. 样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);
  3. 需要大量的内存;
4、代码实现
(1)手动编写knn分类器

import numpy as np

# 创建数据集,包含四个实例和两个分类 
def createDataSet():      
      group = np.array([[1.0, 0.9], [1.0, 1.0], [0.1, 0.2], [0.0, 0.1]])  
      labels = ['A', 'A', 'B', 'B'] 
      return group, labels  

# 用KNN进行分类 
def kNNClassify(newInput, dataSet, labels, k):  
      numSamples = dataSet.shape[0] # shape[0]代表行数,这里为样本点个数      
    ## step 1: 计算欧式距离       
       # >行数=原来*numSamples,列数=原来*1 
       # >然后每个特征点和样本的点进行相减,返回一个矩阵       
      diff = np.tile(newInput, (numSamples, 1)) - dataSet     
      squaredDiff = diff ** 2 
        # axis=0 按列求和,1为按行求和,行向量分别相加,从而得到新的一个行向量
      squaredDist = np.sum(squaredDiff, axis = 1) # 每一列分别求和,得到行向量    
      distance = squaredDist ** 0.5     
        ## step 2: 对距离按大小逆序排序    
      sortedDistIndices =np.argsort(distance)  #返回的是数组元素值从小到大的索引值  
      classCount = {} # 定义一个元组,用于存距离最近的K个点中,点所属的每个类出现的次数
      for i in xrange(k):  
            ## step 3: 在距离中选择最小K个距离  
          voteLabel = labels[sortedDistIndices[i]]   
            # step 4: 计算标签发生的概率  
            #  get()函数返回指定键的值,如果值不在字典中返回默认值0。            
          classCount[voteLabel] = classCount.get(voteLabel, 0) + 1  
          ## step 5: 最大的类将会被返回 
     maxCount = 0  
     for key, value in classCount.items():  
        if value > maxCount:  
            maxCount = value  
            maxIndex = key    
     return maxIndex   
if __name__ == '__main__':
       dataSet, labels = createDataSet()    
       testX = np.array([1.2, 1.0])  
       k = 3  
       outputLabel = kNNClassify(testX, dataSet, labels, 3)  
       print "Your input is:", testX, "and classified to class: ", outputLabel        
       testX = np.array([0.1, 0.3])  
       outputLabel = kNNClassify(testX, dataSet, labels, 3)  
       print "Your input is:", testX, "and classified to class: ", outputLabel

(2)调用框架中的工具实现Knn分类器

import numpy as np
from sklearn.neighbors import KNeighborsClassifier  

group = np.array([[1.0, 0.9], [1.0, 1.0], [0.1, 0.2], [0.0, 0.1]])  
labels = ['A', 'A', 'B', 'B'] 
knn = KNeighborsClassifier(n_neighbors=3)   # k值设置为3
knn.fit(group, labels)  
print(knn.predict([[0.1, 0.3]])) # 预测值  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值