【机器学习】最近邻算法KNN原理、流程框图、代码实现及优缺点

本文介绍了KNN算法的基本原理,通过Python实现KNN算法,并对其优缺点进行了分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过机器学习教学视频,初识KNN算法,对原理和算法流程通过小应用进行Python实现,有了自己的一些理解。因此在此整理一下,既是对自己学习的阶段性总结,也希望能和更多的朋友们共同交流学习相关算法,如有不完善的地方欢迎批评指正。

1、KNN算法原理

KNN,全称k-NearestNeighbor,即常说的k邻近算法。

该算法的核心思想:一个样本x与样本集中的k个最相邻的样本中的大多数属于某一个类别yLabel,那么该样本x也属于类别yLabel,并具有这个类别样本的特性。简而言之,一个样本与数据集中的k个最相邻样本中的大多数的类别相同

由其思想可以看出,KNN是通过测量不同特征值之间的距离进行分类,而且在决策样本类别时,只参考样本周围k个“邻居”样本的所属类别。因此比较适合处理样本集存在较多重叠的场景,主要用于聚类分析、预测分析、文本分类、降维等,也常被认为是简单数据挖掘算法的分类技术之一。

2、KNN流程框图

在建立训练集时,就要确定训练数据及其对应的类别标签;然后把待分类的测试数据与训练集数据依次进行特征比较;从训练集中挑选出最相近的k个数据,这k个数据中投票最多的分类,即为新样本的类别。

为了方便阅读算法流程,将其描述为如下流程框图:


3、KNN代码实现

参考《视觉机器学习 20讲》,整理KNN算法的伪代码如下:

Algorithm KNN(A[n], k)
{
    Input: A[n]为N个训练样本的分类特征;
		   k为近邻个数;

	Initialize:
		选择A[1]至A[k]作为x的初始近邻;
		计算初始近邻与测试样本x间的欧氏距离d(x, A[i]), i=1,2,...k;
		按d(x, A[i])从小到大排序;
		计算最远样本与x间的距离D,即max{d(x, A[j]) | j=1,2...k};

	for(i=k+1; i<n+1; i++)
		计算A[i]与x间的距离d(x, A[i]);

		if  (d(x, A[i]) < D ) then
		用A[i]代替最远样本;
		按照d(x, A[i])从小到大排序;
		计算最远样本与x间的距离D,即max{d(x, A[j]) | j=1,...i};
		计算前k个样本A[i]所属类别的概率,i=1,2,...k;
		具有最大概率的类别即为样本x的类;
	end for

    Output: x所属的类别。
}

参照麦子学院彭亮主讲机器学习课程中,KNN的Python代码,实现了KNN算法的分类功能。

import csv
import random
import math
import operator

#导入数据,并分为训练集和测试集
def loadDataset(filename, split, trainingSet = [], testSet = []):
    with open(filename, 'rt') as csvfile:
        lines = csv.reader(csvfile)
        dataset = list(lines)
        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个数据集),testInstance是实例
def getNeighbors(trainingSet, testInstance, k):
    distances = []
    length = len(testInstance)-1
    for x in range(len(trainingSet)):
        #testinstance
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))#distance是一个多个元组的list
        #distances.append(dist)
    distances.sort(key=operator.itemgetter(1))#按照dist排序
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])#要的是数据集
        return neighbors

#投票法找出最近邻的结果哪种最多
def getResponse(neighbors):
    classVotes = {}#key--花名字 value--个数
    for x in range(len(neighbors)):
        response = neighbors[x][-1]
        if response in classVotes:
            classVotes[response] += 1
        else:
            classVotes[response] = 1
    sortedVotes = sorted(classVotes.items(), 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 = 1/3
    loadDataset(r'E:\pycharmcode\irisdata.txt', 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)):
        # trainingsettrainingSet[x]
        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) + '%')

4、KNN算法优缺点

4.1、优点

(1)理论成熟简单,易于理解及算法实现

(2) 可以用于多分类分类、回归等;

4.2、缺点

(1)需要计算待分类样本与所有已知样本的距离,计算量大;

(2)样本容量小或样本分布不均衡时,容易分类错误,后者可通过施加距离权重进行改善

5、参考资料

1、《视觉机器学习 20讲》;

2、K-近邻(KNN)算法

3、机器学习实战之kNN算法

4、KNN(k-nearest neighbor的缩写)最近邻算法原理详解

5、麦子学院在线课程

### KNN回归与KNN分类算法原理图解及区别 #### 一、KNN分类算法原理 KNN(k-Nearest Neighbor)是一种基于实例的学习方法,其核心思想是通过计算待预测样本与其训练集中已知类别的样本之间的相似度来完成分类或回归任务。对于KNN分类算法而言,主要依据的是多数表决原则[^1]。 具体来说,在给定测试样本的情况下,首先会在特征空间中找到该样本最接近的 \( k \) 个邻居;然后统计这 \( k \) 个邻居所属类别中的众数作为最终预测结果。这种策略通常被称为“投票机制”,即哪个类别的票数最多就将其分配为此类别[^2]。 #### 二、KNN回归算法原理 相比之下,KNN回归则更关注数值型目标变量而非离散标签。它的基本思路同样是寻找最近邻点集合,不过这里不再简单地采用投票方式决定输出值,而是通过对这些近邻的目标值进行某种形式的平均运算得出估计值。常见的做法包括算术均值或者加权平均等技术手段[^1]。 例如,在执行加权平均操作时可以考虑让距离越短的数据点拥有更大的权重系数,从而使得它们对整体结果的影响程度更高一些。这样做的好处在于能够更好地反映局部特性并减少噪声干扰带来的影响[^2]。 ```python from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor import numpy as np # 构造简单的二维数据集用于演示目的 X = np.array([[1], [2], [3]]) y_classify = ['A', 'B', 'C'] # 分类问题对应的标签 y_regression = [1.0, 2.5, 3.7] # 回归问题对应的真实值 # 初始化模型对象 clf = KNeighborsClassifier(n_neighbors=2) reg = KNeighborsRegressor(n_neighbors=2) # 训练两个不同类型的KNN模型 clf.fit(X, y_classify) reg.fit(X, y_regression) print(clf.predict([[1.8]])) # 输出:['B'] print(reg.predict([[1.8]])) # 输出:大约等于2.25 (取决于具体的实现细节) ``` 以上代码片段展示了如何利用 `scikit-learn` 库分别创建一个KNN分类器以及一个KNN回归器,并对其进行了基础配置之后再加以应用的例子[^1]。 #### 三、两者的异同对比分析 | **比较维度** | **KNN分类** | **KNN回归** | |--------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| | 预测目标 | 对新输入向量赋予离散类别标签 | 给出连续数值型响应 | | 决策规则 | 使用多数表决法确定归属 | 运用平均或其他聚合函数得到预期输出 | | 数据分布假设 | 同一类别的样本倾向于聚集在一起 | 数字间存在线性关系或者其他可建模关联 | 值得注意的地方还有关于参数\( k \)的选择方面也存在一定差异。在处理分类任务的时候如果选取较大的\( k \),可能会平滑掉某些细小但是重要的边界区域划分情况;而对于回归场景下,则可能因为过度概括而导致欠拟合现象发生[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值