k近邻法最简单的实现方法-线性扫描

k近邻法的原理在这就不再多说,可以参考李航老师的《统计学习方法》(第2版),这里直接展示用python实现k近邻最简单的实现方法-线性扫描。

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
    # K近邻法线性扫描方法的实现,该方法在训练集很大时,计算会非常耗时,这种情况下是不适合采用该方法的
    # 实现步骤:
    # 1.计算输入实例与每一个训练实例的距离;
    # 2.对以上距离按照递增次序进行排序;
    # 3.选取合适的k值;
    # 4.确定与该输入实例最邻近的k个实例的类别的出现频数;
    # 5.返回这k个类别中出现频数最多的类别,作为该输入实例的类别
"""
import numpy as np
import operator

def KNN_liner_scan(inputExample, dataSet, category, k):
    """
    :param inputExample: 输入的实例
    :param dataSet: 训练数据集
    :param category: 分类类别
    :param k: k值
    :return: 输入实例的类别
    """
    dataSetSize = dataSet.shape[0]  # 训练数据集的个数
    """
      # 接着计算输入实例与各训练集之间的差值(为下一个的距离度量做准备)
      # 通过numpy.tile(A, reps)给定重复次数来构造与训练实例数组一样大小的数组,用于差值计算
    """
    differenceValue = np.tile(inputExample, (dataSetSize, 1)) - dataSet
    squareDifferenceValue = differenceValue ** 2
    rowSumValue = squareDifferenceValue.sum(axis=1)     # 将每行的平方距离数据求和,输入空间为n维向量
    euclideanDistance = rowSumValue ** 0.5      # 距离度量采用欧式距离,计算输入实例与各训练集数据的欧式距离,作为距离度量。
    sortedEuclideanDistanceIndices = euclideanDistance.argsort()    # 将欧式距离进行排序(从小到大)之后,返回对应的在原来数组中的索引,方便为下一步获取类别
    categoryInfo = {}      # 用于统计这k个实例的类别出现的频数
    for i in range(k):
        kExampleCategory = category[sortedEuclideanDistanceIndices[i]]  # 获取这k个实例对应的类别
        categoryInfo[kExampleCategory] = categoryInfo.get(kExampleCategory, 0) + 1  # 统计各类别出现的频数

    # 对各类别出现的频数进行降序排序
    sortCategoryInfo = sorted(categoryInfo.items(), key=operator.itemgetter(1), reverse=True)
    return sortCategoryInfo[0][0]       # 采用多数表决,返回出现频数最大的类别

def createDataSet():
    # 创建测试数据
    dataSetTest = np.array([
        [1.1, 1.2],
        [1.4, 2.0],
        [2.1, 2.2],
        [1.8, 1.6],
        [2.9, 3.0],
        [5.0, 2.5]
    ])
    categoryTest = ['a1', 'b2', 'a1', 'b4', 'a1', 'd1']
    return dataSetTest, categoryTest

# 获取创建数据
dataSet, category = createDataSet()
predictCategory = KNN_liner_scan([1.3, 1.9], dataSet, category, 2)
print('category of [1.3, 1.9]:', predictCategory)


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值