k-近邻算法(knn)

积微成著 积微成著     2022-08-04     396

关键词:

概述

简单地说,K-近邻算法(K-Nearest-Neighbors Classification)采用测量不同特征值之间的距离方法进行分类。

  • 优点:精度高、对异常值不敏感、无数据输入假定
  • 缺点:计算复杂度高、空间复杂度高
  • 使用数据范围:数值型和标称型
  • 工作原理:要确定测试样本属于哪一类,就寻找所有训练样本中与该测试样本“距离”最近的前K个样本,然后看这K个样本大部分属于哪一类,那么就认为这个测试样本也属于哪一类。简单的说就是让最相似的K个样本来投票决定。
  • 这里所说的距离,一般最常用的就是多维空间的欧式距离。这里的维度指特征维度,即样本有几个特征就属于几维。

近邻的距离度量表示法

  • 欧氏距离
  • 曼哈顿距离
  • 切比雪夫距离
  • 闵可夫斯基距离
  • 马氏距离
  • 巴氏距离

K值的选择

不要小看了这个K值选择问题,因为它对K近邻算法的结果会产生重大影响。如李航博士的一书「统计学习方法」上所说:

  • 如果选择较小的K值,就相当于用较小的领域中的训练实例进行预测,“学习”近似误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是“学习”的估计误差会增大,换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合;
  • 如果选择较大的K值,就相当于用较大领域中的训练实例进行预测,其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误,且K值的增大就意味着整体的模型变得简单。K=N,则完全不足取,因为此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的累,模型过于简单,忽略了训练实例中大量有用信息。
  • 在实际应用中,K值一般取一个比较小的数值,例如采用交叉验证法(简单来说,就是一部分样本做训练集,一部分做测试集)来选择最优的K值。

KNN算法的优缺点

优点

  • 理论成熟,思想简单,即可以用来做分类也可以用来做回归;
  • 可用于非线性分类;
  • 训练时间复杂度为O(n);
  • 对数据没有假设,准确度高,对outlier不敏感。

缺点

  • 计算量大;
  • 样本不平衡问题(即有些类别的样本数量很多,而其他样本数量很少);
  • 需要大量内存。

具体应用案

案例一

这里有4组数据,且(1,1.1)和(1,1)定义为A类,(0,0)和(0,0.1)为B类。下面对(0.5,0.5)进行分类,判断其为A、B哪一类。
算法过程:
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增次序排序;
(3)选取与当前点距离最小的K个点;
(4)确定前K个点所在类别的出现频率;
(5)返回前K个点出现频率最高的类别作为当前点的预测分类。

具体代码:

from numpy import *
import operator
from os import listdir

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5 #计算距离
    sortedDistIndicies = distances.argsort()     
    classCount={}          
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#选择距离最小的k个点
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]#排序

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

group,labels=createDataSet()
classify0([0.5,0.5],group,labels,3)

输出:

‘B‘

案例二:

  • 数据集介绍
    iris虹膜数据集,是一种植物,通常被用来作为机器学习的案例。该数据集中有150个实例,每个实例包含了花的四个维度,分别为萼片长度、宽度,花瓣长度、宽度。该花共有3种分类:iris setosa、iris versicolor、iris virginica。
  • 利用python的机器学习库sklearn:SKLearnExample.py
    该库中包含了很多机器学习的算法,如KNN。接下来我们介绍如何调用KNN的算法:
from sklearn import neighbors#导入包含KNN算法模块
from sklearn import datasets#导入数据集模块

knn = neighbors.KNeighborsClassifier()#调用分类器方法

iris = datasets.load_iris()#导入数据

print iris#分类规则:iris setosa、iris versicolor、iris virginica分别为用0、1、2表示

knn.fit(iris.data, iris.target)#建立模型

predictedLabel = knn.predict([[0.1, 0.2, 0.3, 0.4]])#预测新的对象属于哪一类

print predictedLabel

结果:

[0]

以上就是如何使用python里面的sklearn库来进行KNN算法的调用。
接下来介绍适合通过自己写程序来实现KNN的算法。

案例三

基本步骤:

  • 加载数据集;
  • 计算距离;
  • 返回最近的K个邻居;
  • 用“少数服从多数”的原则进行归类划分;
  • 测算预测值的准确率。
import csv#用于读取数据
import random
import math
import operator

