《机器学习实战笔记--第一部分 分类算法:KNN算法 3》

现在我们要做一个小程序,通过输入一些信息,程序就会给出预测值。

将下面的代码加入KNN.py中:

def classifyPerson():
    resultList = ['not at all','in small doses','in large doses']
    percentTats = float(input("percentage of time spent playing video games?"))
    ffMiles = float(input("frequent filer miles earned per year?"))
    iceCream = float(input("liters of ice cream cosumed per year?"))
    datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
    normMat, ranges, minVals = autoNorm(datingDataMat)
    inArr = array([ffMiles, percentTats, iceCream])
    print(inArr)
    classifierResult = classify0((inArr-minVals)/ranges, normMat, datingLabels, 3)
    print("you will like the person:",resultList[classifierResult - 1])
    
classifyPerso()

我们将看到:


提示我们输入信息,然后会得到分类的数据。

我们已经完成了在数据上建立分类器。下面我们将在人们不太容易看懂的数据上使用分类器,我们将在二进制存储的图像数据上使用KNN。

示例:手写识别系统

下面我们将一步一步的构造使用KNN算法的手写识别系统。简单起见,我们只识别0-9,需要识别的数字已用图形软件处理,处理成具有相同的色彩和大小:宽高是32*32像素的黑白照片。尽管文本格式存储图像不能有效的利用内存空间,但是为了方便理解我们还是将图像转化程文本格式。

    为了给的训练和测试数据用上我们之前写好的分类器,所以我们要把32*32的二进制图像矩阵转换成1*1024的向量。

    首先,我们先编写函数img2vector,将图像转换成向量:创建1*1024的numpy数组,然后打开文件,循环读出文件的前32行,并将每行的前32个字符存储在numpy数组中,最后返回数组。

def img2vector(filename):
    returnVect = zeros((1,1024))
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVect[0,i*32+j] = int(lineStr[j])
    return returnVect

    我们可以看到

    现在我们已经将数据处理成分类器可以使用的格式了,接下来我们要把这些数据输入到分类器中,检测分类器的效果。

    程序handwritingClassTest()用来测试分类器代码,首先我们要导入listdir,它可以列出给定目录的文件名。

def handwritingClassTest():
    hwLabels = []
    trainingFileList = listdir('手写数字数据集的例子/trainingDigits')
    m = len(trainingFileList)
    trainingMat = zeros((m,1024))
    for i in range(m):
        fileNameStr = trainingFileList[i]
        #print(fileNameStr)
        fileStr = fileNameStr.split('.')[0]
        #print(fileStr)
        a = fileStr.split('_')[0]
        #print(a)
        classNumStr = int(a)
        hwLabels.append(classNumStr)
        trainingMat[i,:] = img2vector('手写数字数据集的例子/trainingDigits/%s'%fileNameStr)
    
    testFileList = listdir('手写数字数据集的例子/testDigits')
    errorCount = 0.0
    mTest = len(testFileList)
   
    for i in range(mTest):
        fileNameStr0 = testFileList[i]
        fileStr0 = fileNameStr0.split('.')[0]
        classNumStr0 = int(fileStr0.split('_')[0])
        vectorUnderTest = img2vector('手写数字数据集的例子/trainingDigits/%s'%fileNameStr0)
        classifierResult = classify0(vectorUnderTest,trainingMat,hwLabels,3)
        print('%d这个数字分类的结果是%d'%(classNumStr0,classifierResult))
        if classifierResult != classNumStr0:
            errorCount += 1
    print('总共错误的个数:%d'%errorCount)
    print('错误率是:%f'%(errorCount/float(mTest)))   

    我们会的到如下的结果:

    ...


    错误率仅为1.2%。但是我们在实际的运算当中,算法执行的效率并不高,因为算法需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度的浮点型运算,总计要计算900次。同时我们还需要为测试的向量准备2MB的空间存放。

以后我们将接触到K决策树,是KNN的优化版,可以节省大量的计算开销。

    小结:

    KNN是分类数据最简单有效的方法,我们通过两个实例讲述了如何让实现和使用KNN算法构造分类器。KNN是基于实例的学习,使用算法时我们必须要有接近实际数据的训练样本数据。KNN算法必须保存全部数据集,如果数据集很大,将会占用大量的存储空间,此外由于必须对数据集中的每个数据计算距离,实际使用时将很耗时间。
    KNN另一个缺陷是它无法给出任何数据的基础结构信息,因此我们也无法知晓平均实例样本和典型实例样本具有什么特征。下一章我们将使用概率方法处理分类问题,该算法可以解决这个问题。

猜你喜欢

转载自blog.csdn.net/qq_41635352/article/details/79978812