关键词:分类·监督学习 原理:基于特征距离的最相近样本的等权重投票制。 简单来讲:存在一个样本数据集合(训练集),样本中的每一条数据都存在一个标签(所属分类)。预测数据集合是仅有特征数据没有标签的数据集合。 对于预测集的每一条数据,我们均可以将其与样本集合中的数据在特征空间进行距离计算,挑选出与之距离最相近的K个样本数据。然后这K个 样本数据中,出现次数最多的分类即为我们要预测的那个分类。 优缺点:显而易见,计算的时间复杂度与空间复杂度均较高,并且无法理解数据的内在含义。
函数名称: classify0(intX,dataSet,labels,k) 函数说明: kNN 实现分类 输入参数: intX : 预测数据(特征向量) : list dataSet : 训练集(特征向量集) : array labels : 训练集对应的标签(类型向量) : list k : 投票个体数 : int 返回参数: 预测结果:最有可能的分类 : str
def classify0(intX,dataSet,labels,k):
#计算距离(此处采用的是欧式距离)
dataSetSize = dataSet.shape[0]
diffMat = tile(intX,(dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis = 1)
distances = sqDistances**0.5
#选择距离最小的K个点
sortedDistIndicies = distances.argsort()
classCount = {}
for i in range(k):
voteILabel = labels[sortedDistIndicies[i]]
classCount[voteILabel] = classCount.get(voteILable,0) + 1
#排序
sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
测试时,难免会用到一些复用性较高的函数(模块)来提高效率。 比如,针对classify0中的dataSet和labels,我们可以编写模块来从数据源读取。当然在前期较简单的方式如下: #kNN.py from numpy import * import operator def createDataSet(): featureVecSet = array([[1,0],[0,1],[0,0]]) labels = ['A','B','C'] return featureVecSet,labels 当我们需要测试时,可以这样: import kNN dataSet,labels = kNN.createDataSet() ………………………… ------------------------------------------------------------------------------------------------------------------------------
将特征数据(一般是保存在文本中的)输入分类器之前,必须将其格式化为可接受的形式。 def file2matrix(filename): #获取文件行数 fr = open(filename) arrayOLines = fr.readlines() numberOfLine = len(arrayOLines) #创建返回特征集合矩阵(N为特征数,硬编码) returnMat = zeros((numberOfLine,N)) #创建返回分类向量 classLabelVector = [] index = 0 for line in arrayOLines: line = line.strip() listFromLine = line.split('\t') returnMat[index,:] = listFromLine[:,N] classLabelVector.append(int(listFromLine[-1])) index += 1 return returnMat,classLabelVector ------------------------------------------------------------------------------------------------------------------------------
在处理”距离“时,一定要注意数据归一化的问题。因为不同特征的取值范围是不一样的。 比如: Feature1的范围[0,1] Feature2的范围[0,1000],若不进行归一化处理,Feature2对结果造成的影响远远大于Feature1。 通常采用的方法,将范围处理为0到1(或者-1到1)之间。下面给出一种处理为 0到1 的方案: newValue = (oldValue - minValue) / (maxValue - minValue) 下面给出实现代码: def autoNorm(dataSet): minVals = dataSet.min(0) maxVals = dataSet.max(0) ranges = maxVals - minVals normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet - tile(minVals,(m,1)) normDataSet = normDataSet/tile(ranges,(m,1)) return normDataSet, ranges, minVals
Welcome to contact me,the friends who like Machine-Learning and Data-Mining.
02 Nov 2014