《机器学习实战》第2章课后题——手写识别系统

学后面几张的时候卡住了,然后突然想回头再自己写一遍课后习题,毕竟第一遍有点对着书敲的意味。果不其然,自己回头重写总会有的地方有问题。

第二章是用的KNN算法,优点是精度高(结果看来的确很高),对异常值不敏感(我觉得是因为KNN算法要选出与当前距离最小的k个点,异常值肯定在很后面,所以根本排不上号),无数据输入假定(没能理解这个),缺点是计算复杂度高,空间复杂度高,这两点好理解。

from numpy import array
from os import listdir
import operator

def GetData(String):
    fl = open(String,'r')
    NumberName = String.split('.')[0].split('_')[0][-1]           #先以'.'为分界,再以'_'分界,这样最后一位就是图片的数字
    NumberList = []
    lines = fl.readlines()
    for line in lines:
        for i in range(len(line)-1):            #字符串最后一位是'\n',所以要减去一
            NumberList.append(int(line[i]))
    return NumberList, int(NumberName)

def GetDistances(x,y):            #传进来的时候,x,y都是list,公式是欧式公式
    x = array(x)
    y = array(y)
    d = x-y
    sqd = d**2
    sqdistances = sqd.sum()
    distances = sqdistances**0.5
    return distances

def KNN(dataSet, NumberNameSet, testdata, k):
    l = len(dataSet)
    Distances = []
    for i in range(l):
        Distances.append(GetDistances(dataSet[i],testdata))
    sortedDistances = array(Distances).argsort()            #argsort()返回array(Distances)排序后的值的索引值
    NumberNameDict = {}         #key是数字名字,value是出现的次数
    for i in range(k):
        if NumberNameSet[sortedDistances[i]] not in NumberNameDict:
            NumberNameDict[NumberNameSet[sortedDistances[i]]] = 0
        else:
            NumberNameDict[NumberNameSet[sortedDistances[i]]] += 1
    sortedNumberNameDict = sorted(NumberNameDict.items(),key=operator.itemgetter(1),reverse = True)
    return sortedNumberNameDict[0][0]

def HeadWriteDiscriminate():
    TrainFileList = listdir('PythonTest/机器学习/machinelearninginaction-master/Ch02/digits/trainingDigits')
    l = len(TrainFileList)
    DataSet = []
    NumberNameSet = []
    for i in range(l):
        String ='PythonTest/机器学习/machinelearninginaction-master/Ch02/digits/trainingDigits/' + TrainFileList[i]
        data,numbername = GetData(String)
        DataSet.append(data)
        NumberNameSet.append(numbername)
    TestFileList = listdir('PythonTest/机器学习/machinelearninginaction-master/Ch02/digits/testDigits')            #返回值是乱序的,不过无所谓拉
    m = len(TestFileList)
    right = 0
    count = 0
    for i in range(m):
        String = 'PythonTest/机器学习/machinelearninginaction-master/Ch02/digits/testDigits/' + TestFileList[i]
        testdata,testnumbername = GetData(String)
        if KNN(DataSet, NumberNameSet, testdata, 3) == testnumbername:
            right += 1
        count += 1
    print('预测准确率:'+ str(right/count))

这个地方与书上不同的是:

书上是将测试图片的特征值复制成很多行形成二维数组,二维数组的大小和训练图片的特征值集(N*1024)大小一样,然后直接对两个二维数组进行计算。我第一次做这个的时候,发现运行内存不够。所以将测试图片的特征值与特征值集的每行分别进行计算,这样就没之前那个问题了。

你可能感兴趣的:(机器学习)