简单介绍
k近邻法可用于分类和回归,是最简单的机器学习方法,是懒惰学习的著名代表。
算法原理:给定一个训练数据集(类别确定),对于输入的实例,在训练数据集中寻找到与输入实例最接近的k个实例。k个实例中多数类别即为输入实例的类别。
算法三要素
由算法原理我们可以知道,实现这个算法我们需要明白,k值是多少,度量输入实例和训练实例的距离规则,以及我们对实例类别的判断规则是什么。这是我们必须要解决和明白的问题。
要素1—k值
k值过小:容易过拟合,模型复杂。(过拟合:在训练集上准确率高,在测试率上准确率低。学习很好,考试很差)
k值过大:模型过于简单,容易预判错误。
解决方法:交叉验证法
将训练集划分为两组,一组用于训练模型,另一组用于测试模型。改变两组数据的占比和k值,比较使模型准确率最高的k值。
要素2—度量距离
度量距离用于描述样本间的相似程度,简单来说就是计算样本间的距离的方式
要素3—分类决策规则
多采用表决,也可以基于距离进行加权投票。
Python代码实现
import numpy as np import operator from os import listdir ##电影分类 # #导入数据集 def createDataSet(): group = np.array([[179,42], [178, 43], [165, 36], [177, 42],[160,35]]) labels = ['男', '男', '女', '男','女'] # print(group) # print(labels) return group, labels def classify0(inX, dataSet, labels, k,min,ranges): inX=inX-min inX=inX/ranges dataSetSize = dataSet.shape[0] # print(dataSetSize) diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet ##测试数据矩阵化相减得到一个新的距离矩阵 # print(diffMat) sqDiffMat = diffMat**2 ##欧氏距离 # print(sqDiffMat) sqDistances = sqDiffMat.sum(axis=1) ##欧式距离 # print(sqDistances) distances = sqDistances**0.5 ##欧式距离--算得测试数据与每个练习数据的距离 # print(distances) sortedDistIndicies = distances.argsort() ##将距离降序排列得到它的数组序列 # print(sortedDistIndicies) classCount = {} for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1##计算k个最近距离的样本出现的标签数量 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) ##k个出现标签数量顺序排列 return sortedClassCount[0][0] #数据归一化 def autoNorm(dataSet): minVals = dataSet.min(0) #min(0)返回该矩阵中每一列的最小值 maxVals = dataSet.max(0) #max(0)返回该矩阵中每一列的最大值 ranges = maxVals - minVals # print(maxVals) # print(minVals) # print(ranges) normDataSet = np.zeros(np.shape(dataSet)) #准备新数组存放归一化后的数据 m = dataSet.shape[0] #返回数据的行数 normDataSet = dataSet - np.tile(minVals, (m, 1)) #把最小数据的一维数组化成与数据一样的矩阵,方便他们相减 normDataSet = normDataSet/np.tile(ranges, (m, 1)) #element wise divide # print(normDataSet) return normDataSet, ranges, minVals