一只菜鸡的KNN入门

1、算法核心理论:

  1. 欧式距离计算公式  :         d = \sqrt{(xA - xB)^{}2 + (xA_{1} - xB_{1})^{2}},计算测试样本与训练样本之间的距离,维度越多,根号下的算式越多。
  2. 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个最小值,并按照频次进行从大到小排序,取频次最高值对应标签,即为测试数据对应类别。

  3. 若数据集中部分维度值过大,且实际业务中此维度值与其他维度重要性同等,则会造成距离计算偏差,故需要进行归一化操作:

    # 归一化操作
    
    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算法优点在于精确度高,对异常值不敏感,无数据输入假定,但缺点同样明显,若数据集及维度均较大,则计算量过大,无法给出数据集的典型样本和平均特征。

猜你喜欢

转载自blog.csdn.net/Oldog_1991/article/details/81185066
今日推荐