前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >KNN (K 邻近)分类算法

KNN (K 邻近)分类算法

作者头像
caoqi95
发布2019-03-27 17:52:05
1.2K0
发布2019-03-27 17:52:05
举报

最近看到一个很火的 100-Days-Of-ML-Code 的活动,在 Github 上看了下每日的学习内容,发现是个很好的查漏补缺的列表。这个学习列表里面包含机器学习,深度学习,统计学,线性代数等内容。KNN 是第 7 天的学习内容。

什么是 KNN?

KNN,K-Nearest Neighbours ,K值邻近算法,是一个简单的,常被用于分类问题的算法。它也可以用于回归问题。

KNN 是非参数的(non-parametric),基于实例(instance-based)的算法。非参数意味着其不在底层的数据分布上进行任何的臆测。而基于实例意味着其不是明确地学习一个模型,而是选择记忆训练的实例们。

KNN is non-parametric(means that it does not make any assumptions on the underlying data disturbution),instance-based(means that our algorithm doesnt explicitly learn a model.instead,it choose to memorize the training instances.) and used in a supervised learning setting.

由于 KNN 是基于实例的算法,也常被称呼为懒算法(lazy algorithm)。了解了下面 KNN 的原理,也就知道为什么它会被称为 lazy algorithm。:)

KNN 算法原理

当 KNN 被用于分类问题时,其输出是一个类别的成员(预测一个类别 - 一个离散值) 该算法包含三个元素:标记对象的集合(比如:一个分数记录的集合),对象之间的距离,k 的取值,即最邻近距离的数量。

如上图所示,这是一个小例子。我们将要把灰色的点分类为亮绿色,绿色,棕色中的一类。一开始会计算灰色点与其他各个点的之间的距离,然后再找出 k 值 - 最邻近的一些点。

最邻近的点的数据按顺序如上所示,会发现亮绿色包含两个点,绿色包含一个点,棕色也包含一个点。亮绿色的个数最多,所以灰色的点被划分为亮绿色所在的类。可以发现 KNN 是通过测量不同样本之间的距离进行分类的。KNN 算法的核心思想是:如果一个样本在特征空间中的 k 个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别。

距离公式

其中最常见的计算各点之间的方法是欧氏距离(Euclidean Distance)。欧氏距离就是计算 N 维空间中两点之间的距离。

其他常用的方法还有:

  • 汉明距离(Hamming Distance)
  • 曼哈顿距离 (Manhattan Distance)
  • 闵可夫斯基距离(Minkowski Distance)

k 的取值

k 的取值并非容易。k 值取小的话,意味着数据噪音将会在结果上有很大的影响。k 值取大的话,将会使计算成本很大。k 的取值很大程度上也依赖于个人遇到的问题。如何取得更好的 k 值,将由自己来衡量。

简单 KNN 分类实践

此实践教程来源:机器学习实战教程(一):K-近邻算法(史诗级干货长文)

我们实践一个简单的例子,用 KNN 来分类一个电影是动作片还是爱情片。下面是关于电影数据的说明。这个数据集有两个特征,即打斗镜头数和接吻镜头数。除此之外,我们也知道每个电影的所属类型,即分类标签。用肉眼粗略地观察,接吻镜头多的,是爱情片。打斗镜头多的,是动作片。

电影数据说明

下面就是用 KNN 算法来写一个电影分类器的过程:

代码语言:javascript
复制
import numpy as np
import operator

"""
函数说明:创建数据集

Params:
    无
Returns:
    group - 数据集
    labels - 分类标签
"""
def createDataset():
    # 四组二维特征
    group = np.array([[1, 101], [5, 89], [108, 5], [115, 8]])
    # 四组特征标签
    labels = ['爱情片', '爱情片', '动作片', '动作片']
    return group,labels

"""
函数说明:KNN算法,分类器

Params:
    inX - 用于分类的数据(测试集)
    dataSet - 用于训练的数据(训练集)
    labels - 分类标签
    k - KNN算法参数,选择距离最小的 k 个点
Returns:
    sortedClassCount[0][0] - 分类器结果
"""

def classify0(inX, dataset, labels, k):
    # numpy 函数shape[0]返回dataSet 的行数
    datasetSize = dataset.shape[0]
    # 在列向量方向上重复 inX 共 1 次(横向),行向量方向上重复 inX 共 dataSize 次(纵向)
    diffMat = np.tile(inX, (datasetSize,1)) - dataset
    # 二维特征相减后平方
    sqDiffMat = diffMat**2
    # sum() 所有元素相加,sum(0)列相加,sum(1)行相加
    sqDistances = sqDiffMat.sum(axis=1)
    # 开方,计算距离
    distances = sqDistances**0.5
    # 返回 diatances 中元素从小到大排序后的索引值
    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
    
    # key=operator.itemgetter(1)根据字典的值进行排序
    # key=operator.itemgetter(0)根据字典的键进行排序
    # reverse降序排序字典
    #print(classCount)
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    # 返回次数最多的类别,即所有分类的类别
    #print(sortedClassCount)
    return sortedClassCount[0][0]
代码语言:javascript
复制
group, labels = createDataset()
test = [10, 202]
# KNN 分类
test_class = classify0(test, group, labels, 3)
# 打印结果
print(test_class)
代码语言:javascript
复制
爱情片

参考: [1]. K Nearest Neighbours | Day 7 - 100 Days of ML Code [2]. 机器学习(一)——K-近邻(KNN)算法

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.08.19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 KNN?
  • KNN 算法原理
  • 距离公式
  • k 的取值
  • 简单 KNN 分类实践
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档