基于K-近邻的PLOSAR图像分类

🎀个人主页: https://zhangxiaoshu.blog.csdn.net
📢欢迎大家:关注🔍+点赞👍+评论📝+收藏⭐️,如有错误敬请指正!
💕未来很长,值得我们全力奔赴更美好的生活!

前言

K-近邻(KNN)是一种简单但有效的机器学习算法,可用于图像分类。POLSAR(极化合成孔径雷达)是一种雷达成像技术,提供了极化信息,适用于地物分类和识别。将KNN应用于POLSAR图像分类具有简单易实现、多类别适用、无需假设数据分布、基于邻近性进行分类、对噪声鲁棒以及可用于增量学习等优点,本文为基于K-近邻实现PLOSAR图像分类的一个小实例。



一、数据预处理

对于提供的原始数据ALLData.mat和标签数据label.mat来说,标签数据是包含背景0的,所以,在分类之前,我们首先需要将对应label为0的对于提供的原始数据删除。将原始数据ALLData.mat和标签数据label.mat读取并查看维度信息如下所示:

#读取mat数据
data_orginal = io.loadmat(r"D:/VSCode/Task_python/lab/homework/Image classification/PolSAR/ALLData.mat")["ALLData"]
label_original = io.loadmat(r"D:/VSCode/Task_python/lab/homework/Image classification/PolSAR/label.mat")["label"]
label = np.reshape(label_original, data_orginal.shape[0], order='F')

print("ALLData shape=",data_orginal.shape)
print("label shape=",label.shape)

输出为:

ALLData shape= (768000, 9)
label shape= (768000,)

可以看到ALLData和label共有768000条数据,其中ALLData的每一条数据是一个1*9的向量,label为一个数,为了后续清零操作的便利,我们将这两个数据拼接在一起,即使用:

data_o=torch.cat([torch.tensor(data_orginal),

torch.tensor(label).reshape(768000,1)],-1).numpy(),

这样我们便得到了一个768000*10的序列。

下面进行清零操作,首先,我们定义一个data数据,将第一个label不为0的数据赋值给data,之后遍历读取的原始拼接在一起的数据data_o,如果data_o[i][9]不等于0,我们就将data_o[i]拼接到data中,最后保存data,操作过程如下所示。

#数据清零
data=data_o[111135]
for i in range(111136,768000-1):
    if data_o[i][9]!=0:
        data=np.vstack((data,data_o[i]))
np.save('data.npy',data)

清零完成后,我们便得到了一个167712*10的数据,其中前9列是数据,后面一列为标签。

二、基于K-近邻的PLOSAR图像分类

1. KNN简介

K最近邻(KNN)算法是一种基本的机器学习算法,常用于分类和回归任务。它的工作原理非常简单直观:对于一个新的未知样本,根据其在特征空间中与已知样本的距离,找出距离最近的K个邻居,然后根据这K个邻居的标签来预测未知样本的标签。

在这里插入图片描述

KNN算法的基本步骤如下:

  • 选择K值:首先选择一个合适的K值,它表示在预测时要考虑多少个最近邻居的标签。K值的选择可能会影响算法的性能。

  • 计算距离:对于待预测的样本,计算它与所有已知样本之间的距离。通常使用的距离度量包括欧式距离曼哈顿距离闵可夫斯基距离等。

  • 找出K个最近邻:根据计算得到的距离,找出与待预测样本最近的K个已知样本。

  • 投票决策:对于分类任务,根据这K个最近邻的标签,采用投票的方式来确定待预测样本的标签。一般来说,可以选择多数票决定样本的分类标签。

  • 回归预测:对于回归任务,根据这K个最近邻的标签,可以采用平均值或加权平均值来预测待预测样本的输出。

2. 分类实验

首先,我们将之前处理得到的data数据读入,然后按列分成1677129的数据和1677121的标签。其过程如下代码所示:

#加载清零后的数据
data=np.load("D:\VSCode\Task_pytorch\z_home_work\Image classification\data.npy")
print(data.shape)
#将数据和label分开
[data,label]=np.split(data,[9],axis=1)
print(data.shape)
print(label.shape)

