KNN(K近邻)——原理及算法实现

01 基本原理

给定一个数据集,对于新的输入实例,在训练集中找到与该实例最邻近的K个实例,这K个实例中的大多数属于某个类别,则认为该输入实例就属于某个类别。

02 优缺点

优点:易于实现,无需估计参数,无需训练,支持增量学习
缺点:计算量大,分析速度慢(需要扫描全部训练样本并计算距离)

03 KNN的三要素

1.距离度量:衡量特征空间中两个实例点的距离
2.K值得选择:K值过小,近似误差减小,估计误差变大,易于过拟合,噪声敏感。K值过大,近似误差变大,估计误差变小。
3.决策规则:多数表决法,也可以用加权表决法,权重为距离平方的倒数。

04 优化计算量

由于需要计算全部特征距离,计算量过大,可以采用二叉树的数据存储方式减少计算量。

05 构建KNN分类器基本步骤

1.计算输入X与训练数据集中的各点的距离。
2.按照距离,选取距离最近的K个点。
3.对K个点的类别归类计数,x归为计数最大的类(加权表决)
4.或者对K个点的类别按权值归类计数,x归为计数大的类。

06 自定义KNN分类器代码

# newInput: 新输入的待分类数据(x_test),本分类器一次只能对一个新输入分类
# dataset:输入的训练数据集(x_train),array类型,每一行为一个输入训练集
# labels:输入训练集对应的类别标签(y_train),格式为['A','B']而不是[['A'],['B']]
# k:近邻数
# weight:决策规则,"uniform" 多数表决法,"distance" 距离加权表决法
import numpy as np
def KNNClassify(newInput, dataset, labels, k, weight):
    numSamples = dataset.shape[0] #获取数据集的第一列维数

    diff = np.tile(newInput, (numSamples, 1)) - dataset  # 将输入实例按列方向复制numSamples倍,然后与训练数据集做差
    squaredist = diff ** 2 #将差值平方
    distance = (squaredist.sum(axis=1)) ** 0.5  # axis=1,按行累加,再开平方根
    sortedDistance = distance.argsort() # 对数组distance按升序排序,返回数组排序后的值对应的索引值
    classCount = {}  # 定义一个空字典,存放k个近邻点的分类计数
    for i in range(k):
        votelabel = labels[sortedDistance[i]] # 第i个近邻点在distance数组中的索引,对应的分类
        classCount[votelabel] = classCount.get(votelabel, 0) + 1
        # votelabel作为字典的key,对相同的key值累加(多数表决法)初始值为0,若下一次还是为此标签,则加一,达到计数的目的。后面为权值
        break

    # 对k个近邻点的分类计数按降序排序,返回得票数最多的分类结果
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    #sorted():reverse=turn 表示降序排列
    #reverse=False 表示升序排列
    print("新输入到训练集的最近%d个点的计数为:" % k, "\n", classCount)
    print("新输入的类别是:", sortedClassCount[0][0])

    return sortedClassCount[0][0]

#该函数返回降序 排列后的第一个值,即该实例的类别。局限性是一次只能预测一个实例。

你可能感兴趣的:(机器学习)