路漫漫其修远兮,希望不要漏洞百出,记录一下。
1、算法核心理论:
- 欧式距离计算公式 : ,计算测试样本与训练样本之间的距离,维度越多,根号下的算式越多。
-
def classify0(testsamp,trainsamp,labels,K): trainsize = trainsamp.shape[0] diff = tile(testsamp,(trainsize,1)) - trainsamp sqdiff = diff ** 2 sum = sqdiff.sum(1) distance = sum ** 0.5 sortdistance = distance.argsort()# 根据值大小排序,返回值对应索引,方便下一步提取marks classmarks = {} for i in range(k): marks = labels[sortdistance[i]] # dict.get(x1,x2)函数,当x1键存在,获取x1的value,否则取x2;此处,若marks之前出现过,则取对应值,实现频次累加,若无,取0,进行累加 classmarks[marks] = classmarks.get(marks,0) + 1 sortclassm = sorted(classmarks.items(),key=operator.itemgetter(1),reverse=True) return sortclassm[0][0]
以上算法选取前K个最小值,并按照频次进行从大到小排序,取频次最高值对应标签,即为测试数据对应类别。
-
若数据集中部分维度值过大,且实际业务中此维度值与其他维度重要性同等,则会造成距离计算偏差,故需要进行归一化操作:
# 归一化操作 def transNorm(dataSet): minVals = dataSet.min(0) maxVals = dataSet.max(0) ranges = maxVals - minVals normSet = zeros(dataSet.shape) m = dataSet.shape[0] normSet = dataSet - tile(minVals,(m,1)) / tile(ranges,(m,1)) return nromSet, ranges, minVals
4、顺便记录一下文本解析到列表,生成数据集和标签:
def fileParse(filename): with open(filename) as fl: lines = fl.readlines() normSet = zeros((len(lines),k)) labels = [] index = 0 #用于生成新数据集 for line in lines(): newline = line.strip() normline = newline.split('\t') normSet[index,:] = normline[0:3] labels.append(int(normline[-1])) index += 1 return normSet, labels
5、KNN算法优点在于精确度高,对异常值不敏感,无数据输入假定,但缺点同样明显,若数据集及维度均较大,则计算量过大,无法给出数据集的典型样本和平均特征。