您的位置:首页 > 其它

机器学习实战第二章kNN算法详解

2017-08-26 12:44 465 查看
from numpy import *

import operator

from os import listdir

#2.1.2 k-近邻算法

def classify0(inX, dataSet, labels, k):    #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             #求出各个训练集与输入向量的距离,并以数组形式存储在变量distance中

    sortedDistIndicies = distances.argsort()    #将distance中的元素从小到大排列,提取其对应的index(索引),然后输出到sortedDistIndicies中      

    classCount={}                           

    for i in range(k):

        voteIlabel = labels[sortedDistIndicies[i]]

        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1   #对距离最小的k个点添加标签并以字典方式存储在classCount中

    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)#对字典内的元祖按照降序第二个元素(标签所对应元素的频率)排列存储在数组sortedClassCount中(此时字典内的键为标签,值为对应标签的频率)

    return sortedClassCount[0][0]       #返回频率最高的元素标签

 #2.1.1 创建数据集和标签

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

    

#2.2.1   从文本中解析数据

def file2matrix(filename):          

    fr = open(filename)                         #打开文件

    numberOfLines = len(fr.readlines())         #获得文件行数

    returnMat = zeros((numberOfLines,3))        #创建一个全部为0名称为returnMat的矩阵

    classLabelVector = []                       #创造一个空向量来存储数据,当作方法结束返回向量 

    fr = open(filename)                         

    index = 0

    for line in fr.readlines():

        line = line.strip()                     #截取回车字符

        listFromLine = line.split('\t')         #将上一步得到的数据分割为元素列表

        returnMat[index,:] = listFromLine[0:3]  #每三个元素为一组存储到特征矩阵中

        classLabelVector.append(int(listFromLine[-1]))  #通过索引值-1将列表的最后一列元素存储到向量classLabelVector中

        index += 1                                  

    return returnMat,classLabelVector

    

#2.2.3 归一化特征值    

def autoNorm(dataSet):

    minVals = dataSet.min(0)                #minVals 每一列的最小值

    maxVals = dataSet.max(0)                #maxVals 每一列的最大值

    ranges = maxVals - minVals              

    normDataSet = zeros(shape(dataSet))     #创建一个长度为dataSet的维度值的0向量

    m = dataSet.shape[0]                    #读取dataSet的第一维长度存储在变量m中

    normDataSet = dataSet - tile(minVals, (m,1))    #将变量内容变成与输入矩阵同样大小的矩阵        

    normDataSet = normDataSet/tile(ranges, (m,1))   #特征值归一化公式

    return normDataSet, ranges, minVals

   

 #2.2.4 约会网站测试代码   

def da
a274
tingClassTest():

    hoRatio = 0.10      #hold out 10%

    datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')       #从文件中读取数据

    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)   #将以上取得的数据输入到kNN分类函数classify0中

        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 ("thr errorCount is: %d "  % errorCount)              #计算错误率并输出结果

    

    

#2.3.1 将图像转化为测试向量    

def img2vector(filename):

    returnVect = zeros((1,1024))        #创建一个1*1024的0向量

    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')           #读取文件内容

    m = len(trainingFileList)

    trainingMat = zeros((m,1024))           #创建m*1024的训练矩阵

    for i in range(m):

        fileNameStr = trainingFileList[i]

        fileStr = fileNameStr.split('.')[0]     

        classNumStr = int(fileStr.split('_')[0])     

        hwLabels.append(classNumStr)            #从文件名中切割出分类的数字并加入在向量hwLables中

        trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)    #用img2vector函数载入图像

    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]     

        classNumStr = int(fileStr.split('_')[0])

        vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)     #同上一个循环功能类似,切割出分类数字

        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) #用classify0函数测试该目录下的每一个文件

        print ("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))

        if (classifierResult != classNumStr): errorCount += 1.0     #对错误数据进行统计

    print ("\ntotal numbers:  %d" % mTest)

    print ("\nthe total number of errors is: %d " % errorCount)

    print ("\nthe total error rate is: %f" % (errorCount/float(mTest)))         #输出结果

    

#handwritingClassTest()  

#datingClassTest()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: