机器学习01-KNN算法的python实现及手写体数字的识别

1.knn算法介绍:(copy自百度)
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。
kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。
2.knn算法的python实现:
(#运行环境python3.6.2)
import numpy as np
from PIL import Image
import operator
import os
#k为选择最相邻样本的个数
#testdata为需要进行测试的一条新数据:包含n条特征的numpy一维数组
#traindata为包含多条已知结果的训练数据:由m条与测试数据相同(特征长度为n)的numpy二维数组
#labels为训练数据的结果集,一个list对象
def knn(k,testdata,traindata,labels):
    #先把测试数据转为一维数组,然后把所有训练数据减去该一维数组
    rst = traindata-testdata
    #求出差值的平方
    reqrst = rst**2
    # print(reqrst.size)
    #把每一行数据相加再开方
    distance = (np.sum(reqrst,axis=1))**0.5
    #根据距离来排序索引值,由小到大
    sorteddistance = distance.argsort()
    count = {}
    for i in range(k):
        type = labels[sorteddistance[i]]
        count[type] = count.get(type,0)+1
    sort_count =sorted(count.items(),key=operator.itemgetter(1),reverse=True)
    return sort_count[0][0] #返回统计结果中value值最大的那个key值,即识别的结果
3.knn算法的使用案例:
利用knn进行手写体数字的识别,数据包为在csdn下载的手写数字数据包.数据存放在nums文件夹,将其中一个图片剪切出来放入到test文件夹,重命名为test.bmp ,作为待识别的数据.
def study():#学习的方法
    #遍历获取当前目录下的nums文件夹中的所有数字图片,并转为一维数组,同时按照顺序保存其类型labels
    traindata = np.empty(2) #用于保存训练数据的具体值的数组
    # print(f'size:{traindata.size}')
    labels  =[]     #用于保存训练数组类型的数组
    for i in range(10):
        num_pic_names = os.listdir('./nums/'+str(i)+'/')
        for name in num_pic_names:
            img = Image.open('./nums/'+str(i)+'/'+name)#打开图片
            array = np.array(img) #转为数组
            simple_arr = np.where(array == 0, 0, 1) #把灰度值转为0,1数组
            item = simple_arr.flatten()
            labels.append(i)
            # print(traindata.shape)
            if traindata.size == 2:
                traindata = item
            else:
                traindata = np.row_stack((traindata,item))
    # print(traindata.shape)
    # print(len(labels))
    return  traindata,labels #返回训练数据的具体值和类型

def test():

    # ====================识别一个测试数据的代码===========
    traindata,labels = study()
    test_img = Image.open('./test/test.bmp')
    test_array = np.array(test_img)  # 转为数组
    simple_arr = np.where(test_array == 0, 0, 1)  # 把灰度值转为0,1数组
    testdata = simple_arr.flatten()
    rst = knn(3,testdata,traindata,labels)
    print('===========================================')
    print(f'本次的识别结果为:{rst}')

test() #调用test()方法来执行代码

4.knn算法识别率的测试:
knn算法在手写体数字测试中的识别率比较高,通过切分训练数据和测试数据来进行测试(约1000个数据,切分出5%作为测试数据),准确率可以达到95%以上.
import time
from sklearn.model_selection import train_test_split

def test2():
    #====================以下为测试识别的准确率的代码
    print('开始学习...')
    begin = time.time()
    traindata, labels = study()
    study_end =time.time()
    print(f'学习结束,总共耗时{study_end-begin}秒,接下来进行准确率的验证')
    x_train,x_test,y_train,y_test = train_test_split(traindata, labels,test_size=0.05,random_state=20)
    count=0
    right=0
    print(f'本次测试数据的个数为:{len(y_test)}')
    for test,rst in zip(x_test,y_test):
        knn_rst= knn(3,test,x_train,y_train)
        count+=1
        # print(f'原数据结果为:{rst},识别结果为:{knn_rst},',end='') #如果识别错误,则打印出错误信息
        if knn_rst == rst:
            print('识别成功')
            right+=1
        else:
            print()
    print(f'准确率为:{right/count}')
    end = time.time()
    print(f'本次总共耗时{end-begin}秒')

test2() #调用test2()方法来执行代码














  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KNN(K-最近邻)是一种常用的分类算法,下面将用Python代码实现基于KNN算法手写体数字识别,使用的数据集为MNIST。 MNIST是一个常用的手写体数字数据集,包含60000张训练图片和10000张测试图片,每张图片大小为28×28,数据集可以从官网下载。 首先,我们需要读取数据,并对数据进行简单的处理: ``` python # 导入必要的库 import numpy as np import pandas as pd # 读取数据 train_data = pd.read_csv('mnist_train.csv') test_data = pd.read_csv('mnist_test.csv') # 处理数据,将数据转换成numpy数组格式 X_train = np.array(train_data.iloc[:, 1:]) y_train = np.array(train_data.iloc[:, 0]) X_test = np.array(test_data.iloc[:, 1:]) y_test = np.array(test_data.iloc[:, 0]) ``` 接下来,我们定义KNN算法的函数,并使用Sklearn库中的KNeighborsClassifier类实现算法: ``` python from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score def knn(k, X_train, y_train, X_test, y_test): """ KNN算法实现 :param k: K值 :param X_train: 训练集特征 :param y_train: 训练集标签 :param X_test: 测试集特征 :param y_test: 测试集标签 :return: 准确率 """ knn_classifier = KNeighborsClassifier(n_neighbors=k, n_jobs=-1) knn_classifier.fit(X_train, y_train) y_pred = knn_classifier.predict(X_test) acc = accuracy_score(y_test, y_pred) return acc # 设置K值为5,调用KNN函数 acc = knn(5, X_train, y_train, X_test, y_test) print('准确率:%.2f%%' % (acc * 100)) ``` 运行代码后,得到手写体数字识别的准确率为97.07%,即使用KNN算法成功实现手写体数字识别。 总结: 本文介绍了利用Python实现KNN算法实现手写体数字识别的方法。通过调用Sklearn库中KNeighborsClassifier类实现算法,并对MNIST数据集进行处理和拆分,最终得到准确率较高的识别结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值