#导入数据
def loadDataset(filename, split, trainingSet=[] , testSet=[]):#加载数据集
    with open(filename, ‘rb‘) as csvfile:#将filename导入为csv格式的文件。(‘rb’读写模式)
        lines = csv.reader(csvfile)#读取文件行数
        dataset = list(lines)#转化为list的数据结构
        for x in range(len(dataset)-1):
            for y in range(4):
                dataset[x][y] = float(dataset[x][y])
            if random.random() < split:#将数据分为两部分,分别加到训练集和测试集中
                trainingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])

#计算距离
def euclideanDistance(instance1, instance2, length):#传入两个实例及维度
    distance = 0
    for x in range(length):#所有维度距离的平方和
        distance += pow((instance1[x] - instance2[x]), 2)
    return math.sqrt(distance)

#返回最近的K个label
def getNeighbors(trainingSet, testInstance, k):#testInstance测试集中的一个数据
    distances = []#定义一个空的容器
    length = len(testInstance)-1
    for x in range(len(trainingSet)):#计算测试集(一个)到每一个训练集的距离
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))#将所有的距离放在定义好的空容器diastances
    distances.sort(key=operator.itemgetter(1))#距离从小到大排序
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
    return neighbors#返回最近的k个邻居

#对邻居进行分类,找出类别最多的
def getResponse(neighbors):
    classVotes = {}
    for x in range(len(neighbors)):
        response = neighbors[x][-1]
        if response in classVotes:
            classVotes[response] += 1
        else:
            classVotes[response] = 1
    sortedVotes = sorted(classVotes.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedVotes[0][0]

#计算正确率
def getAccuracy(testSet, predictions):
    correct = 0
    for x in range(len(testSet)):
        if testSet[x][-1] == predictions[x]:
            correct += 1
    return (correct/float(len(testSet))) * 100.0

def main():
    # prepare data
    trainingSet=[]#创建两个空的测试集和训练集
    testSet=[]
    split = 0.67#将2/3的数据划分为训练集,1/3划分为测试集
    loadDataset(r‘/home/duxu/exercise/iris.csv‘, split, trainingSet, testSet)
    print ‘Train set: ‘ + repr(len(trainingSet))
    print ‘Test set: ‘ + repr(len(testSet))
    # generate predictions
    predictions=[]
    k = 3
    for x in range(len(testSet)):
        neighbors = getNeighbors(trainingSet, testSet[x], k)
        result = getResponse(neighbors)
        predictions.append(result)
        print(‘> predicted=‘ + repr(result) + ‘, actual=‘ + repr(testSet[x][-1]))
    accuracy = getAccuracy(testSet, predictions)
    print(‘Accuracy: ‘ + repr(accuracy) + ‘%‘)
main()

输出:

Train set: 100
Test set: 49
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-setosa‘, actual=‘Iris-setosa‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-virginica‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-versicolor‘, actual=‘Iris-versicolor‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
> predicted=‘Iris-virginica‘, actual=‘Iris-virginica‘
Accuracy: 97.95918367346938%

从结果看出:训练集有100个实例,测试集有50个实例;接着打印出来了测试集的预测结果和实际分类;最后计算出了预测的正确率约为98%,比较理想。

基本分类方法——knn(k近邻)算法

...程中,提到了KNN算法。有点熟悉,上网一查,居然就是K近邻算法,机器学习的入门算法。参考内容如下:http://www.cnblogs.com/charlesblc/p/6193867.html1、kNN算法又称为k近邻分类(k-nearestneighborclass 查看详情

机器学习分类算法--k近邻算法knn(代码片段)

一、K近邻算法基础KNN-------K近邻算法--------K-NearestNeighbors思想极度简单应用数学知识少(近乎为零)效果好(缺点?)可以解释机器学习算法使用过程中很多细节问题更完整的刻画机器学习应用的流程 importnumpyasnpimportmatplotlib... 查看详情

k近邻算法(knn)

1.前言K近邻法(k-nearestneighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用,就是“物以类聚,人以群分”。比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出... 查看详情

k-近邻算法(knn)

...的新样本时,用算法提取训练样本集中和待分类的样本最近邻的K个分类标签(比如样本只有两个特征,在二维坐标系中用点来表示一个样本,选择和新样本点距离最近的K个点)。选取这k个分类标签中出现次数最多的分类,作为... 查看详情

机器学习实战☛k-近邻算法(k-nearestneighbor,knn)(代码片段)

机器学习实战☛k-近邻算法(K-NearestNeighbor,KNN)文章目录机器学习实战☛k-近邻算法(K-NearestNeighbor,KNN)k-近邻算法概述原理简介k-近邻算法一般流程伪代码与实现示例:使用kNN改进约会网站的配对效... 查看详情

k-近邻算法(knn)

1、K-近邻算法原理 1.1算法特点简单地说,k-近邻算法采用测量不同特征值之间的距离方法进行分类。优点:精度高、对异常值不敏感、无数据输入假定缺点:计算复杂度高、空间复杂度高适用数据范围:数值型和标称型 1... 查看详情

k-近邻算法(knn)

算法简介KNN算法原理是:存在一个样本数据集合(训练样本集),并且样本集合中每个数据都已知该数据的分类。当输入没有标签的新数据时,我们将新数据的特征与已知样本集合进行逐个比较,提取K个最相近的数据的标签,... 查看详情

k近邻算法(knn)与k-means算法的对比

k近邻算法(knn)是一种基本的分类与回归的算法,k-means是一种基本的聚类方法。k近邻算法(knn)基本思路:如果一个样本在特征空间的k个最相似(即特征空间最邻近)的样本大多数属于某一类,则该样本也属于这一类。影响... 查看详情

手写数字识别的k-近邻算法实现

...况下转载)前言手写字符识别是机器学习的入门问题,k-近邻算法(kNN算法)是机器学习的入门算法。本文将介绍k-近邻算法的原理、手写字符识别问题分析、手写字符识别的kNN实现、测试。kNN算法原理kNN算法是一种分类算法,... 查看详情

k-近邻算法(knn)(代码片段)

K-近邻算法(KNN)1KNN介绍2KNN的初步使用3距离度量3.1基本性质3.2常见距离公式3.3距离属性4k值选择5KNN优化—kd树5.1kd树简介5.2构造方法5.3案例分析6数据集6.1获取数据集6.2划分数据集7特征工程—特征预处理7.1归一化7.2标准化... 查看详情

机器学习实战第2章k-近邻算法(k-nearestneighbor,knn)

第2章k-近邻算法<scripttype="text/javascript"src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=default"></script>KNN概述k-近邻(kNN,k-NearestNeighbor)算法主要是用来进行分类的.KNN场景电影可以按照题材分类,那么如何区分&nbs 查看详情

k-近邻算法(knn)

概述简单地说,K-近邻算法(K-Nearest-NeighborsClassification)采用测量不同特征值之间的距离方法进行分类。优点:精度高、对异常值不敏感、无数据输入假定缺点:计算复杂度高、空间复杂度高使用数据范围:数值型和标称型工作... 查看详情

机器学习-k-近邻算法(代码片段)

...言算法介绍距离计算算法实现数据转换K值选取结语前言K-近邻算法(k-nearestneighborsalgorithm),又称为KNN算法,是这学期机器学习课教的第一个算法,也是我接触的第一个机器学习算法。学习之后的感触便是:机器学习和我想象的有... 查看详情

分类算法之k-近邻算法(knn)(代码片段)

一、k-近邻算法概述 1、什么是k-近邻算法如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。2、欧式距离两个样本的距离可以通过如下公式计算,又叫... 查看详情

tensorflow实现knn(k近邻)算法

首先先介绍一下knn的基本原理:KNN是通过计算不同特征值之间的距离进行分类。整体的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。K通常... 查看详情

第二章:k-近邻算法(knn)

  kNN功能:解决输入是数值型或者标称型的分类问题  kNN大致原理:输入数据集相当于在一定维度的空间中标点,测试集(或者说要预测标签的),相当于是计算与这些已有点的距离(一般是欧式距离),选择前k个距离最... 查看详情

k-近邻算法(knn)

参考技术A简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类。欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:身高、体重、鞋子尺码数据对应性别导包,机器学习的算法... 查看详情

史诗级干货长文k-近邻算法(代码片段)

K-近邻算法前言1.K-近邻算法简介1.1什么是K-近邻算法1.2K-近邻算法(KNN)概念1.3电影类型分析1.4KNN算法流程总结2.KNN算法API初步使用2.1Scikit-learn工具介绍2.1.1安装Scikit-learn2.1.2Scikit-learn包含的内容2.2K-近邻算法API2.3案例2.3.1步骤分析2.3.2... 查看详情