k近邻算法简单,直观:给定一个训练数据集,对新的输入实例,在训练集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。k近邻不需要像LR一样去训练。
K近邻模型由三个基本要素组成:距离度量,k值选择,分类决策规则
距离度量
一般采用欧式距离
k值选择
k值得选择会对k近邻算法的结果产生重大影响。
如果选择的k值较小,就相当于用较小的的邻域中的训练实例进行预测。此时预测的结果会对近邻的实例点非常敏感。
如果选择较大的k值,就相当于在较大的邻域中训练实例进行预测。此时,与输入实例较远的训练实例也会对预测起作用,使预测发生错误。
如果k等于训练样本个数,此时将输入实例简单的预测为训练样本中最多的类。这时模型过于简单,会完全忽略训练样本中的大量有用信息,是不可取的。
在应用中,k值一般选取一个比较小的数值,通常采用交叉验证法来选取最优的k值。
优缺点
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
适用数据范围:数值型和标称型。
分类决策规则
k近邻算法中分类决策规则往往是多数表决,即由输入实例的k个邻近的训练实例中的多数类决定输入实例的类
代码
该章节所有代码可参考这
数据格式
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
对未知类别属性的数据集中的每个点依次执行以下操作:
(1)计算已知类别数据集中的点与当前点之间的欧式距离;
(2)按照距离递增次序排序;
(3)选取与当前点距离最小的k个点;
(4)确定前k个点所在类别的出现频率;
(5)返回前k个点出现频率最高的类别作为当前点的预测分类。
附:
numpy-tile
numpy-argsort
from numpy import *
import operator
def classify0(inX, dataSet, labels, k):
#步骤1
dataSetSize = dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
#步骤2
sortedDistIndicies = distances.argsort()
classCount={}
#步骤3、4
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#步骤5
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
执行预测分类
>>> group,labels = createDataSet()
>>> classify0([0,0], group, labels, 3)