zoukankan      html  css  js  c++  java
  • 分类 kNN

    #coding=utf-8
    from numpy import *
    import operator
    from os import listdir
    import matplotlib
    import matplotlib.pyplot as plt
    
    #从文件当中读取内容,保存到矩阵当中
    #因为文件当中有两部分内容,一部分是三个原因,另一部分是结果
    def file2matrix(filename):
        fr=open(filename)
        numberOfLines=len(fr.readlines())#计算文件的行数
        returnMat=zeros((numberOfLines,3))#生成一个零矩阵
        classLabelVector=[]#生成一个序列,主要操作是切片
        fr=open(filename)
        index=0
        for line in fr.readlines():
            line=line.strip()#读取一行的内容
            listFromLine=line.split('	')#将line分割成3个列
            returnMat[index,:]=listFromLine[0:3]#取前三个到切片放到第index行
            classLabelVector.append(int(listFromLine[-1]))#取最后一个追加到classLabelVector
            index+=1#index自加
        return returnMat,classLabelVector
    
    #归一化数据
    def autoNorm(dataSet):
        #获取每一列的最小值,也就是说结果是一个3维的数组,数组的元素
        #是每一列到最小值
        #如果0改为1,那么获取到的是每一行的最小值,也就是一个数组
        minVals=dataSet.min(0)
        maxVals=dataSet.max(0)#获取每一列的最大值
        ranges=maxVals-minVals
        normDataSet=zeros(shape(dataSet))#生成一个零矩阵
    
        #shape,显示一个矩阵的行列,如果没有[0],那么输出
        #(1000,3)也就是1000行,3列,
        # [0]表示第一个元素(行),[1]表示第二个元素(列)
        m=dataSet.shape[0]#获取行的行的数然后复制给m
        #tile是一个复制函数,将minVals复制
        #行的方向上复制m次你,列的方向上复制1次
        normDataSet=dataSet-tile(minVals,(m,1))
        normDataSet=normDataSet/tile(ranges,(m,1))
        return normDataSet,ranges,minVals
    
    
    #绘图
    def draw():
        fig=plt.figure()
        ax=fig.add_subplot(111)
        datingDataMat,datingLabels= file2matrix('datingTestSet.txt')
        ax.scatter(datingDataMat[:,0],datingDataMat[:,1],
               15.0*array(datingLabels),15.0*array(datingLabels))
        plt.show()
    
    #分类
    def classify0(inX, dataSet, labels, k):
        #获取到dataSet的行数量
        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.iteritems(), key=operator.itemgetter(1), reverse=True)
        return sortedClassCount[0][0]
    
    
    
    #识别过程
    def datingClassTest():
        hoRatio=0.10
        #从文件当中读取txt文件,转化为矩阵
        datingDataMat,datingLabels=file2matrix('datingTestSet.txt')
        normMat,ranges,minVals=autoNorm(datingDataMat)
    
        m=normMat.shape[0]
        numTestVecs=int(m*hoRatio)
        errorCount=0.0
        #从1到100
        for i in range(numTestVecs):
            #第一个参数是待分类到矩阵
            #normMat[i,:]代表一个行,也就是矩阵的第i行的一位矩阵
            #normMat[numTestVecs:m,:]使用从100到1000行的矩阵去分类
            #datingLabels[numTestVecs:m]使用从100到1000行的结果去分类
            #3代表kNN当中的k
            classfierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],
                                        datingLabels[numTestVecs:m],3)
            print "机器人认为的结果是%d,正确的答案是:%d"%(classfierResult,datingLabels[i])
            if(classfierResult!=datingLabels[i]):
                errorCount+=1.0
        print "错误律是:%f" %(errorCount/float(numTestVecs))
    
    datingClassTest()
    
    """
    最初错误原因
    dataSet=file2matrix('datingTestSet.txt')
    print dataSet#有两个返回值,会把后一个返回值追加到dataSet上面,构成元祖
    print "*****************************"
    datingDataMat,datingLabels=file2matrix('datingTestSet.txt')
    print datingDataMat
    print "*****************************"
    print datingLabels
    """
    
  • 相关阅读:
    .JDBC访问数据库的基本步骤是什么?
    文本的四种编码方式
    实现不在栈中产生对象
    字符串链接和复制
    堆和栈的区别(详细)
    产生随机数字
    利用返回引用来操作结构体
    inline 内联函数可以避免函数重定义问题
    五大内存分区,堆与栈的区别(转)
    Strategy模式
  • 原文地址:https://www.cnblogs.com/yufenghou/p/3344082.html
Copyright © 2011-2022 走看看