KNN算法

- 日理万妓 2022-01-26 01:11 420阅读 0赞

1、kNN算法又称为k近邻分类(k-nearest neighbor classification)算法。
最简单平凡的分类器也许是那种死记硬背式的分类器,记住所有的训练数据,对于新的数据则直接和训练数据匹配,如果存在相同属性的训练数据,则直接用它的分类来作为新数据的分类。这种方式有一个明显的缺点,那就是很可能无法找到完全匹配的训练记录。

kNN算法则是从训练集中找到和新数据最接近的k条记录,然后根据他们的主要分类来决定新数据的类别。该算法涉及3个主要因素:训练集、距离或相似的衡量、k的大小。

下面通过一个简单的例子来看下

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDIzOTU0MQ_size_16_color_FFFFFF_t_70

通过KNN算法算出唐人街探案是属于哪种类型的电影

过程:

(1)在进行KNN算法之前需要先进行数据清洗,如异常值,野值等会干扰结论(本案例数据较少可不用进行数据清洗)

(2)计算每个样本和新样本的相似度

公式:d= √(x-x1)^2+(x-x2)^2+(x-x3)^2

(3)对数据以相似度进行顺序排序

(3)选取k值,根据样本数据数量的大小取k值,本案中可取k=5,然后取5个样本数据中最多的标签(取众数)

代码如下

  1. import pandas as pd
  2. import numpy as np
  3. data = pd.read_excel(r'C:\Users\Administrator\Desktop\电影分类数据.xlsx',encoding='gbk')
  4. print(data.columns)
  5. # 计算与表中每个电影的相似度并插入表中'相似性'字段
  6. data['相似度'] = np.sqrt((data.columns[7]-data['搞笑镜头'])**2+(data.columns[8]-data['拥抱镜头'])**2+(data.columns[9]-data['打斗镜头'])**2)
  7. # 对表中的数据以相似性进行顺序排序
  8. data.sort_values(by='相似度',inplace=True)
  9. print(data)
  10. result = data['电影类型'].head()
  11. print('{}属于'.format(data.columns[6]),result.mode()[0])

运行结果:

  1. E:\Anaconda3\python.exe E:/Project/人工智能/day-05-27/KNN算法.py
  2. Index(['序号', '电影名称', '搞笑镜头', '拥抱镜头', '打斗镜头', '电影类型', '唐人街探案', 23, 3, 17], dtype='object')
  3. 序号 电影名称 搞笑镜头 拥抱镜头 打斗镜头 电影类型 唐人街探案 23 3 17 相似度
  4. 6 7 我的特工爷爷 6 4 21 动作片 NaN NaN NaN NaN 17.492856
  5. 1 2 美人鱼 21 17 5 喜剧片 NaN NaN NaN NaN 18.547237
  6. 3 4 功夫熊猫3 39 0 31 喜剧片 NaN NaN NaN NaN 21.470911
  7. 0 1 宝贝当家 45 2 9 喜剧片 NaN NaN NaN NaN 23.430749
  8. 2 3 澳门风云3 54 9 11 喜剧片 NaN NaN NaN NaN 32.140317
  9. 10 11 新步步惊心 8 34 17 爱情片 NaN NaN NaN NaN 34.438351
  10. 8 9 夜孔雀 9 39 8 爱情片 NaN NaN NaN NaN 39.661064
  11. 9 10 代理情人 9 38 2 爱情片 NaN NaN NaN NaN 40.570926
  12. 11 12 伦敦陷落 2 3 55 动作片 NaN NaN NaN NaN 43.416587
  13. 4 5 谍影重重 5 2 57 动作片 NaN NaN NaN NaN 43.874822
  14. 7 8 奔爱 7 46 4 爱情片 NaN NaN NaN NaN 47.686476
  15. 5 6 叶问3 3 2 65 动作片 NaN NaN NaN NaN 52.009614
  16. 唐人街探案属于 喜剧片
  17. Process finished with exit code 0

如果数据非常多的时候那么如何选定k值呢?

我们需要对k值进行训练,也就是选几组k值,对结果进行比对,准确率最高的就是最佳的k值

有两个文件夹,trainingDigits(训练集数据)和testDigits(测试集数据),每个文件夹中有上千个文件(0-1,0-2…..0-100,1-0,1-1…..),每个文件中有32*32个由1和0组成的数据形式,如图所示;

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDIzOTU0MQ_size_16_color_FFFFFF_t_70 1

根据每个文件夹中的文件(0-1,0-2…..0-100,1-0,1-1…..),例如0-1,0-2……0-100文件中的数据就属于‘0’,1-0,1-1…..1-100文件属于’1’进行分类,根据trainingDigits(训练集数据)进行统一分类建模,用testDigits(测试集数据)进行测试。并选定k值

代码分为两部分,首先是对数据进行读取,并以同样的形式进行保存,代码如下:

  1. import os
  2. import pandas as pd
  3. import numpy as np
  4. def data_train(dirth):
  5. try:
  6. file_list = os.listdir(dirth)
  7. # (1)提取标签,从文件名上
  8. arr = np.zeros((len(file_list),1025))
  9. # (2)读文件夹中所有的txt文件
  10. for index,i in enumerate(file_list):
  11. biaoqian = i.split('_')[0]
  12. file_path =dirth+'/'+i
  13. file_content = np.loadtxt(file_path,dtype=str)
  14. print('-------', file_content)
  15. # shux = ''.join(file_content)
  16. # shux1 = [int(a) for a in shux]
  17. # shux2 = np.array(shux1)
  18. arr1 = np.zeros((32,32))
  19. for index1,a in enumerate(file_content):
  20. # print(index1)
  21. arr1[index1] = np.array(list(map(int,a)),dtype=np.int8) # 32*32
  22. arr1_ravel = arr1.ravel() # 1*1024
  23. print(arr1_ravel)
  24. arr[index,:-1] = arr1_ravel
  25. arr[index,-1] = biaoqian
  26. name = dirth.split('\\')[-1]
  27. np.savetxt(f'{name}.csv',arr,fmt='%d')
  28. except:
  29. pass
  30. if __name__ == '__main__':
  31. dirth1 = 'trainingDigits'
  32. dirth2 = r'C:\Users\Administrator\Desktop\testDigits'
  33. data_train(dirth1)
  34. data_train(dirth2)

