1. from numpy import *
  2. import operator
  3. import matplotlib
  4. import matplotlib.pyplot as plt
  5. from imp import *
  6. #from os import *
  7. import os
  8.  
  9. reload(operator)
  10.  
  11. def start():
  12. group,labels = createDataSet()
  13. testSample = [5,7]
  14. print("测试样本:" ,end="")
  15. print(testSample)
  16.  
  17. return classify0(testSample, group, labels, 4)
  18.  
  19. def createDataSet():
  20.  
  21. group = array([[1,2],[2,3],[1,1],[4,5]]) #此处随意定义,表示一个已知的已分类的数据集
  22. labels = ['A','A','B','B']
  23.  
  24. #例如
  25. #group = array([[1,2],[2,3],[1,1],[4,5],[5,7],[6,6]]) #此处随意定义,表示一个已知的已分类的数据集
  26. #labels = ['A','A','B','B','C','C']
  27.  
  28. return group, labels
  29.  
  30. def classify0(inX, dataSet, labels, k):
  31. """
  32. inX 是输入的测试样本,是一个[x, y]样式的
  33. dataset 是训练样本集
  34. labels 是训练样本标签
  35. k 是top k最相近的
  36. """
  37.  
  38. # 矩阵的shape是个tuple,如果直接调用dataSet.shape,会返回(4,2),即
  39. # 返回矩阵的(行数,列数),
  40. # 那么shape[0]获取数据集的行数,
  41. # 行数就是样本的数量
  42. # shape[1]返回数据集的列数
  43. dataSetSize = dataSet.shape[0]
  44.  
  45. ###################说明代码########################
  46. #print("dataSet.shape[0]返回矩阵的行数:")
  47. #print(dataSetSize)
  48. #print("dataSet.shape[1]返回矩阵的列数:")
  49. #cols = dataSet.shape[1]
  50. #print(cols)
  51. #print(dataSet.shape)
  52. #print("dataSet.shape类型:")
  53. #print(type(dataSet.shape))
  54. ###################################################
  55.  
  56. #此处Mat是Maxtrix的缩写,diffMat,即矩阵的差,结果也是矩阵
  57. #关于tile函数的说明,见http://www.cnblogs.com/Sabre/p/7976702.html
  58. #简单来说就是把inX(本例是[1,1])在“行”这个维度上,复制了dataSetSize次(本例dataSetSize==4),在“列”这个维度上,复制了1次
  59. #形成[[1,1],[1,1],[1,1],[1,1]]这样一个矩阵,以便与dataSet进行运算
  60. #之所以进行这样的运算,是因为要使用欧式距离公式求输入点与已存在各点的距离
  61.  
  62. #这是第1步,求给出点[1,1]与已知4点的差,输出为矩阵
  63. diffMat = tile(inX,(dataSetSize,1)) - dataSet
  64. #print(tile(inX,(dataSetSize,1)))
  65.  
  66. ###################说明代码########################
  67. #print("diffMat:" + str(diffMat))
  68. ###################################################
  69.  
  70. #第2步,对矩阵进行平方,即,求差的平方
  71. sqDiffMat = diffMat ** 2
  72.  
  73. ###################说明代码########################
  74. #print("sqDiffMat:" + str(sqDiffMat))
  75. #print("sqDiffMat",end="")
  76. #print(sqDiffMat[324])
  77. ###################################################
  78.  
  79. #sum(axis=1)是将矩阵中每一行中的数值相加,如[[0 0] [1 1] [0 1] [9 9]]将得到[0,2,1,18],得到平方和
  80. #sum(axis=0)是将矩阵中每一列中的数值相加
  81. #第3步,求和
  82. sqDistances = sqDiffMat.sum(axis=1)
  83. #print("sqDistances:", end="")
  84. #print(sqDistances[875])
  85.  
  86. ###################说明代码########################
  87. #print("sqDistances:" + str(sqDistances))
  88. ###################################################
  89.  
  90. #第4步,将平方和进行开方,得到距离,输出为数组
  91. distances = sqDistances ** 0.5
  92.  
  93. ###################说明代码########################
  94. #print("未知点到各个已知点的距离:",distances)
  95. ###################################################
  96.  
  97. #argsort(),将数组中的元素的索引放在由小到大的位置上由小到大排序
  98. #如数组a = array([ 0 4 3 18]),b = a.argsort()之后,得到b是[0 2 1 3]这是a的索引数组,最小的在最前面,位置0,第二小的是索引为2的元素,即3,3在数组中的位置是2
  99. #第三小的是索引为1的,即4,4在数组中的索引位置是2,第四小的是索引为3的,即18
  100. #这样保证了原数组元素的位置不变,以便进行标签的匹配
  101. #print(distances[875])
  102. #print(distances[324])
  103. #print(distances[392])
  104. sortedDistIndicies = distances.argsort()
  105.  
  106. ###################说明代码########################
  107. #print("索引位置:", sortedDistIndicies) #可得到前k个索引
  108. ###################################################
  109.  
  110. #创建空字典
  111. classCount = {}
  112.  
  113. #k值是取前k个样本进行比较
  114. for i in range(k):
  115. #返回distances中索引为sortedDistIndicies[i]的值
  116. #此例中分别为:
  117. #sortedDistIndicies[0]==0,则labels[0]=='A',voteIlabel=='A'
  118. #sortedDistIndicies[1]==2,则labels[2]=='B',voteIlabel=='B'
  119. #sortedDistIndicies[2]==1,则labels[0]=='A',voteIlabel=='A'
  120. #sortedDistIndicies[3]==18,则labels[0]=='B',voteIlabel=='B'
  121.  
  122. voteIlabel = labels[sortedDistIndicies[i]]
  123. #print("中华人民共和国")
  124. ###################说明代码########################
  125.  
  126. # print(voteIlabel)
  127. # print("标签" + str(i) + ":" + str(voteIlabel))
  128. ###################################################
  129.  
  130. #dict.get(key, default=None),对于键 key 返回其对应的值,或者若 dict 中不含 key 则返回 default(注意, default的默认值为 None,此处设置为0)
  131. #第一次调用classCount.get时,classCount内还没有值
  132. classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
  133.  
  134. ###################说明代码########################
  135. # print("第"+str(i+1)+"次访问,classCount[" + str(voteIlabel) + "]值为:" + str(classCount[voteIlabel]))
  136. # print("classCount的内容为:")
  137. # print(classCount)
  138. ###################################################
  139.  
  140. # sorted(iterable[,cmp,[,key[,reverse=True]]])
  141. # 作用:Return a new sorted list from the items in iterable.
  142. # 第一个参数是一个iterable,返回值是一个对iterable中元素进行排序后的列表(list)。
  143. # 可选的参数有三个,cmp、key和reverse。
  144. # 1)cmp指定一个定制的比较函数,这个函数接收两个参数(iterable的元素),如果第一个参数小于第二个参数,返回一个负数;如果第一个参数等于第二个参数,返回零;如果第一个参数大于第二个参数,返回一个正数。默认值为None。
  145. # 2)key指定一个接收一个参数的函数,这个函数用于从每个元素中提取一个用于比较的关键字。默认值为None。
  146. # 从python2.4开始,list.sort()和sorted()函数增加了key参数来指定一个函数,此函数将在每个元素比较前被调用
  147. # key参数的值为一个函数,此函数只有一个参数且返回一个值用来进行比较。这个技术是快速的,因为key指定的函数将准确地对每个元素调用。
  148. # key=operator.itemgetter(0)或key=operator.itemgetter(1),决定以字典的键排序还是以字典的值排序
  149. # 0以键排序,1以值排序
  150. # 3)reverse是一个布尔值。如果设置为True,列表元素将被倒序排列。
  151. # operator.itemgetter(1)这个很难解释,用以下的例子一看就懂
  152. # a=[11,22,33]
  153. # b = operator.itemgetter(2)
  154. # b(a)
  155. # 输出:33
  156. # b = operator.itemgetter(2,0,1)
  157. # b(a)
  158. # 输出:(33,11,22)
  159. # operator.itemgetter函数返回的不是值,而是一个函数,通过该函数作用到对象上才能获取值
       # 在这里itemgetter(1)的作用是按照第二个元素的顺序对元组进行排序,也就是value的顺序,如果改成itemgetter(0),则根据Key值排序
  1. sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)
  2.  
  3. #print(sortedClassCount)
  4.  
  5. #返回正序排序后最小的值,即“k个最小相邻”的值决定测试样本的类别
  6. print("最终结果,测试样本类别:" , end="")
  7. print(sortedClassCount)
  8. return sortedClassCount[0][0]

