美文网首页
<<机器学习实战>>---KNN

<<机器学习实战>>---KNN

作者: 芮芮cat | 来源:发表于2017-10-29 23:59 被阅读0次

    理论

    K-近邻算法是一种基于计算向量距离的方法来判断的算法,具体描述见书,下面把我这次学习到的python语法及代码贴下来

    语法

    1.shape()查看矩阵或者数组的维数,shape[1] 为第一维的长度,c.shape[0] 为第二维的长度
    2.tile(orginal, (a,b))将原来的矩阵行复制b倍,列复制a倍

    1. **是乘方的意思
    2. get() 函数返回指定键的值,如果值不在字典中返回默认值。dict.get(key, default=None)

    5.sorted()方法升序排列,key参数的值为一个函数,此函数只有一个参数且返回一个值用来进行比较。这个技术是快速的因为key指定的函数将准确地对每个元素调用。
    6.Operator 模块函数有itemgetter,attrgetter用复杂对象的某些值来对复杂对象的序列排序,参数reverse(True or False)来表示升序或降序排序
    7.Python 字典(Dictionary) items()方法用于返回字典dict的(key,value)元组对的列表
    8.zeros(x,y)构建x*y维值为0的矩阵
    9.Python strip() 方法用于移除字符串头尾指定的字符(默认为空格)。
    10.Python split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串 str.split(str="", num=string.count(str)).
    11.classLabelVector.append(int(listFromLine[-1])) # 把该样本对应的标签放至标签集,顺序与样本集对应。 python语言中可以使用-1表示列表中的最后一列元素
    12.figure()返回一个Figure对象
    13.add_subplot返回一个Axes对象,参数111表示画布分割为1行1列,图像画在第一块
    14.ax.scatter(datingDataMat[:,1], datingDataMat[:,2])#散点图使用datingDataMat矩阵的第二、第三列数据
    15.list[start:end(not include):step] list索引的起始位,结束位,步长
    16.其中dataSet.min(0)中的参数0使得函数可以从列中选取最小值,而不是选取当前行的最小值。
    17.a = np.array([[1,5,3],[4,2,6]])
    print(a.min()) #无参,所有中的最小值
    print(a.min(0)) # axis=0; 每列的最小值
    print(a.min(1)) # axis=1;每行的最小值
    结果:
    1
    [1 2 3]
    [1 2]
    18.对于ndarray的切片,格式为[x1:x2, y1:y2],截取行数为[x1,x2),列数为[y1,y2)。左边闭空间,右边开空间。 如果要截取某一行,格式为[x,:],截取某一列:[:,y] 其他截取以此类推
    19.readline()是不是调用一次下一次调用就会自动读取下一行,readlines是读取全部形成一个list
    20.listdir可 以 列 出 给 定 目 录 的 文 件 名 。

    1. 语法:str.split(str="", num=string.count(str))[n]
      参数说明:
      str: 表示为分隔符,默认为空格,但是不能为空('')。若字符串中没有分隔符,则把整个字符串作为列表的一个元素
      num:表示分割次数。如果存在参数num,则仅分隔成
      num + 1
      个子字符串,并且每一个子字符串可以赋给新的变量
      [n]: 表示选取第n个分片
      注意:当使用空格作为分隔符时,对于中间为空的项会自动忽略

    输入

    trainingDigits
    testDigits
    是将图像以数字0和1矩阵储存的文本文件

    代码

    from numpy import  *
    import operator
    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    from os import listdir
    
    def createDataSet():
        # array =
        # # tuple(array)
        group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
        # tuple(array)
        labels = ['A', 'A', 'B', 'B']
        return group, labels
    
    
    def  classify0(intX, dataSet, labels, k):  #返回前K个可能性的类别
        dataSetSize = dataSet.shape[0]
        #shape()查看矩阵或者数组的维数,shape[1] 为第一维的长度,c.shape[0] 为第二维的长度
        diffMat = tile(intX, (dataSetSize, 1)) - dataSet
        #tile(orginal, (a,b))将原来的矩阵行复制b倍,列复制a倍
        sqDiffMat = diffMat ** 2
        #  **是乘方的意思
        #相加为一个列向量
        sqDistances = sqDiffMat .sum(axis = 1)
        #开方
        distances = sqDistances ** 0.5
        #从小到大排序,返回该值在原来值中的索引
        sortedDistIndicies = distances.argsort()
        classCount = {}
        #计算在邻居中哪一类最多
        for i in range(k):
            voteIlabel = labels[sortedDistIndicies[i]]
            classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
            # get() 函数返回指定键的值,如果值不在字典中返回默认值。dict.get(key, default=None)
        sortedClassCount = sorted(classCount.items(),  key = operator.itemgetter(1), reverse = True)
        #sorted()方法升序排列,key参数的值为一个函数,此函数只有一个参数且返回一个值用来进行比较。这个技术是快速的因为key指定的函数将准确地对每个元素调用。
        #Operator 模块函数有itemgetter,attrgetter用复杂对象的某些值来对复杂对象的序列排序,参数reverse(True or False)来表示升序或降序排序
        #Python 字典(Dictionary) items()方法用于返回字典dict的(key,value)元组对的列表
        return sortedClassCount[0][0]
    
    def file2matrix(filename): # 从文件中读入训练数据,并存储为矩阵
        fr = open(filename)
        arrayOLines = fr.readlines()
        numberOfLines = len(arrayOLines)
        returnMat = zeros((numberOfLines, 3))
        #zeros(x,y)构建x*y维值为0的矩阵
        classLabelVector = []
        index = 0
        for line in arrayOLines:
            line = line.strip()
            #Python strip() 方法用于移除字符串头尾指定的字符(默认为空格)。
            listFromLine = line.split('\t')
            #Python split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串  str.split(str="", num=string.count(str)).
            returnMat[index, :] = listFromLine[0:3]# 把分割好的数据放至数据集,其中index是该样本数据的下标,就是放到第几行
           # labels = {'didntLike': 1, 'smallDoses': 2, 'largeDoses': 3}
            classLabelVector.append(int(listFromLine[-1])) # 把该样本对应的标签放至标签集,顺序与样本集对应。 python语言中可以使用-1表示列表中的最后一列元素
            index += 1
        return returnMat, classLabelVector
    
    #datingDataMat,datingLabels = file2matrix('C:/Users/LRT/PycharmProjects/M_learn/datingTestSet.txt')
    # print(datingDataMat,datingLabels)
    
    def matpt():#画散点图
        fig = plt.figure()#figure()返回一个Figure对象
        ax = fig.add_subplot(111)#add_subplot返回一个Axes对象,参数111表示画布分割为1行1列,图像画在第一块
        #ax.scatter(datingDataMat[:,1], datingDataMat[:,2])#散点图使用datingDataMat矩阵的第二、第三列数据
        #list[start:end(not include):step]   list索引的起始位,结束位,步长
        ax.scatter(datingDataMat[:,1], datingDataMat[:,0], 15.0*array(datingLabels), 15.0*array(datingLabels))#利用变量datingLabels存储的类标签属性,在散点图上绘制了色彩不等、尺寸不同的点
        plt.show()
    
    
    def autoNorm(dataSet):   #归一化特征值
        minVals = dataSet.min(0)#其中dataSet.min(0)中的参数0使得函数可以从列中选取最小值,而不是选取当前行的最小值。
    # a = np.array([[1,5,3],[4,2,6]])  
    # print(a.min()) #无参,所有中的最小值  
    # print(a.min(0)) # axis=0; 每列的最小值  
    # print(a.min(1)) # axis=1;每行的最小值 
    # 结果:
    # 1
    # [1 2 3]
    # [1 2]
        maxVals = dataSet.max(0)
        ranges = maxVals - minVals
        normDataSet = zeros(shape(dataSet))
        m = dataSet.shape[0]
        normDataSet = dataSet - tile(minVals, (m,1))
        normDataSet = normDataSet/tile(ranges, (m,1))
        return normDataSet, ranges, minVals
    
    
    # normMat, ranges, minVals = autoNorm(datingDataMat)
    # print(normMat, ranges, minVals)
    
    def datingClassTest():
        hoRatio = 0.50      #hold out 10%
        datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')       #load data setfrom file
        normMat, ranges, minVals = autoNorm(datingDataMat)
        m = normMat.shape[0]
        numTestVecs = int(m*hoRatio)
        errorCount = 0.0
        for i in range(numTestVecs):
            classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)  #normMat前numTestVecs数量的列作为测试集,后numTestVecs数量的列为训练集
            #  对于ndarray的切片,格式为[x1:x2, y1:y2],截取行数为[x1,x2),列数为[y1,y2)。左边闭空间,右边开空间。  
            #  如果要截取某一行,格式为[x,:],截取某一列:[:,y]  
            #  其他截取以此类推 
            print ("the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]))
            if (classifierResult != datingLabels[i]): errorCount += 1.0
        print ("the total error rate is: %f" % (errorCount/float(numTestVecs)))
        print(errorCount)
    
    # datingClassTest()
    
    def classifyPerson():   #预测约会对象喜欢程度函数
        resultList = ['not at all', 'in small doses', 'in large doses']
        percenTags = float( input("percentage of time spent playing video game?"))
        ffMiles = float(input("frequent filer miles earned per year?"))
        iceCream = float(input("liters of ice cream consumed per years?"))
        datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
        normMat, ranges, minVals = autoNorm(datingDataMat)
        inArr = array([ffMiles, percenTags, iceCream])
        #numpy中封装的array有很强大的功能,里面存放的都是相同的数据类型
        classifierResult = classify0((inArr-minVals)/ranges, normMat, datingLabels, 3)
        print("you will probably like this person", resultList[classifierResult - 1])
    
    
    # classifyPerson()
    
    
    def img2vector(filename):   #将图像转化为向量
        returnVect = zeros((1, 1024))
        fr = open(filename)
        for i in range(32):
            lineStr = fr.readline()#readline()是不是调用一次下一次调用就会自动读取下一行,readlines是读取全部形成一个list
            for j in range(32):
                returnVect[0, 32 * i + j] = int(lineStr[j])
        return returnVect
    
    # testVector = img2vector('testDigits/0_13.txt')
    # print(testVector[0, 0:31])
    
    
    def handwritingClassTest():
        hwLabels = []
        trainingFileList = listdir('trainingDigits')           #load the training set      listdir可 以 列 出 给 定 目 录 的 文 件 名 。
        m = len(trainingFileList)
        trainingMat = zeros((m,1024))
        for i in range(m):
            fileNameStr = trainingFileList[i]
            fileStr = fileNameStr.split('.')[0]     #take off .txt
            classNumStr = int(fileStr.split('_')[0])
            # 语法:str.split(str="", num=string.count(str))[n]
            # 参数说明:
            # str:   表示为分隔符,默认为空格,但是不能为空('')。若字符串中没有分隔符,则把整个字符串作为列表的一个元素
            # num:表示分割次数。如果存在参数num,则仅分隔成
            # num + 1
            # 个子字符串,并且每一个子字符串可以赋给新的变量
            # [n]:   表示选取第n个分片
            # 注意:当使用空格作为分隔符时,对于中间为空的项会自动忽略
            hwLabels.append(classNumStr)
            trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
        testFileList = listdir('testDigits')        #iterate through the test set
        errorCount = 0.0
        mTest = len(testFileList)
        for i in range(mTest):
            fileNameStr = testFileList[i]
            fileStr = fileNameStr.split('.')[0]     #take off .txt
            classNumStr = int(fileStr.split('_')[0])
            vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)
            classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
            print ("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
            if (classifierResult != classNumStr): errorCount += 1.0
        print ("\nthe total number of errors is: %d" % errorCount)
        print ("\nthe total error rate is: %f" % (errorCount/float(mTest)))
    
    handwritingClassTest()
    

    相关文章

      网友评论

          本文标题:<<机器学习实战>>---KNN

          本文链接:https://www.haomeiwen.com/subject/xvbupxtx.html