zoukankan      html  css  js  c++  java
  • 机器学习2—K近邻算法学习笔记

           Python3.6.3下修改代码中def classify0(inX,dataSet,labels,k)函数的classCount.iteritems()为classCount.items(),另外print在Python新版本下是函数,print后面需加上一对括号,否则执行会报错。

    classify0详解

    import numpy as np
    #用于分类的输入向量是inX,输入的训练样本集为dataSet,
    #标签向量为 labels ,最后的参数 k 表示用于选择最近邻居的数目,其中标签向量的元素数目和矩
    #阵 dataSet 的行数相同。
    def classify0(inX,dataSet,labels,k):
        # 获取 数组 形状的 第一个 参数 a=[[1,2],[1,2],[1,2]]  a.shape = [3,2] a.shape[0] = 3
    # 一、
        dataSetSize = dataSet.shape[0]
        # tile 代表了inX,复制为dataSetSize行,1列的数组
    # 二、
        diffMat = np.tile(inX,(dataSetSize,1))-dataSet
        # 平方
        sqDiffMat = diffMat**2
        # axis 等于 1 是将 矩阵的每一行 相加
        sqDistances = sqDiffMat.sum(axis=1)
        # 开方
        distances = sqDistances**0.5
    # 三、
        # 从小到大 排列,argsort : 将distacnces中的元素从小到大排列,提取其对应的index(索引),然后输出到sortedDistances 
        sortedDistances = distances.argsort()
        classCount = {}
    # 四、求出来 最低距离 的 labels结果,存放在classCount 中
        for i in range(k):
            #取第i+1个邻近的样本对应的类别标签
            voteIlabel =labels[sortedDistances[i]]
            #以标签为key,标签出现的次数为value将统计到的标签及出现次数写进字典
            classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
            #对字典按value从大到小排序
        sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
            #返回排序后字典中最大value对应的key
        return sortedClassCount[0][0]

     以下注解参考

    #将文本记录转换为Numpy的解析程序  
    def file2matrix(filename):  
            
          fr=open(filename)     #打开文件  
            
          arrayOLines=fr.readlines()   #获取文件所有行  
            
          numberOfLines=len(arrayOLines)     #得到文件行数  
            
          returnMat=zeros((numberOfLines,3))   #先用零元素创建需要返回的numpy矩阵,(行数,列数)  
            
          classLabelVector=[]    # 创建空的标签列表  
            
          index=0  
            
          for line in arrayOLines:  
                  
                line=line.strip()   #截取掉尾部的回车字符  
                  
                listFromLine=line.split('	')  #用‘	’作为分隔符将整行元素分割成元素列表,将一行数据按空进行分割,  
                  
                returnMat[index,:]=listFromLine[0:3] #选取列表前三个元素到=矩阵中  
                  
                classLabelVector.append(listFromLine[-1]) #将列表的最后一列存储到向量中  
                  
                index += 1  
                  
          return returnMat,classLabelVector  #返回数据集矩阵和对应的标签向量  
    #归一化特征值      
    def autoNorm(dataSet):  
            
        minVals = dataSet.min(0)  #找到数据集中的最小值(实际上应该是样本数据中的一列中的最小值,参数0就代表这个,下同),这样说的话minVals和maxVals都应该是一个行向量(1*n)  
          
        maxVals = dataSet.max(0)   #找到数据集中的最大值  
          
        ranges = maxVals - minVals    #得到数据的范围差值  
          
        normDataSet = zeros(shape(dataSet))     # 定义空的要返回的归一化后的矩阵,该矩阵和传入的数据集是一样的大小  
          
        m = dataSet.shape[0]       #得到矩阵第一行的数据个数,也就是维数  
          
        normDataSet = dataSet - tile(minVals, (m,1))  #数据集与最小值相减(title()函数将按照括号中的参数制作对应大小的矩阵,用给定的minVals内容来填充  
          
        normDataSet = normDataSet/tile(ranges, (m,1))   #除以范围值之后就是归一化的值了。(注意是矩阵除法)  
          
        return normDataSet, ranges, minVals  
    #分类器针对约会网站的测试代码  
    def datingClassTest():  
            
        hoRatio = 0.10      #测试所占的比例  
          
        datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')       #将文件中的数据转换为矩阵形式和提取出标签矩阵  
          
        normMat, ranges, minVals = autoNorm(datingDataMat)    #对提取出的矩阵数据归一化处理  
          
        m = normMat.shape[0]   #获得数据总的条数  
          
        numTestVecs = int(m*hoRatio)    #得出作为测试的数据个数  
          
        errorCount = 0.0      #初始化错误个数为0  
          
        for i in range(numTestVecs):  #对测试的数据进行遍历  
                
            classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)    # 对数据进行分类  
              
            print("the classifier came back with: %s, the real answer is: %s" % (classifierResult, datingLabels[i]))   #输出分类结果和实际的类别(之前的代码有问题啊,要将%d,改为%s)  
              
            if (int(classifierResult) != int(datingLabels[i])): errorCount += 1.0    # 如果分类结果与实际结果不一致 ,错误数加1  
              
        print("the total error rate is: %f" % (errorCount/float(numTestVecs)))   # 输出错误率  
          
        print(errorCount)    #输出错误总数
    #约会网站预测函数  
    def classiyPerson():  
          
        resultList = ['not at all','in small doses','in large doses']         # 定义分类结果的类别  
         
        percentTats = float(raw_input("percentage of time spent playing video games?"))    # 读取输入数据   
         
        ffMiles = float(raw_input("frequent flier miles earned per year?"))     # 读取输入数据   
          
        iceCream = float(raw_input("liters of ice cream consumed per year?"))     # 读取输入数据   
          
        datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')         # 从文件中读取已有数据  
         
        normMat,ranges,minVals = autoNorm(datingDataMat)                     # 对数据进行归一化  
         
        inArr =array([ffMiles,percentTats,iceCream])                         # 将单个输入数据定义成一条数据  
          
        classifierResult = classify0(inArr,datingDataMat,datingLabels,3)      # 对输入数据进行分类  
         
        print('You will probably like this person: %s' % (resultList[int(classifierResult) - 1]))       # 输出预测的分类类别
    # 将单个手写字符文件变成向量   
    def img2vector(filename):  
            
        returnVect = zeros((1,1024))   #创建要返回的1*1024的矩阵并初始化为0  
          
        fr = open(filename)    # 打开文件  
          
        for i in range(32):    #从0到31行遍历  
                
            lineStr = fr.readline()   #读取一行(自动成为一个列表)  
              
            for j in range(32):  #从0到31列  
                    
                returnVect[0,32*i+j] = int(lineStr[j])   #将一行中的每个元素复制到要返回的矩阵中  
                  
        return returnVect   #返回该1*1024的矩阵 
    # 手写字符识别测试  
    def handwritingClassTest():  
            
        hwLabels = []      # 定义手写字符标签(类别)   
          
        trainingFileList = listdir('trainingDigits')          # 列出目录下所有的文件  
          
        m = len(trainingFileList)            # 计算训练文件的数目  
          
        trainingMat = zeros((m,1024))        # 定义手写字符数据矩阵  
          
        for i in range(m):      # 依次读取每个文件  
                
            fileNameStr = trainingFileList[i]        # 依次获得文件名   
              
            fileStr = fileNameStr.split('.')[0]     # 对文件名进行分割  
              
            classNumStr = int(fileStr.split('_')[0])   # 获得文件名中的类标签  
              
            hwLabels.append(classNumStr)    # 把类标签放到hwLabels中  
              
            trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)     # 把文件变成向量并赋值到trainingMat这个矩阵中    
              
        testFileList = listdir('testDigits')       # 列出测试目录下的所有文件  
          
        errorCount = 0.0        # 定义错误数  
          
        mTest = len(testFileList)       # 获得测试文件数目  
          
        for i in range(mTest):     # 遍历测试文件  
                
            fileNameStr = testFileList[i]         # 定义测试文件名  
              
            fileStr = fileNameStr.split('.')[0]        # 对测试文件名进行分割  
              
            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" % (int(classifierResult), int(classNumStr)))       # 输出预测类别和实际类别  
              
            if (int(classifierResult) != int(classNumStr)): errorCount += 1.0      # 如果二者不一致,累加错误数量   
              
        print("
    the total number of errors is: %d" % errorCount)       # 输出分类错误的数目  
          
        print("
    the total error rate is: %f" % (errorCount/float(mTest)))          # 输出分类的错误率  

    第二章代码修改如下:

    from numpy import *
    import operator
    from os import listdir
    
    def classify0(inX, dataSet, labels, k):
        dataSetSize = dataSet.shape[0]
        diffMat = tile(inX, (dataSetSize,1)) - dataSet
        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
        sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
        return sortedClassCount[0][0]
    
    def createDataSet():
        group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
        labels = ['A','A','B','B']
        return group, labels
    
    def file2matrix(filename):
        fr = open(filename)
        numberOfLines = len(fr.readlines())         #get the number of lines in the file
        returnMat = zeros((numberOfLines,3))        #prepare matrix to return
        classLabelVector = []                       #prepare labels return   
        fr = open(filename)
        index = 0
        for line in fr.readlines():
            line = line.strip()
            listFromLine = line.split('	')
            returnMat[index,:] = listFromLine[0:3]
            classLabelVector.append(int(listFromLine[-1]))
            index += 1
        return returnMat,classLabelVector
        
    def autoNorm(dataSet):
        minVals = dataSet.min(0)
        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))   #element wise divide
        return normDataSet, 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)
            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)
        
    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,32*i+j] = int(lineStr[j])
        return returnVect
    
    def handwritingClassTest():
        hwLabels = []
        trainingFileList = listdir('trainingDigits')           #load the training set
        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])
            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("
    the total number of errors is: %d" % errorCount)
        print("
    the total error rate is: %f" % (errorCount/float(mTest)))
    View Code
  • 相关阅读:
    Python中的下划线(转)
    全面Python小抄(转)
    Python函数参数默认值的陷阱和原理深究(转)
    Python中的默认参数(转)
    PEP8 Python 编码规范整理(Python)
    PEP8中文翻译(转)
    这次面试就差不多了,你有什么问题需要问我呢?(转)
    MySQL事务隔离级别,锁(转)
    Web安全学习图径——系列课程推荐
    盗墓笔记—阿里旺旺ActiveX控件imageMan.dll栈溢出漏洞研究
  • 原文地址:https://www.cnblogs.com/Vae1990Silence/p/8108584.html
Copyright © 2011-2022 走看看