以下为输出结果,未必完全一致,请自行调试。

输出结果:

dataSet.shape[0]返回矩阵的行数:

dataSet.shape[1]返回矩阵的列数:

(4, 2)
dataSet.shape类型:
<class 'tuple'>
diffMat:[[ 2 1]
[ 1 0]
[ 2 2]
[-1 -2]]
sqDiffMat:[[4 1]
[1 0]
[4 4]
[1 4]]
sqDistances:[5 1 8 5]
未知点到各个已知点的距离: [ 2.23606798 1. 2.82842712 2.23606798]
索引位置: [1 0 3 2]
标签0:A
第1次访问,classCount[A]值为:1
classCount的内容为:
{'A': 1}
标签1:A
第2次访问,classCount[A]值为:2
classCount的内容为:
{'A': 2}
标签2:B
第3次访问,classCount[B]值为:1
classCount的内容为:
{'A': 2, 'B': 1}
标签3:B
第4次访问,classCount[B]值为:2
classCount的内容为:
{'A': 2, 'B': 2}
[('A', 2), ('B', 2)]
最终结果,测试样本类别:A
[Finished in 5.3s]

《机器学习实战》中的程序清单2-1 k近邻算法(kNN)classify0都做了什么的更多相关文章

  1. 机器学习实战 - python3 学习笔记(一) - k近邻算法

    一. 使用k近邻算法改进约会网站的配对效果 k-近邻算法的一般流程: 收集数据:可以使用爬虫进行数据的收集,也可以使用第三方提供的免费或收费的数据.一般来讲,数据放在txt文本文件中,按照一定的格式进 ...

  2. 机器学习(四) 分类算法--K近邻算法 KNN (上)

    一.K近邻算法基础 KNN------- K近邻算法--------K-Nearest Neighbors 思想极度简单 应用数学知识少 (近乎为零) 效果好(缺点?) 可以解释机器学习算法使用过程中 ...

  3. 机器学习(四) 机器学习(四) 分类算法--K近邻算法 KNN (下)

    六.网格搜索与 K 邻近算法中更多的超参数 七.数据归一化 Feature Scaling 解决方案:将所有的数据映射到同一尺度 八.scikit-learn 中的 Scaler preprocess ...

  4. 《机器学习实战》---第二章 k近邻算法 kNN

    下面的代码是在python3中运行, # -*- coding: utf-8 -*- """ Created on Tue Jul 3 17:29:27 2018 @au ...

  5. 机器学习 Python实践-K近邻算法

    机器学习K近邻算法的实现主要是参考<机器学习实战>这本书. 一.K近邻(KNN)算法 K最近邻(k-Nearest Neighbour,KNN)分类算法,理解的思路是:如果一个样本在特征空 ...

  6. 机器学习(1)——K近邻算法

    KNN的函数写法 import numpy as np from math import sqrt from collections import Counter def KNN_classify(k ...

  7. 机器学习随笔01 - k近邻算法

    算法名称: k近邻算法 (kNN: k-Nearest Neighbor) 问题提出: 根据已有对象的归类数据,给新对象(事物)归类. 核心思想: 将对象分解为特征,因为对象的特征决定了事对象的分类. ...

  8. 机器学习实战python3 K近邻(KNN)算法实现

    台大机器技法跟基石都看完了,但是没有编程一直,现在打算结合周志华的<机器学习>,撸一遍机器学习实战, 原书是python2 的,但是本人感觉python3更好用一些,所以打算用python ...

  9. 机器学习实战笔记(Python实现)-01-K近邻算法(KNN)

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  10. 02机器学习实战之K近邻算法

    第2章 k-近邻算法 KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法是一种基本分类与回归方法,我们这里只讨论分类问题中的 k-近邻算法. 一句话总结:近朱者赤近墨者黑! k ...

随机推荐

  1. centos7 更改主机名

    在CentOS或RHEL中,有三种定义的主机名:a.静态的(static),b.瞬态的(transient),以及 c.灵活的(pretty).“静态”主机名也称为内核主机名,是系统在启动时从/etc ...

  2. laravel 5.3升级5.4

    1)修改 composer 配置文件 composer.json 1.如果你用了 laravel-admin,larvel-admin 版本改 1.4.x-dev 2.laravel 版本改 5.4. ...

  3. PostgreSQL存储过程(4)-return语句

    1. return语句 有三个命令可以用来从函数中返回数据: RETURN RETURN NEXT RETURN QUERY 2. RETURN命令 语法: RETURN RETURN express ...

  4. Ansible Playbook handlers 语句

    handlers 用法如下,表示当 tasks 执行成功之后再执行 handlers,相当于 shell 中的 && 用法,如果 tasks 执行失败是不会执行 handlers 语句 ...

  5. Django 创建第一个项目

    创建项目: [root@localhost ~]$ django-admin.py startproject web # web是项目名 [root@localhost ~]$ tree web/ w ...

  6. Android应用程序的结构

    1.src目录 存放该项目的源代码 2.gen目录 该目录文件是ADT自动生成的,并不需要认为地去修改 3.Android2.1 该目录存放的是该项目支持的JAR包,同时还包含项目打包时需要的META ...

  7. 《Mysql 入门很简单》(读后感①)

    下载完整版<Mysql 入门很简单>,点击这里~: http://files.cnblogs.com/files/zhengyeye/MySQL%E5%85%A5%E9%97%A8%E5% ...

  8. gitlab数据迁移

    由于gitlab是默认安装的,随着公司代码越来越多,导致gitlab数据目录空间不足,出现无法访问gitlab了. 磁盘空间: /home有1.8T的空间一直没用上! 现在打算将原有代码目录迁移到新目 ...

  9. ECMAScript 面向对象JS学习笔记1

    1.对象的 prototype 属性,可以把它看成创建新对象所依赖的原型.===在我理解,就是prototype下设置的字段是唯一性的,共享性的,不管创建多少个对象,所处空间都是不变的,没有增加也没有 ...

  10. echarts - 特殊需求实现方案汇总

    五分钟上手echarts echarts中 设置x||y轴文案.提示文字等为固定字数,超出显示"..." 关于echarts下钻功能的一些总结.js echarts - 特殊需求实 ...