k-近邻算法

目录

1、k-近邻算法

概述

原理

基本流程

优缺点

2、距离公式

欧氏距离(Euclidean Distance)

曼哈顿距离(Manhattan Distance)

​3、应用实例

4、小结


1、k-近邻算法

概述

简单来说,k-近邻算法即采用测量不同特征值之间的距离方法来进行分类。

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

原理

KNN 的原理就是当预测一个新的值 x 的时候,根据它距离最近的 K 个点是什么类别来判断 x 属于哪个类别。

例:

图中蓝色正方形,红色三角形分别为两种类别

我们想要预测绿点x为什么类别。

假设k=3,如图实线圆圈圈出了与绿点最近的3个点,三点中红色三角形最多,我们可以把该绿点归为红色三角形。

当我们假设k=5时,如图虚线圆圈圈出了与绿点最近的5个点,五点中蓝色正方形最多,那么我们就可以把该绿点归为蓝色正方形。

基本流程

(1)收集数据:可以使用任何方法。
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式。
(3)分析数据:可以使用任何方法。
(4)训练算法:此步骤不适用于k-近邻算法。
(5)测试算法:计算错误率。    
(6)使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

优缺点

优点:算法简单,易于实现,因为算法的复杂性并不高。 精度高、对异常值不敏感、无数据输入假定。

缺点:参数量少,训练 KNN 算法时唯一需要的参数是 k 的值和我们想从评估指标中选择的距离度量的选择。 计算复杂度高、空间复杂度高。适用数据范围:数值型和标称型。

2、距离公式

欧氏距离(Euclidean Distance)

​ 欧氏距离是最常见的距离度量,衡量的是多维空间中两个样本点之间的绝对距离。

曼哈顿距离(Manhattan Distance)

红线代表曼哈顿距离,绿色代表欧氏距离,也就是直线距离,而蓝色和黄色代表等价的曼哈顿距离。曼哈顿距离一一两点在南北方向上的距离加上在东西方向上的距离。

3、应用实例

import numpy as np
import operator
'''
函数说明: 创建数据集
Returns:
group - 数据集
labels - 分类标签
'''
def createDataSet():
    group=np.array([[1,101],[5,89],[108,5],[115,8]]) #数据集,四组二维特征
    labels=['爱情片','爱情片','动作片','动作片'] #分类标签,四组特征的标签
    return group,labels
 
"""
函数说明:kNN算法,分类器
Parameters:
inX - 用于分类的数据(测试集)
dataSet - 用于训练的数据(训练集)
labes - 分类标签
k - kNN算法参数,选择距离最小的k个点
Returns:
sortedClassCount[0][0] - 分类结果
"""
def classify0(inX, dataSet, labels, k):
    # numpy函数shape[0]返回dataSet的行数
    dataSetSize = dataSet.shape[0]
    # b = tile(a,(m,n)):即是把a数组里面的元素复制n次放进一个数组c中,然后再把数组c复制m次放进一个数组b中
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    # 二维特征相减后平方
    sqDiffMat = diffMat ** 2
    # sum()所有元素相加,sum(0)列相加,sum(1)行相加
    sqDistances = sqDiffMat.sum(axis=1)
    # 开方,计算出距离
    distances = sqDistances ** 0.5
    # 返回distances中元素从小到大排序后的索引值
    sortedDistIndices = distances.argsort()
    # 定一个记录类别次数的字典
    classCount = {}
    for i in range(k):
        # 取出前k个元素的类别
        voteIlabel = labels[sortedDistIndices[i]]
        # dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。
        # 计算类别次数
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    # python3中用items()替换python2中的iteritems()
    # key=operator.itemgetter(1)根据字典的值进行排序
    # key=operator.itemgetter(0)根据字典的键进行排序
    # reverse降序排序字典
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    # 返回次数最多的类别,即所要分类的类别
    return sortedClassCount[0][0]
 
 
if __name__ == '__main__':
    # 创建数据集
    group, labels = createDataSet()
    # 测试集
    test = [101, 20]
    # kNN分类
    test_class = classify0(test, group, labels, 3)
    # 打印分类结果
    print(test_class)

运行结果:

4、小结

1、k-近邻算法使用起来方便快捷,但对k值要求较高,一般而言,随着的逐渐增大,K近邻算法的分类效果会逐渐提升;但在增大到某个值后,随着的进一步增大,K近邻算法的分类效果会逐渐下降。所以说,k值的选择十分重要。

2、我们在使用k-近邻算法时,必须要确保有接近实际数据的训练样本,避免误差过大。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值