上面的程序将两个文件夹中的数据进行形式统一,且各自分好了属于每组数的标签,然后保存到两个文件中,接下来需要将测试集中的数据根据训练集种的数据分类来进行KNN算法分类。并最值终确定k值

  1. import pandas as pd
  2. import numpy as np
  3. # KNN算法
  4. def knn(arr_test,arr_train,k):
  5. true_num = 1
  6. for i in range(arr_test.shape[0]):
  7. test = arr_test[i,:-1]
  8. # 求相似度
  9. d = np.sqrt(((test - arr_train[:,:-1])**2).sum(axis=1))
  10. # 排序
  11. sort_index = d.argsort()[:k]
  12. tag = arr_train[sort_index,-1]
  13. df = pd.DataFrame(tag).mode()
  14. print('预测值',df[0][0])
  15. print('实际值',arr_test[i,-1])
  16. if df[0][0] == arr_test[i,-1]:
  17. true_num += 1
  18. print('准确度为',true_num/arr_test.shape[0])
  19. return true_num/arr_test.shape[0]
  20. if __name__ == '__main__':
  21. arr_test = np.loadtxt('testDigits.csv', dtype=int)
  22. arr_train = np.loadtxt('trainingDigits.csv', dtype=int)
  23. y = []
  24. for k in range(5,15):
  25. prec = knn(arr_test,arr_train,k)
  26. y.append(prec)
  27. x = range(5,15)
  28. import matplotlib.pyplot as plt
  29. plt.figure()
  30. plt.plot(x,y,marker='*',markersize=12)
  31. plt.xlabel('k')
  32. plt.ylabel('准确度')
  33. plt.show()

最终的折线图如图所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDIzOTU0MQ_size_16_color_FFFFFF_t_70 2

如图所示共选取了十组k值进行最终的准确率比对,发现当k=5的时候准确率最高,说明k=5

产生误差数据的饼图

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. def knn(test_arr,train_arr,k):
  5. test_list = []
  6. for i in range(test_arr.shape[0]):
  7. test_data = test_arr[i,:-1]
  8. # 相似度
  9. d = np.sqrt(((test_data - train_arr[:,:-1])**2).sum(axis=1))
  10. # 排序
  11. sort_index = d.argsort()[:k]
  12. tag = train_arr[sort_index,-1]
  13. df = pd.DataFrame(tag).mode()
  14. value_yuce = df[0][0]
  15. value_shiji = test_arr[i,-1]
  16. print('预测值',value_yuce)
  17. print('实际值',value_shiji)
  18. if value_shiji != value_yuce:
  19. test_list.append(value_shiji)
  20. return test_list
  21. if __name__ == '__main__':
  22. test_arr = np.loadtxt('testDigits.csv',dtype=int)
  23. train_arr = np.loadtxt('trainingDigits.csv',dtype=int)
  24. k = 5
  25. test_list = knn(test_arr,train_arr,5)
  26. print(test_list)
  27. data = pd.DataFrame(test_list)
  28. data1 = data[0].value_counts()
  29. label = data1.index
  30. explode = [0.01,0.01,0.01,0.01,0.01,0.01]
  31. plt.figure()
  32. plt.pie(data1,explode=explode,labels=label,autopct='%1.1f%%')
  33. plt.savefig('误差数据饼图')
  34. plt.show()

图像如图所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDIzOTU0MQ_size_16_color_FFFFFF_t_70 3

根据上图所示标签为8的数据产生的误差率最大。

发表评论

表情:
评论列表 (有 0 条评论,420人围观)

还没有评论,来说两句吧...

相关阅读

    相关 KNN算法

    记得读研那会,接触过这个算法,算法原理还是比较容易理解,类似机器学习中的预测,在给定的一堆数据,预测当前节点的分类。计算距离,然后排序,计算最相似的分类。 impor

    相关 knn算法概述

    数据挖掘算法原理与实践:k-近邻 knn算法概述 201228 > educoder 答案 任务描述 本关任务:使用python实现方法,找出目标样本最近的k个样

    相关 KNN分类算法

    KNN分类算法 最简单最初级的分类器,就是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类 K近邻(k-nea

    相关 kNN算法总结

    一直接触KNN近邻算法,但是一直没有机会系统的总结一下,现在做一下总结,希望加深一下自己对近邻算法的理解。 定义:K-近邻算法采用测量不同特征值之间的距离方法进行分类 优缺

    相关 KNN算法思考

    学习机器学习时,我们可能接触到KNN算法,这是一中间的算法,是利用距离来表征两者之间的相似度。这一算法最经典的应用就是给相似人群做推荐系统。这里对算法内容不做详细解释,只是引发

    相关 KNN算法

    KNN算法即K-近邻算法,KNN的核心思想是通过你的“邻居”来推断出你的类别。 1 K-近邻算法(KNN)原理     k 值取得过小,容易受到异常点的影响   

    相关 KNN算法

    1、kNN算法又称为k近邻分类(k-nearest neighbor classification)算法。 最简单平凡的分类器也许是那种死记硬背式的分类器,记住所有的训练数