图像分类(一)—KNN算法概述(附代码)

目录​​​​​​​

目录

一、理论知识

1、什么是KNN?

2、KNN算法的计算逻辑

3、距离度量(重点)

3.1 曼哈顿距离(Manhattan Distance)

3.2 欧式距离(Euclidean Metric)

二、分类器构建(代码实现)

1、显示训练数据

2、创建KNN分类器

3、测试数据

三、参考书籍​​​​​​​


一、理论知识

1、什么是KNN?

K—最近邻近算法(K- Nearest Neighbor, KNN):假设在一平面(图1)内,存在两种已知的样本数据(训练数据)类型,我们把蓝色的方块定义为A类样本数据,把橙色的菱形定义为B类样本数据。然而,在图1中,我们可以发现还存在一个红色的圆形(待预测的数据),我们怎么样才能知道它到底是属于A类(蓝色方块)还是B类(橙色菱形)呢?

KNN算法可以很好的解决这个问题,其核心思想就是可以通过选择周围的k个“邻居”,在k个最邻近的样本数据中选择所占比例最高的类别赋予预测数据。

具体来说,假设k=3(虚线圆圈),A类数据所占比例为1/3,B类数据所占比例为2/3,所以红色的圆形被赋予为B类;假设k=8(实线圆圈),A类数据所占比例为5/8,B类数据所占比例为3/8,所以红色的圆形被赋予为A类。

图1  KNN算法

2、KNN算法的计算逻辑

从上面的例子,我们可以简单的总结KNN算法的计算逻辑:

  • 计算训练数据与测试数据中每一个样本的距离(因为开始时,我们不知道哪些训练数据会成为最近的邻居,只有在计算出所有可能的距离之后,才能确定哪些是最近的k个邻居);
  • 选取距离测试数据最近的k个训练数据样本,作为“邻居”;
  • 选择所占比例最高的类别赋予测试数据。

因此,可以发现有两个因素可以直接决定KNN算法的准确性:

  • k值(“邻居”数量)的选择
  • 训练数据和测试数据中样本之间的距离

3、距离度量(重点)

在这里,对于k值(“邻居”数量)的选择先不展开赘述,主要探讨如何计算训练数据和测试数据中样本之间的距离。

3.1 曼哈顿距离(Manhattan Distance)

对于一个二维平面,假设有两个点\boldsymbol{\left ( x_1,y_1 \right )}\boldsymbol{\left ( x_2,y_2 \right )}。这两点之间的曼哈顿距离为:

\boldsymbol{\mathbf{} D = \left | x_1 - x_2\right | + \left | y_1 - y_2\right |}

曼哈顿距离也可以用在多维空间中,假设有两个点\boldsymbol{(x_1,x_2,...x_i)}\boldsymbol{(y_1,y_2,...y_i)}

\boldsymbol{\mathbf{D = \sum_{i = 1}^{n}}\left | x_i - y_i \right |}​​​​​​​

这种距离度量的核心思想是,它测量在各个坐标轴方向上的绝对差之和。

3.2 欧式距离(Euclidean Metric)

还是假设二维平面内有两个点\boldsymbol{\left ( x_1,y_1 \right )}\boldsymbol{\left ( x_2,y_2 \right )},那么这两点之间的欧式距离为:

\boldsymbol{D = \sqrt{(x_1 - x_2)^{2} + (y_1 - y_2)^{2}}}

欧式距离也可以用在多维空间中,假设有两个点\boldsymbol{(x_1,x_2,...x_i)}\boldsymbol{(y_1,y_2,...y_i)}

\mathbf{D = \sqrt{\sum_{i = 1}^{n}(x_i -y_i)^2}}

欧式距离测量的是点到点之间“直线”最短距离。

二、分类器构建(代码实现)

1、显示训练数据

在一个二维坐标轴上显示训练数据集,其中用红色星号(*)表示A类数据,对应的标签为A;用绿色加号(+)表示B类数据,对应的标签为B(图2)。

代码如下:

show_dataset.py

import numpy as np
import matplotlib.pyplot as plt

# 训练数据及其对应的标签
group = np.array([[1.0, 2.0], [1.2, 0.1], [0.1, 1.4], [0.3, 3.5], [1.1, 1.0], [0.5, 1.5]])
labels = np.array(['A', 'A', 'B', 'B', 'A', 'B'])

#A类数据用红色星号表示;B类数据用绿色加号表示
plt.scatter(group[labels == 'A', 0], group[labels == 'A', 1], color='r', marker='*')
plt.scatter(group[labels == 'B', 0], group[labels == 'B', 1], color='g', marker='+') 
plt.show()

图2  训练数据显示

2、创建KNN分类器

定义createDataSet函数用于创建测试数据及对应的标签(A/B),再定义kNN_classify函数选择使用曼哈顿距离或者欧式距离作为距离度量。

代码如下:

classify.py

import numpy as np
import operator

def createDataSet():
    # 创建测试数据及对应的标签
    group = np.array([[1.0, 2.0], [1.2, 0.1], [0.1, 1.4], [0.3, 3.5], [1.1, 1.0], [0.5, 1.5]])
    labels = np.array(['A', 'A', 'B', 'B', 'A', 'B'])
    return group, labels


