机器学习-14:MachineLN之kNN源码

我想说:

其实你坚持的东西都是有意义的,就好比给代码加注释,你真去做了就知道了;另外建议大家建立一个自己的工具箱,就像我建立一个MachineLP_tools,里面放可以复用的代码,然后支持大家开源,你手上现有的代码可能很快就会过时,希望能够在有效期内发挥最大的功效;最后建议自己搭建一个自己的机器学习训练框架,用着顺手、用着舒服、用着放心,比起相信别人,相信大家更相信自己。

下面是kNN代码和详细注释, 又是截图,哈哈,虽然好代码都是敲出来的但是需要文本的可以私聊我;kNN原理参考:MachineLN之kNN

# 下面就是kNN的核心公式,每次给代码加注释都能想起李皓宇老师  
def classify0(inX, dataSet, labels, k):  
    # 在矩阵中我们一般说行和列,而在图像中我们说的是宽和高,但是宽对应的是列,高对应的是行;  
    # 首先获取有样本集的数量,为什么? 这下一句就能看出来,为了给新的输入样本做广播,进行向量与矩阵的减法;  
    dataSetSize = dataSet.shape[0]  
    # dataSetSize行,1列; 进行矩阵减法;  
    diffMat = tile(inX, (dataSetSize,1)) - dataSet  
    # 下面三行就是平方求和取根号, 计算欧式距离; 也就是计算样本间的相似度;  
    sqDiffMat = diffMat**2  
    # 求和  
    sqDistances = sqDiffMat.sum(axis=1)  
    # 取根a号  
    distances = sqDistances**0.5  
    # 对新样本与各类别样本计算距离后排序,然后返回排序后的索引; (默认的是升序排列)  
    sortedDistIndicies = distances.argsort()  
    # 定义一个字典, 排序后的前k个值中含有类别的个数;  
    classCount={}  
    # 下面就是kNN中的k;            
    for i in range(k):  
        # 下面就是根据排序后的索引值,取出对应样本的标签值;  
        voteIlabel = labels[sortedDistIndicies[i]]  
        # 统计前排序后k个中个类别的数量; 这里的get用的很妙,前几天刚听同事提过,学习了;  
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1  
    # 对字典按照value进行排序; python2中可以用下面的方式,貌似python3貌似用不了;  
    # 如果没有好的方法; 那么可以用我这种比较笨拙的方法:但是返回的是列表;  
    ''''' 
    def dict2list(dic:dict):   
        #将字典转化为列表  
        keys = dic.keys()   
        vals = dic.values()   
        lst = [(key, val) for key, val in zip(keys, vals)]   
        return lst   
    # lambda生成一个临时函数   
    # d表示字典的每一对键值对,d[0]为key,d[1]为value   
    # reverse为True表示降序排序   
    stat = sorted(dict2list(stat), key=lambda d:d[1], reverse=True) '''  
    # 降序排列;   
    sortedClassCount = sorted(classCount.iteritems(), 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  
    # 定义返回样本的集二维数组; 只取了3个数据所以定义为3列;  
    returnMat = zeros((numberOfLines,3))        #prepare matrix to return  
    # 存放对应的标签;  
    classLabelVector = []                       #prepare labels return     
    fr = open(filenamea)  
    index = 0  
    # 读取文件中的每一行数据;  
    for line in fr.readlines():  
        # 去掉开头和结尾的符号的  
        line = line.strip()  
        # 由于文件中各数据是已制表符分开的,所以已制表符进行切割;  
        listFromLine = line.split('\t')  
        # 前三个是样本中的数据; 最后一个是标签;  
        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))  
    # 获取样本的集的数量; 用于对最小值 和 ranges进行广播; 用于后面矩阵的减法 和 除法;  
    m = dataSet.shape[0]  
    # 归一化的操作; 此处有问题; 可以查看 MachineLN之样本归一化;  
    normDataSet = dataSet - tile(minVals, (m,1))  
    normDataSet = normDataSet/tile(ranges, (m,1))   #element wise divide  
    return normDataSet, ranges, minVals  
  
  
# kNN 分类   
def datingClassTest():  
    # 设置一个比率,在0到1之间,用于将样本集设置多少训练集和多少为测试集;   
    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):  
        # 取第i个测试样本,通过训练集计算新样本的类别;  
        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):  
    # 用来存储每个图片拉成向量后的结果,这里的图片是32*32所以是1024;  
    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  
  
  
# 下面是手写体数字通过kNN进行识别;  
def handwritingClassTest():  
    # 用于存放样本类别  
    hwLabels = [a]  
    # 由于每张手写体的图是放在一个文件中;要将所有文件生成样本集;  
    # 获取文件夹中的所有文件;  
    trainingFileList = listdir('trainingDigits')           #load the training set  
    # 获取文件数量;  
    m = len(trainingFileList)  
    # 定义一个数组, m行(手写体数量),1024像素数;  
    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)  
        # 取第i个测试样本,通过训练集计算新样本的类别; k值仍为3  
        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))  

推荐阅读:

推荐阅读:

  1. 机器学习-1:MachineLN之三要素

  2. 机器学习-2:MachineLN之模型评估

  3. 机器学习-3:MachineLN之dl

  4. 机器学习-4:DeepLN之CNN解析

  5. 机器学习-5:DeepLN之CNN权重更新(笔记)

  6. 机器学习-6:DeepLN之CNN源码

  7. 机器学习-7:MachineLN之激活函数

  8. 机器学习-8:DeepLN之BN

  9. 机器学习-9:MachineLN之数据归一化

  10. 机器学习-10:MachineLN之样本不均衡

  11. 机器学习-11:MachineLN之过拟合

  12. 机器学习-12:MachineLN之优化算法

  13. 机器学习-13:MachineLN之kNN

  14. 机器学习-14:MachineLN之kNN源码

  15. 机器学习-15:MachineLN之感知机

  16. 机器学习-16:MachineLN之感知机源码

  17. 机器学习-17:MachineLN之逻辑回归

  18. 机器学习-18:MachineLN之逻辑回归源码

image

版权声明:本文为博主原创文章,未经博主允许不得转载。有问题可以加微信:lp9628(注明CSDN)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容