《机器学习实战》斧头书——第二章—KNN算法(2)——手写巨多的数字识别

《机器学习实战》斧头书——KNN

对文章的说明

对本文有几点说明如下:

  1. 我是一个刚学没多久的小白,所以代码可能也会有错误,欢迎各位大佬提出我的问题,感谢;
  2. 对于python版本 ,斧头书《机器学习实战》是用的2.x,本文使用的是3.x,然后代码的话,有的是参考书上的和网上的,还有部分是自己写的;
  3. 用的参考书是下面这本,封面拿了个斧头的人,这本书没有调库,都是用python写的底层代码,感觉对理解算法原理会更深入一点;

需要识别的数字例子

在这里插入图片描述

代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os,sys
def l_knn(k,data,new): #自己封装一个函数,形参为k,data为已有的数据,new为需要判断类型的数据,都是DataFrame的数据类型
    m = new.shape[0] #946
    n = data.shape[1]-1 
    result2 = []
    for i in range(m):
        distance = (((data.iloc[:,:-2] - new.iloc[i,:-2])**2).sum(1))**0.5 #sum(1)是横的相加,0是竖的相加
        #code和word分别与new做差,然后平方,求和,开根号,就是欧氏距离。
        distance_new = pd.DataFrame({'juli':distance,'number':data.iloc[:,-1]}) #用算好的距离那列替代原来的2列
        d2=distance_new.sort_values(by='juli')[:k] #根据juli距离这一列来排序
        result = d2.loc[:,'number'].value_counts().index[0] #根据values的值来counts频率,排第一的就是结果啦
        result2.append(result)
    new['predict'] = result2
    accuracy = (new.iloc[:,-1]==new.iloc[:,-2]).mean()#'number'和'predict'这2列对比
    # print(distance_new.sort_values(by='juli'))
    print("KNN模型用于手写数字识别预测的准确率是:",accuracy*100,"%")
    print("KNN模型用于手写数字识别预测的损失率是:",(1-accuracy)*100,"%")
def img2vector(filename):#将32*32的图像转换成一个1*1024的格式
    vector_new = np.zeros((1,1024))
    fr = open(filename) #打开文件
    for i in range(32):
        fhang = fr.readline() #读取整个txt文件的行,共32行,执行一次读一行,再执行一次就读下一行,最后读到第32行
        for j in range(32):
            vector_new[0,i*32+j] = int(fhang[j])
    fr.close() #关闭文件
    return vector_new
#分别获取训练集和测试集
def train_df():
    trainlist = os.listdir('D:\\python_writing\\digits\\trainingDigits')
    filelabel = []
    for i in range(len(trainlist)):#110-------1934
        trainlist1 = trainlist[i]
        filename1 = trainlist1.split('.')[0] #分开的结果是0_13
        file2 = filename1.split('_')[0] #分开的结果是0
        filelabel.append(file2) #制作标签label
        a = 'digits/trainingDigits/%s'%trainlist1
        q1024 = img2vector(a)
        if i==0:
            dfq = pd.DataFrame(q1024) #第一次是创建df,后面再加入新的行
        if i>0:
            dfq = dfq.append(pd.DataFrame(q1024))
    dfq['label']=list(filelabel)
    return dfq
def test_df():
    testlist = os.listdir('D:\\python_writing\\\\digits\\testDigits')
    file2label = []
    for i in range(len(testlist)):#110-------946
        testlist1 = testlist[i]
        filename1 = testlist1.split('.')[0] #0_13
        file2 = filename1.split('_')[0]
        file2label.append(file2) #0
        a = 'digits/testDigits/%s'%testlist1
        q1024 = img2vector(a)
        if i==0:
            dfq = pd.DataFrame(q1024)
        if i>0:
            dfq = dfq.append(pd.DataFrame(q1024))
    dfq['label']=list(file2label)
    return dfq
df = train_df()
df2 = test_df()
l_knn(5,df,df2)

看一下结果吧,准确率98.2%。

真的,运行一次要好久好久,10多分钟的感觉。
在这里插入图片描述

总结

1、KNN算法比较简单,但是数据量多的话,运行一次要很久很久很久,这个的运行一次就挺久的,一开始算法出了问题,于是每个数字只取了0-10的数据集,这样方便快速调试。
2、学会了怎么读取文件和提高split获取标签值,进一步熟悉了pandas的用法。
3、那个文件的路径名,中间分开竟然是用2个\,一开始用的1个\(从我的电脑里复制的)怎么都获取不到数据,后来用os获取当前文件名才知道的。
4、多写几个子函数,更方便点。
5、其实一开始是在Jupyter notebook上写的,那个方便看结果,全部写好后,再去pycharm上封装起来,方便以后的使用。
6、谢谢阅读,我是刚学不久的小白,有错误的话欢迎各位大佬提出来,共同进步,谢谢了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值