KNN主要使用来分类的。
算法原理:
- 假设有带有标签的训练样本集,其中包含每条数据与所属分类的对应关系;
- 输入一个没有标签的新数据,将新数据的每个特征与样本集中数据对应的特征进行比较,计算新数据与样本数据集中每条数据的距离,对求得所有距离进行排序(越小表示越相似),取前k(k<=20)个样本数据对应的分类标签。
- 求K个数据中出现次数最多的分类标签作为新数据的分类。
KNN算法特点:
优点:精度高,对异常值不敏感,无数据输入假定
缺点:计算复杂度高,空间复杂度高
适用数据范围:数值型和标称型
KNN项目案例:
项目概述:构造一个能够识别0-9的基于KNN分类器的手写数字识别系统
数据集MNIST手写字体数据集大小是28*28像素的灰度图像。
"""
Created on 2019-06-04
KNN:k近邻算法
Author: ZJ
"""
print(__doc__)
from numpy import *
import operator
import os
import cv2
from PIL import Image
hwLabels = []
#图片像素大小28*28
p = 28
def classify(intX,dataset,labels,k):
#intX 测试数据的特征向量
#dataset 训练数据的特征
#labels 训练数据的标签
#k 选择近邻的数目
#欧式距离
datasetSize = dataset.shape[0]
#tile 表示重复intX datasetSize列 1行
#生成与训练样本对应的矩阵,并且求差
diffMat = tile(intX,(datasetSize,1)) - dataset
# 取平方
sqDiffMat = diffMat ** 2
# 将矩阵的每一行相加
sqDistances = sqDiffMat.sum(axis=1)
# 开方
distances = sqDistances ** 0.5
#根据距离从小到大排序,然后返回的是对应索引的位置
sortedDistIndicies = distances.argsort()
#找到最近的k个样本所对应的标签,统计最多的类型就是测试数据的类型
#使用字典进行统计
classCount = {}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#表示对classCount中的第一维进行降序排序,即获得最多相同标签的类型
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
def imgvector(file):
rVector = zeros((1,28*28))
img = cv2.imread(file,0)
for i in range(28):
for j in range(28):
rVector[0,i*28 + j] = 1 if img[i][j] > 32 else 0
return rVector
def train():
path = r"F:\C\ps\SNN\MNIST\testimage\pic2\\"
ld = os.listdir(path)
global hwLabels
trainMat = zeros((3000,28 * 28))
for i in ld:
numLabel = int(i)
for j in range(0,300):
hwLabels.append(numLabel)
imgpath = path + i + '\\' + str(j+1) + '.bmp'
trainMat[numLabel*300 + j] = imgvector(imgpath)
return trainMat
if __name__ == '__main__':
trainMat = train()
num = 0
path = r"F:\C\ps\SNN\MNIST\testimage\pic2\\"
ld = os.listdir(path)
for i in ld:
numLabel = int(i)
num = 0
for j in range(300,400):
imgpath = path + i + '\\' + str(j) + '.bmp'
testVector = imgvector(imgpath)
testLabel = classify(testVector,trainMat,hwLabels,3)
num += 1 if testLabel == numLabel else 0
print(i + "的准确率为:" , num/100,'%')
Created on 2019-06-04
KNN:k近邻算法
Author: ZJ
0的准确率为: 0.99 %
1的准确率为: 0.99 %
2的准确率为: 0.9 %
3的准确率为: 0.9 %
4的准确率为: 0.86 %
5的准确率为: 0.88 %
6的准确率为: 0.97 %
7的准确率为: 0.93 %
8的准确率为: 0.84 %
9的准确率为: 0.92 %