KNN k-近邻算法

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 %

                                                                                        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值