【模式识别】实验二:K近邻算法(KNN)

举报
zstar 发表于 2022/08/06 02:33:49 2022/08/06
【摘要】 KNN是模式识别中的经典算法,本次实验就MNIST数据集来做KNN算法的实验,并结合前一次的LDA降维对数据进行进一步处理。 实验报告图片版 pdf版本可以戳这:模式识别实验报告:KNN K...

KNN是模式识别中的经典算法,本次实验就MNIST数据集来做KNN算法的实验,并结合前一次的LDA降维对数据进行进一步处理。

实验报告图片版

pdf版本可以戳这:模式识别实验报告:KNN K近邻算法
请添加图片描述

关键代码

KNN原理报告里有写,不作重复赘述。
本实验使用的编程环境是Jupyter,完整的程序代码可以戳这下载。
【模式识别】实验二:KNN,python程序代码与实验过程
这里仅贴上核心代码

MNIST数据集的导入

在本专栏之前一篇博文专门分析过,这里只上代码:

mnist = fetch_openml("mnist_784")
X, y = mnist['data'], mnist['target'] # X:data,y:label

  
 
  • 1
  • 2

特征标准化

特征标准化的好处:1、提高精度。2、提高计算速度

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

scaler = StandardScaler()
X_standardized = scaler.fit_transform(X1)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

数据筛选

shuffle_index = np.random.permutation(60000)  # 随机排列一个序列,返回一个排列的序列。
X1, y1 = X[shuffle_index[:10000]], y[shuffle_index[:10000]]

  
 
  • 1
  • 2

对KNN来说,数据筛选是很有必要的。MNIST总共7w条数据,全部都跑会跑到天荒地老~
因此本实验随机筛选了10000条数据。

KNN实现方式一:调用sklearn的KNeighborsClassifier

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import learning_curve
from sklearn import metrics

def knn(k):
    # 测试用,记录算法的时间
    # begin_t = t.time()
    #创建一个有5个邻居的KNN分类器对象
    knn = KNeighborsClassifier(n_neighbors=k, n_jobs=-1)

    #训练模型
    model = knn.fit(X_train, y_train)

    #预测数据
    predictions = model.predict(X_test)

    #测试准确率
    accuracy = metrics.accuracy_score(y_test, predictions)
#     print ("k=",k)
#     print ('accuracy:%.2f%%'%(100*accuracy))
    return 100*accuracy
    # print("Total time: {:.2f}s".format(t.time()-begin_t))

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

KNN实现方式二:手动实现

def knn(k):
    accuracy = 0
    m = X_train.shape[0] # m 标记预测值数量8000 ; n 标记测试集数量 2000
    n = X_test.shape[0]
    for i in range(n):
        count = np.zeros(10)
        prediction = 0
        distance = np.zeros((m,2))
        for t in range(m):
            distance[t,0] = y_train[t]              # 储存标签和欧式距离
            distance[t,1] = np.sqrt(sum(np.power(X_train[t] - X_test[i], 2)))  # 求欧式距离
        order = distance[np.lexsort(distance.T)]    # 按第二列(距离)排序
        for j in range(k):
            a = order[j,0]
            a = a.astype(int)
            count[a] += 1   
        prediction = count.argmax()                           # 取出现次数最多的为预测值
        if prediction == y_test[i]:
            accuracy += 1
    Accuracy = accuracy/n
    return 100*Accuracy  # 化成百分数形式

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

简要描述下算法思路:
1、逐次遍历测试集,对每个样本计算其和训练集的欧式距离。
2、将每个训练样本到该样本欧式距离排序,选取前K个训练样本。
3、统计这K个样本的标签,测试样本的标签即为这K个样本的最多的标签。

LDA降维

# 使用Fisher进行降维 
# 注:LDA最大降维数<分类数-1
# minsit为10分类,因此维度数可以取1-8
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
def mylda(X, y, demension):
    lda = LDA(n_components=demension)
    lda.fit(X, y)
    result_x = lda.transform(X)
    return result_x

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

总结

KNN需要计算每一个样本到训练样本的距离,因此训练样本越多,程序运行越慢;
优势在于程序无需经过训练,可以直接将样本进行判别分类。

文章来源: zstar.blog.csdn.net,作者:zstar-_,版权归原作者所有,如需转载,请联系作者。

原文链接:zstar.blog.csdn.net/article/details/121237262

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。