KNN-K最近邻(k-NearestNeighbor)分类算法

K最近邻(kNN,k-NearestNeighbor)分类算法,见名思意:找到最近的k个邻居(样本),在前k个样本中选择频率最高的类别作为预测类别。

解释:

1)算距离:给定测试对象,计算它与训练集中的每个对象的距离 2)找邻居:圈定距离最近的k个训练对象,作为测试对象的近邻 3)做分类:根据这k个近邻归属的主要类别,来对测试对象分类

 

可借鉴的优点:

1)由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

2)该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。

缺点:

KNN算法缺点:

1)是懒散学习方法(lazy learning,基本上不学习),一些积极学习的算法要快很多。:没有训练阶段,数据集事先已有了分类和特征值,待收到新样本后直接进行处理

2)类别评分不是规格化的(不像概率评分)。

3)输出的可解释性不强,例如决策树的可解释性较强。

4)该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。

5)计算量较大。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本:新样本需要与数据集中每个数据进行距离计算,计算复杂度和数据集中的数据数目n成正比

 

for detail:

1)算距离:欧氏距离:x,y为2个样本,n为维度,xi,yi为x,y第i个维度上的特征值

代码实现步骤:

1)计算已知类别数据集中的点与当前点之间的距离 2)按距离递增次序排序 3)选取与当前点距离最小的k个点 4)统计前k个点所在的类别出现的频率 5)返回前k个点出现频率最高的类别作为当前点的预测分类

代码实现:


'''

KNN算法

'''
import numpy as np

def classify(intX,dataSet,labels,k):
#numpy中shape[0]返回数组的行数,shape[1]返回列数
    dataSetSize = dataSet.shape[0]
#将intX在横向重复dataSetSize次,纵向重复1次
#例如intX=([1,2])--->([[1,2],[1,2],[1,2],[1,2]])便于后面计算
    diffMat = np.tile(intX,(dataSetSize,1))-dataSet

#二维特征相减后乘方
    sqdifMax = diffMat**2

#计算距离
    seqDistances = sqdifMax.sum(axis=1)
    distances = seqDistances**0.5
    print ("distances:",distances)

#返回distance中元素从小到大排序后的索引
    sortDistance = distances.argsort()
    print ("sortDistance:",sortDistance)

    classCount = {}

    for i in range(k):

    #取出前k个元素的类别

        voteLabel = labels[sortDistance[i]]

        print ("第%d个voteLabel=%s",i,voteLabel)

        # dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。
        classCount[voteLabel] = classCount.get(voteLabel,0)+1

        #计算类别次数
        #key=operator.itemgetter(1)根据字典的值进行排序

        #key=operator.itemgetter(0)根据字典的键进行排序

        #reverse降序排序字典
        sortedClassCount = sorted(classCount.items(),key = operator.itemgetter(1),reverse = True)

        #结果sortedClassCount = [('动作片', 2), ('爱情片', 1)]

        print ("sortedClassCount:",sortedClassCount)

    return sortedClassCount[0][0]

代码解析:

python numpy.tile(A,reps) #简单理解是此函数将A进行重复输出:

计较常用的形式有两种,是将A简单进行一维重复输出,和将A进行二维重复后输出。

一维重复:

import numpy as np

a = [[1,2,3],[4,5,5]]

b = np.tile(a,3)

print(b)

#输出为

#[[1 2 3 1 2 3 1 2 3]

# [4 5 5 4 5 5 4 5 5]]

二维重复:

import numpy as np

a = [[1,2,3],[4,5,5]]

b = np.tile(a,[2,3])

print(b)

#输出为:

#[[1 2 3 1 2 3 1 2 3]

# [4 5 5 4 5 5 4 5 5]

# [1 2 3 1 2 3 1 2 3]

# [4 5 5 4 5 5 4 5 5]]

Python sorted() 函数:排序

sorted 语法:

sorted(iterable[, cmp[, key[, reverse]]])

参数说明:

  • iterable -- 可迭代对象。
  • cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
  • key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。

几个算例:

https://blog.csdn.net/saltriver/article/details/52502253

https://www.cnblogs.com/erbaodabao0611/p/7588840.html

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值