然后定义一个KNN分类器,这里我们直接使用sklearn来实现,然后我们的实验分别测试了当训练数据集比例为[0.1,0.3,0.5]时的准确率,同时测试了k值为[10,20,30,40,50]的准确率,共九组实验,其中实验过程代码如下图4所示,实验数据如下表所示。从实验结果中我们可以看到,使用KNN分类器的分类效果比较好,基本达到了85%-87%的准确率,同时,我们可以看到,对于不同的训练数据集比例来说,较大的数据集更加能学习到更好的分类特征。对于不同的K值来说,我们可以看到无论过大或是过小都会对模型的准确度产生影响,所以K的取值往往需要一个合适的区间或值,另一方面,K的取值可以看到对最后的结果影响不大,即KNN分类器受K值的影响波动较小较稳定。

acc=[]
k=[10,20,30,40,50]
train_size=[0.1,0.3,0.5]
for i in range(5):
    print("K=",k[i],"时:")
    for j in range(3):
        #划分训练集和测试集
        X_train,X_test,y_train,y_test = train_test_split(data, label, train_size=train_size[j], stratify=label)
        knn = KNeighborsClassifier(n_neighbors=k[i]) 
        knn.fit(X_train, y_train.reshape((-1, 1)).ravel())
        y_predict = knn.predict(X_test) 
        acc.append(accuracy_score(y_test, y_predict))
        print("train_size=",train_size[j], "的分类准确率为: ", acc[i*3+j])

训练结果:

  • K= 10 时:
    train_size= 0.1 的分类准确率为: 0.8641323431009468
    train_size= 0.3 的分类准确率为: 0.8803056244090666
    train_size= 0.5 的分类准确率为: 0.8870444571646632
  • K= 20 时:
    train_size= 0.1 的分类准确率为: 0.8637812125267489
    train_size= 0.3 的分类准确率为: 0.8780398470174363
    train_size= 0.5 的分类准确率为: 0.8832999427590155
  • K= 30 时:
    train_size= 0.1 的分类准确率为: 0.8615154265573965
    train_size= 0.3 的分类准确率为: 0.8762681113127029
    train_size= 0.5 的分类准确率为: 0.8826440564777714
  • K= 40 时:
    train_size= 0.1 的分类准确率为: 0.8586202555965576
    train_size= 0.3 的分类准确率为: 0.874624145009753
    train_size= 0.5 的分类准确率为: 0.8810341537874451
  • K= 50 时:
    train_size= 0.1 的分类准确率为: 0.8551553255907938
    train_size= 0.3 的分类准确率为: 0.8714980536461129
    train_size= 0.5 的分类准确率为: 0.8786848883800802
train_size=0.1 train_size=0.3 train_size=0.5
K=10 0.8641323431009468 0.8803056244090666
K=20 0.8637812125267489 0.8780398470174363
K=30 0.8615154265573965 0.8762681113127029
K=40 0.8586202555965576 0.874624145009753
K=50 0.8551553255907938 0.8714980536461129

最后,我们使用训练好的模型将原始数据读入,并将分类的结果绘制成图片的形式,其结果如下图所示。
在这里插入图片描述
结合SVM的实验结果从整体上两个分类器所表现的行性能来看,KNN相对来说更加稳定一些,在KNN实验中,无论K的取值如何,它的最终结果总是保持在85-87%之间,但是反观SVM来说,它受kernel函数取值的影响太多,例如,在kernel函数为rbf时,其最高准确率可以达到87%。但是在kernel函数为linear时,最高准确率仅仅只有达到22%。总的来说,SVM分类器受到kernel函数很大程度上的影响。


文中有不对的地方欢迎指正、补充。

相关推荐

  1. 基于k-均值聚类图像分割

    2024-03-25 17:50:02       60 阅读
  2. 机器学习实战-k近邻分类

    2024-03-25 17:50:02       30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-25 17:50:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-25 17:50:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-25 17:50:02       87 阅读
  4. Python语言-面向对象

    2024-03-25 17:50:02       96 阅读

热门阅读

  1. 【NC19989】容易题(EASY)

    2024-03-25 17:50:02       32 阅读
  2. 中国象棋C++

    2024-03-25 17:50:02       37 阅读
  3. Python实现WebSocket通信

    2024-03-25 17:50:02       33 阅读
  4. 第十五届蓝桥杯模拟赛 第三期 (C++)

    2024-03-25 17:50:02       40 阅读
  5. golang实现枚举

    2024-03-25 17:50:02       43 阅读
  6. Qt笔记 计时器

    2024-03-25 17:50:02       44 阅读
  7. Day28:学习SpringCloud

    2024-03-25 17:50:02       39 阅读
  8. 为什么大家都在推美国MSB?

    2024-03-25 17:50:02       42 阅读
  9. 编程生活day3--Left Pad、出生年

    2024-03-25 17:50:02       43 阅读