kNN算法的核心思想是把测试数据和训练数据集通过一些方法计算得出的值(距离)进行排序,然后在前K个值中找出出现频数最高的那个分类.
如右图(取自百度百科),有 蓝正方形 和 红三角 两类,通过计算得到 绿圆(测试数据) 和各个 训练数据 的位置距离,
然后查看离 绿圆 最近的K个训练数据中哪个频数最高就把绿圆归为哪类.图中实线(K=3)中红三角最多所以把 绿圆和红三角 归为一类;而当取虚线(K=5)时 蓝正方形 最多,所以绿圆和 归为蓝正方形.
讲白了这个也就是猜,看离的近的哪类多就归为哪类.
从有图也可以看的出K的取值大小对准确率具有一定的影响.
例:手写数字识别
- 收集数据:提供文件.
- 准备,分析数据:把图像转换为分类器可以使用的格式(list)并分类.
- 训练算法:knn算法不适用.
- 测试算法:使用测试数据集测试.
- 使用算法.
一.
这里我用的数据集是 UCI的手写数数据集:手写数字数据集
二.
#用一维数组读取图片的数据
num = []
for i in range(0,longs):
strl1 = strl[i][-21:-2]
strl2= strl1.split(' ')
#print(strl2)
for k in range(0,10):
if strl2[k] == '1':
num.append(k)
break
#读取对应的是什么数字
snum = []
for i in range(0,longs):
ss = strl[i][0:-22]
stl = ss.split(' ')
n = []
for k in range(0,len(stl)):
n.append(float(stl[k]))
snum.append(n)
三.
KNN算法不适用这一步所以跳过了.
四.
#测试数据数
testsize = 100
#打印信息用,显示剩余测试数
nmm = testsize
#错误数
error = 0
for i in range(0,testsize):
nnm = 800 + i * 2 #测试数据,从第800个开始,隔一个数据再取
o = [0,0,0,0,0,0,0,0,0,0] #记录排序后前K个距离各个分类的数目
max = 0 #查找o中频数最大分类用
oo = 0 #记录频数最大分类
test = [] #测试数据与各训练数据距离
testnum = [] #记录训练数据对应分类
#计算距离,使用欧式距离公式
for k in range(0,800):
nm = 0
for p in range(0,256):
nm += ((snum[nnm][p] - snum[k][p])*(snum[nnm][p] - snum[k][p]))
test.append(nm**0.5)
for l in range(0,800):
testnum.append(num[l])
bubble_sort(test,testnum) #把测试数据与训练数据距离和对应类比排序
#取前K个中频数最大的
for l in range(0,3):
o[testnum[l]]+=1
for l in range(0,10):
if o[l]>max:
max = o[l]
oo = l
nmm -= 1
print('test:',num[nnm],'-----answer:',oo,'-----remaining:',nmm)
if num[nnm] != oo:
error += 1
五.
('test:', 0, '-----answer:', 0, '-----ramaining:', 99)
('