def kNN_classify(k,dis,X_train,x_train,Y_test):
    assert dis == 'E' or dis == 'M' #确保函数的调用者必须选择这两种距离度量中的一种,否则函数将无法正确执行
    # E代表欧氏距离,M代表曼哈顿距离
    num_test = Y_test.shape[0]  # 测试样本的数量
    labellist = []

    if dis == 'E':
        for i in range (num_test):
            distances = np.sqrt(np.sum(((X_train - np.tile(Y_test[i], (X_train.shape[0],1))) ** 2), axis=1))
            nearest_k = np.argsort(distances)
            topK = nearest_k[:k]
            classCount = {}
            for i in topK:
                classCount[x_train[i]] = classCount.get(x_train[i], 0) + 1
            sortedClasssCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
            labellist.append(sortedClasssCount[0][0])
        return np.array(labellist)

    elif dis == 'M':
        for i in range(num_test):
            distances = np.sum(np.abs(X_train - np.tile(Y_test[i], (X_train.shape[0], 1))), axis=1)
            nearest_k = np.argsort(distances)
            topK = nearest_k[:k]
            classCount = {}
            for i in topK:
                classCount[x_train[i]] = classCount.get(x_train[i], 0) + 1
            sortedClasssCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
            labellist.append(sortedClasssCount[0][0])
        return np.array(labellist)

3、测试数据

在建立了KNN分类器之后,可以输入任意的测试数据,测试该被赋予A类还是B类,这下列代码中,选取k=6,距离度量用曼哈顿距离(M)。测试数据用蓝色表示,若被赋予A类,则显示为蓝色星号(*);若被赋予B类,则显示为蓝色加号(+)。

test_KNN.py

import numpy as np
import matplotlib.pyplot as plt
from classify import createDataSet,kNN_classify


if __name__ == '__main__':
    group,labels = createDataSet()

    #加载测试数据,可修改
    test_points = np.array([[0.75,1.75],[0.4,2.0]])
    y_test_pred = kNN_classify(6,'M',group,labels,test_points)

    plt.scatter(group[labels == 'A', 0], group[labels == 'A', 1], color='r', marker='*')
    plt.scatter(group[labels == 'B', 0], group[labels == 'B', 1], color='g', marker='+')
    for i, test_point in enumerate(test_points):
        if y_test_pred[i] == 'A':
            plt.scatter(test_point[0], test_point[1], color='b', marker='*')
        else:
            plt.scatter(test_point[0], test_point[1], color='b', marker='+')
    plt.show()

    print(y_test_pred)
图3  测试数据显示

三、参考资料

[1]魏溪含, 涂铭, & 张修鹏. (2020). 深度学习与图像识别: 原理与实践. 北京: 机械工业出版社。

  • 23
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是KNN算法的一个简单实例及其代码代码使用Python和scikit-learn库实现。 假设我们有一个包含两个特征和三个类别的数据集,数据集如下: | 特征1 | 特征2 | 类别 | |-------|-------|------| | 1 | 2 | A | | 2 | 3 | A | | 3 | 4 | B | | 4 | 5 | B | | 5 | 6 | C | | 6 | 7 | C | 首先,我们需要导入需要的库: ```python from sklearn.neighbors import KNeighborsClassifier import numpy as np ``` 然后,我们需要准备数据集,将数据集分为训练集和测试集: ```python # 准备数据集 X_train = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]]) y_train = np.array(['A', 'A', 'B', 'B', 'C', 'C']) X_test = np.array([[2.5, 3.5], [5.5, 6.5]]) ``` 接下来,我们需要实例化KNeighborsClassifier类,并设置K值为3: ```python # 实例化KNeighborsClassifier类 knn = KNeighborsClassifier(n_neighbors=3) ``` 然后,我们需要使用训练集来训练KNN模型: ```python # 训练KNN模型 knn.fit(X_train, y_train) ``` 接下来,我们可以使用测试集来测试KNN模型的分类效果: ```python # 预测测试集的类别 y_pred = knn.predict(X_test) print(y_pred) ``` 最后,我们可以输出KNN模型的评分结果: ```python # 输出KNN模型的评分结果 score = knn.score(X_test, ['B', 'C']) print(score) ``` 完整代码如下: ```python from sklearn.neighbors import KNeighborsClassifier import numpy as np # 准备数据集 X_train = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]]) y_train = np.array(['A', 'A', 'B', 'B', 'C', 'C']) X_test = np.array([[2.5, 3.5], [5.5, 6.5]]) # 实例化KNeighborsClassifier类 knn = KNeighborsClassifier(n_neighbors=3) # 训练KNN模型 knn.fit(X_train, y_train) # 预测测试集的类别 y_pred = knn.predict(X_test) print(y_pred) # 输出KNN模型的评分结果 score = knn.score(X_test, ['B', 'C']) print(score) ``` 输出结果为: ``` ['A' 'C'] 0.5 ``` 其中,y_pred为测试集的预测结果,score为KNN模型的评分结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值