K-NN近邻算法详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/super_YC/article/details/83418634

 K-近邻算法属于一种监督学习分类算法,该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

 (1) 需要进行分类,分类的依据是什么呢,每个物体都有它的特征点,这个就是分类的依据,特征点可以是很多,越多分类就越精确。

 (2) 机器学习就是从样本中学习分类的方式,那么就需要输入我们的样本,也就是已经分好类的样本,比如特征点是A , B2个特征,输入的样本甲乙丙丁,分别为[[1.0, 1.1], [1.0, 1.0], [5.0, 1.1], [5.0, 1.0]]。 那么就开始输入目标值,当然也要给特征了,最终的目标就是看特征接近A的多还是B的多,如果把这些当做坐标,几个特征点就是几纬坐标,那么就是坐标之间的距离。那么问题来了,要怎么看接近A的多还是B的多。

工作原理:存在一个样本数据集合,也称为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。

#!/usr/bin/env python 
# -*- coding:utf-8 -*-

# 科学计算包
import numpy
# 运算符模块
import operator

# 数据样本和分类模拟
# 手动建立一个数据源矩阵group 和数据源的分类结果labels
def createDataSet():
    group = numpy.array([[1.0, 1.1], [1.0, 1.0], [5.0, 1.1], [5.0, 1.0]])
    lables = ['A', 'A', 'B', 'B']
    return group, lables

# 进行KNN 算法
# newInput为输入的目标,dataSet是样本的矩阵,labels是分类,k是需要取的个数
def kNNClassify(newInput, dataSet, lables, k):
    # 读取矩阵的行数,也就是样本数量
    numSamples = dataSet.shape[0]
    print("numSamples = ", numSamples)

    # 变成和dataSet一样的行数,行数 = 原来 * numSamples,列数 = 原来 * 1,然后每个特征点和样本的点进行相减
    # (numSamples, 1)表示矩阵newInput变为三维,重复次数一次
    diff = numpy.tile(newInput, (numSamples, 1)) - dataSet
    print("diff = ", diff)

    # 平方
    squaredDiff = diff ** 2
    print("squaredDiff = ", squaredDiff)

    # axis = 0 按列求和,axis = 1 按行求和
    squaredDist = numpy.sum(squaredDiff, axis=1)
    print("squaredDist = ", squaredDist)

    # 开根号,计算距离
    distance = squaredDist ** 0.5
    print("distance = ", distance)

    # 按大小逆序排序
    sortedDistIndices = numpy.argsort(distance)
    print("sortedDistIndices = ", sortedDistIndices)

    classCount = {}
    for i in range(k):
        # 返回距离(key)对应类别(value)
        voteLabel = labels[sortedDistIndices[i]]
        print("voteLabel = ", voteLabel)

        if voteLabel in classCount.keys():
            value = classCount[voteLabel]
            classCount[voteLabel] = value + 1
        else:
            classCount[voteLabel] = 1

    print("classCount: ", classCount)
    # 返回占有率最大的
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    print("sortedClassCount = ", sortedClassCount)

    return sortedClassCount[0][0]

if __name__ == '__main__':
    dataSet, labels = createDataSet()

    testX = numpy.array([0, 0])
    k = 3
    outputLabel = kNNClassify(testX, dataSet, labels, k)
    print("Your input is:", testX, "and classified to class: ", outputLabel)


总结:K-近邻算法是分类数据中最简单最有效的算法,是基于实例的学习,使用算法时我们必须要有接近实际数据的训练样本数据。K-近邻算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。此外,由于必须对数据集中的每个数据计算距离值,实际使用时可能非常耗时;

          k-近邻算法的另一个缺陷是让无法给出任何数据的基础结构信息,因此我们也无法知晓平均实例样本和典型实例样本具有什么特征。         

猜你喜欢

转载自blog.csdn.net/super_YC/article/details/83418634