k-临近算法

工作原理:

  1.假设一个带有标签的样本数据集(训练样本集),其中每条数据与其分类有对应关系。
  2.输入没有标签的新数据后,将新数据中的每个特征与样本数据集中的每个特征进行比较。
    2.1 计算新数据与样本数据集中的每条数据的距离。
    2.2 对求得的每个距离进行排序(从小到大排序)
    2.3 取前k个样本数据的分类标签。
  3.取前k个数据中出现次数最多的分类标签作为新数据的分类。

通俗理解:

  给定训练样本集,对于新输入实例,在训练样本集中找到与该实例最接近的k个实例,这k个实例中多数属与某个类,就把该输入实例分为这个类。

代码实现:

# !/usr/bin/env python3
# -*- coding: utf-8 -*-
from numpy import *
import operator  # 运算符


def createDataSet():
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels


def classify0(inX, dataSet, labels, k):
    '''
    k-临近算法
    :param inX: 用于分类的输入向量
    :param dataSet: 输入的训练样本集
    :param labels: 标签向量
    :param k: 用于选择最近邻居的数目
    :return: 发生频率最高的元素标签
    '''
    dataSetSize = dataSet.shape[0]  # dataSet行数
    # 使用欧氏距离公式,计算两个向量点之间的距离 -- start
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet  # 将inX纵向复制 后减dataSet
    sqDiffMat = diffMat ** 2  #
    sqDistances = sqDiffMat.sum(axis=1)  # 每一行相加
    distances = sqDistances ** 0.5  # 开根号  [ 1.48660687  1.41421356  0.          0.1       ]
    # -- end
    sortedDistIndicies = distances.argsort()  # 将数组按照从小到大的顺序排序,并按照对应的索引值输出  [2 3 1 0]
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1  # get返回指定键的值,如果值不在字典中返回默认值
    # sorted 可以对所有可迭代的对象进行排序操作 ;operator.itemgetter(1) 指定取待排对象的第1个域进行排序
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]


if __name__ == '__main__':
    group, labels = createDataSet()
    classify0([0, 0], group, labels, 3)

  PS:欧氏距离公式,计算两个向量点xA和xB之间的距离:
    
  例如,点(0,0)与(1,2)之间的距离计算为:
          

posted @ 2020-06-08 16:17  六神酱  阅读(238)  评论(0编辑  收藏  举报