监督学习——K邻近算法及数字识别实践

1. KNN 算法

        K-近邻(k-Nearest Neighbor,KNN)是分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

         K邻近算法原理很简单,但是真正用好它也不容易,比如K的取值到底为多少才合适,而且知道什么场景下用它更不简单。

         缺点:  该算法的执行效率并不高,每次计算都需要将 待识别的用例 与所有测试用例进行求差计算,计算量较大。随着测试数据的增多,计算量会越来越大。

2. 数字识别 Python 实现

        下图为一个 二进制表示的数字“6”,每个训练数据和测试数据都是以这种形式保存在一个txt文件中,数据为32*32(1024个数据)的矩阵。

20171230175900503

 

KNN算法实现数字识别步骤

1. 读取训练数据中的所有数据到一个矩阵中(矩阵中的每一列代表一个图片数据),同时读取数据的标签保存在一个数组中(数据的标签或患者说文件代表的具体数字信息在文件命中)

2. 读取测试数据,转换1024*1的矩阵。

3. 用测试数据与矩阵A中的每一列求距离,求得的L个距离存入距离数组中(距离算法)

4. 从距离数组中取出最小的K个距离所对应的训练集的索引

5. 拥有最多索引的值就是预测值(有多个众数时,按距离和最小)

数据加载函数

该函数用于打开一个数字数据源(32*32),保存在一个1*1024的矩阵中

def openFile(fileName):
    returnVect = np.zeros((1,1024))
    fr = open(fileName)
    for i in range(32):
        linestr = fr.readline();
        for j in range(32):
            returnVect[0,32*i+j] = int(linestr[j])
    return returnVect

如果需要加载某个文件夹下的所有数字文件则可以调用如下函数(数字的标签保存在文件名中第一个字符)

def loadData(dir):
    fileList = listdir(dir)  // 列出dir文件下的所有文件(测试数据)
    lable = []
    index = 0
    dataMat = np.zeros((1024,len(fileList)))
    for file in fileList:
        lable.append(int(file[0]));  // 标签信息保存在文件的第一个字符中
        dataMat[:,index] = openFile(dir+file)
        index +=1;
    return dataMat,lable

距离计算函数

该函数用于计算两个图片举证(1*1024)的距离,(相同位置如果数字相同则距离加1)

def caculateerro(data1,data2):
    len1 = len(data1)
    len2 = len(data2)
    sizelen = min(len1,len2);
    totalerro = 0;
    for i in range(sizelen):
        if data1[i] != data2[i]:
            totalerro +=1
    return totalerro

数字识别函数

def classFier(datain):
    k=15
    dictErro = {} //保存 训练数据编号——测试数据与该训练数据的距离
    trainingdata, traninglabel = loadData('digits\\trainingDigits\\');
    m,n = trainingdata.shape;

    for i in range(n):
        // 计算测试图片与每张训练图片的距离
        currErro = caculateerro(datain,trainingdata[:,i])
        dictErro[i] = currErro
    sortedDict = sorted(dictErro.items(),key=lambda x:x[1],reverse=False);
    numofnumber = range(10)

    for i in range(10):
        numofnumber[i] = 0
    for j in range(30):
        label = int(sortedDict[j][0])
        numofnumber[int(traninglabel[label])] += 1;
    return numofnumber.index(max(numofnumber))

        上述源码中KNN算法的K取值为15,即取出距离训练数据最小的十五个图片,然后判断这15张图片中对应的那个数字出现的平率最多,将最多的数据作为识别结果返回。

 

参考:

《机器学习实战》

https://blog.csdn.net/zzz_cming/article/details/78938107

posted @ 2018-05-19 10:11  NeilZhang  阅读(1484)  评论(0编辑  收藏  举报