学习 machine learning 的最低要求是什么?  我发觉要求可以很低,甚至初中程度已经可以。  首先要学习一点 Python 编程,譬如这两本小孩子用的书:【1】【2】便可。   数学方面,只需要知道「两点间距离」的公式(中学的座标几何会读到)。

这本书第二章介绍 kNN 算法,包括 Python 程序:

其他章节的数学要求可能不同,但我目的是想说明,很多实用的人工智能的原理,其实也很简单的。

kNN 是什么?  For example:

开始时,所有 data points 的 labels (颜色)已经是知道的。

kNN 要解决的问题是:  图中那「?」点的 label 应该是什么颜色?

用肉眼直观来看,那「?」的位置,是在蓝色点密集的区域,所以最「贴切」的标签应该是蓝色。

kNN 的算法就是:

  • 在已知的 data points 中,逐一点检视(把這每一點叫作 P):
    • 首先计算「?」和 P 之间的距离
  • 所有距离计算之后,将他们由小至大 sort 好
  • 从 sort 好的序列,取最前的 k 个(即距离最接近「?」的 k 个点子)
  • 对这 k 个点,读出他们的 label(颜色)是什么,这是问题中已经知道的
  • 所有这些 labels(颜色),哪个出现最多?  (亦即是说,最接近「?」的 k 个点子,它们最普遍是什么颜色?)
  • 这出现次数最多的颜色,就是答案

例如,使用者要求 k = 5 时:

最接近「?」的 5 个点,就是以「?」为中心的虚线圆圈内的 5 个点。  它们的颜色顺序依次为:[ ⬤,⬤,⬤,⬤,⬤ ] 。  出现的次数是 4⬤  1⬤ ,所以最高次数的颜色是 ⬤ 。

如何用 Python 写 kNN ?

1. 计算点与「?」之间距离

首先,回忆中学的坐标几何里,两点间距离的公式。  假设那两点是 A 和 B,它们的座标分别是 $(x_A, y_A)$ 和 $(x_B, y_B)$,则:

$$ \mbox{distance D} = \sqrt{ (x_A - x_B)^2 + (y_A - y_B)^2 } $$

注意,在这公式里,用 $x_A - x_B$ 还是 $x_B - x_A$ 是没有分别的,因为那是正数和负数的分别,而在 $()^2$ 之后便没有分别。(换句话说,计算 A,B 之间的距离,和计算 B,A 之间的距离,是一样的。)

每个点子有 3 个坐标,分别是: x = 「坐飞机旅程」、y = 「吃雪糕的量」、z = 「玩电玩时间」,而 labels 是: 「很喜欢」、「普通喜欢」、「不喜欢」。

因为坐标有 3 个,所以处理的空间是 3 度空间,但为了初学者方便,我们只考虑其中两个座标,所以局限在 2 度空间(平面上)。   如果要 generalize 到 N-度空间,那需要用到 N-度空间中 两点间距离的公式,留给读者作为练习 ☺

写程式时,首先要知道那些点子是如何储存於某个 variable 中。  在书中的 "dating" 例子里,那些点子的坐标是 datingDataMat,而 labels 是储存在 datingLabels。

(妳可以在 Python 命令行,呼叫 file2matrix 函数去准备那些点子,然后试试印出 datingDataMat 和 datingLabel 这两个 variables 的内容。 例如 datingDataMat[ : , 1 ] 可以印出所有点子的第二个坐标(即吃雪糕量)。 那「:」的意思是,不指定指标的 begin 和 end,所以是对那个指标「全取」。)

我们用比较浅显的方法重写书中的 Python 函数(書裡的程式用了 vector 和 matrix 的表示法,比較簡潔,但較難懂):

  1. def classify1(inP, dataSet, labels, k):
  2. N = len(dataSet)
  3. Ds = array([0] * N)
  4. for i in range(N):
  5. x2 = (inP[0] - dataSet[i][0])**2
  6. y2 = (inP[1] - dataSet[i][1])**2
  7. D = sqrt(x2 + y2)
  8. Ds[i] = D

第 1 句: 定义我们的 function。  inP 是 input point 的意思。

第 2 句: N 是我们 dataSet 的 size,即总共有多少点子。

第 3 句: 我们要计算距离 D,而且有 N 个这样的距离,所以要将结果储存在 array 里。  但使用 array 之前,要先定义它,并填上 0(这叫初始化,initialize)。  Ds 这名字的意思是「很多D」(如英语中的 dogs = dog 的众数)。

第 4 句是 loop:  对於每一点,我们用 i 这个 index「指着」它。  Index 是处理 array 的惯用做法,因为 array 容许妳读取任意位置的元素。

第 5、6 句:  计算 $\Delta x^2$ 和 $\Delta y^2$ 的值,注意,因为我们储存 x, y 的方法是 [x, y] 这样的 list, 所以 x 用指标 [0] 读取,y 用指标 [1] 读取。

第 7 句: 计算 $D = \sqrt{ \Delta x^2 + \Delta y^2 }$。

第 8 句: 将计算好的 D 放进 array Ds 里。

2. 将距离排序

很简单,一句:

  1. Dsorted = Ds.sort()

注意,這些程式段落要適當地 indent 好,不然 Python 會出錯的。  这句仍屬於 classify1 函数。

3. 读出点的颜色

刚才说错了,因为 Ds 排序之后,再弄不清哪个点子对应於哪个 label,所以我们要用的是 "arg sort" (argument sort,即是用 指标 来排序)。

例如,设 a = array( [17, 38, 10, 49] ),

a.sort() 会给出 [10, 17, 38, 49],

但 a.argsort() 会给出 [2, 0, 1, 3],这些是 indices(指标)。

换句话说: argsort 的结果是 旧的 indices 的新的排法

Python 程式:

  1. D_sorted = Ds.argsort()
  2. first_k = D_sorted[0:k] # 提取前 k 个元素(但這句其實不需用到)

现在要找出这 k 个点子的 labels,我们可以创造一个新的 array 储存它们:

  1. first_k_labels = array([0]*k) # 准备空的 array
  2. for i in range(0,k):
  3. first_k_labels[i] = labels[ D_sorted[ i ]]

最后那句要说明一下: 如果写 labels[i] 那就是第 i 个元素的 label。 但我们要的是 排序 好之后的元素的 label,所以我们先「look up」这个 D_sorted array,找出排序后的元素的指标,再用那指标「look up」那 labels array。  (就像查字典,我们想查某个中文字的日语翻译,但我们只有汉英字典和英日字典,所以要两次 look up,出现了 array1[ array2[ i ] ] 这样的语法。 这是很常见的。)

4. 哪个颜色出现最多?

用这个 loop 计算每个 label 出现的次数:

  1. like1 = 0 标签是「不喜欢这男孩」 的点的个数
  2. like2 = 0 标签是「普通喜欢这男孩」的点的个数
  3. like3 = 0 标签是「非常喜欢这男孩」的点的个数
  4. for i in range(0, k):
  5. label = first_k_labels[i]
  6. if label == 1:
  7. like1 += 1
  8. elif label == 2:
  9. like2 += 1
  10. elif label == 3:
  11. like3 += 1

然后,找出出现次数最多那个 label:

  1. if like1 > like2 and like1 > like3: # 如果 like1 出现最多
  2. best_label = 1 # 答案是「不喜欢这男孩」
  3. elif like2 > like1 and like2 > like3: 如果 like2 出现最多
  4. best_label = 2 # 答案是「普通喜欢这男孩」
  5. else: 如果 like3 出现最多
  6. best_label = 3 # 答案是「非常喜欢这男孩」

5. 完工!

  1. return best_label

Testing

实际的 Python program,还要加上这几行 "header":

  1. # -*- coding: utf-8 -*- # 加了這句可以用中文 comments
  2.  
  3. from numpy import array
  4. from math import sqrt

运行结果:

这例子里,「?」的坐标是 [4.54e+04, 4.98e+00],那是我看了数据后作出来的。 4.54e+04 是 scientific notation,即是 $4.54 \times 10^4$。

我把 k 增加到 600,才开始看到 like2 不是 0。

什么是 kNN 算法?的更多相关文章

  1. 【Machine Learning】KNN算法虹膜图片识别

    K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  2. KNN算法

    1.算法讲解 KNN算法是一个最基本.最简单的有监督算法,基本思路就是给定一个样本,先通过距离计算,得到这个样本最近的topK个样本,然后根据这topK个样本的标签,投票决定给定样本的标签: 训练过程 ...

  3. kNN算法python实现和简单数字识别

    kNN算法 算法优缺点: 优点:精度高.对异常值不敏感.无输入数据假定 缺点:时间复杂度和空间复杂度都很高 适用数据范围:数值型和标称型 算法的思路: KNN算法(全称K最近邻算法),算法的思想很简单 ...

  4. 数据挖掘之KNN算法(C#实现)

    在十大经典数据挖掘算法中,KNN算法算得上是最为简单的一种.该算法是一种惰性学习法(lazy learner),与决策树.朴素贝叶斯这些急切学习法(eager learner)有所区别.惰性学习法仅仅 ...

  5. 机器学习笔记--KNN算法2-实战部分

    本文申明:本系列的所有实验数据都是来自[美]Peter Harrington 写的<Machine Learning in Action>这本书,侵删. 一案例导入:玛利亚小姐最近寂寞了, ...

  6. 机器学习笔记--KNN算法1

    前言 Hello ,everyone. 我是小花.大四毕业,留在学校有点事情,就在这里和大家吹吹我们的狐朋狗友算法---KNN算法,为什么叫狐朋狗友算法呢,在这里我先卖个关子,且听我慢慢道来. 一 K ...

  7. 学习OpenCV——KNN算法

    转自:http://blog.csdn.net/lyflower/article/details/1728642 文本分类中KNN算法,该方法的思路非常简单直观:如果一个样本在特征空间中的k个最相似( ...

  8. KNN算法与Kd树

    最近邻法和k-近邻法 下面图片中只有三种豆,有三个豆是未知的种类,如何判定他们的种类? 提供一种思路,即:未知的豆离哪种豆最近就认为未知豆和该豆是同一种类.由此,我们引出最近邻算法的定义:为了判定未知 ...

  9. Python 手写数字识别-knn算法应用

    在上一篇博文中,我们对KNN算法思想及流程有了初步的了解,KNN是采用测量不同特征值之间的距离方法进行分类,也就是说对于每个样本数据,需要和训练集中的所有数据进行欧氏距离计算.这里简述KNN算法的特点 ...

随机推荐

  1. MySQL之远程登录配置

    1.注释掉mysql配置文件中的这一行:#bind-address  = 127.0.0.1 2.给指定服务器的用户授权:GRANT ALL PRIVILEGES ON *.* TO root@&qu ...

  2. Redis常用命令入门5:有序集合类型

    有序集合类型 上节我们一起学习了集合类型,感受到了redis的强大.现在我们接着学Redis的最后一个类型——有序集合类型. 有序集合类型,大家从名字上应该就可以知道,实际上就是在集合类型上加了个有序 ...

  3. javascript和jquey的自定义事件小结

    “通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率.” 可以把多个关联但逻辑复杂的操作利用自定义事件的机制灵活地控制好 对象之间通过直接方法调用来交互 1)对象A直接调用 ...

  4. Java8之——简洁优雅的Lambda表达式

    Java8发布之后,Lambda表达式,Stream等等之类的字眼边慢慢出现在我们字眼.就像是Java7出现了之后,大家看到了“钻石语法”,看到了try-with-resource等等.面对这些新东西 ...

  5. Python future模块

    今天看到了Pyhon中的模块__future__,查了一下资料,感觉这个module很有用. 从python2.1开始以后, 当一个新的语言特性首次出现在发行版中时候, 如果该新特性与以前旧版本pyt ...

  6. Android studio 提示:Can't use Subversion command line client: svn Probably the path to Subversion executable is wrong. Fix it.

    1.参考来源:http://my.oschina.net/fyyy/blog/519353 按照下图,svn相关选项不要选.

  7. Android中的dp, px, pt

    定义: px是像素,表示屏幕显示的最小元素单位 pt是磅数,一磅等于1/72英寸,一般用来作为字体的单位使用 问题: px和pt不使用于手机,因为同样的px在高低分辨率的手机上显示的比例不同 解决办法 ...

  8. 获取数据库表详细信息、存储过程、视图、的sql

    select s.[name] + '.' + t.[name] as tablename from sys.tables as t,sys.schemas as s where t.schema_i ...

  9. win7下安装Sass和compass

    由于项目需要我们使用到sass来编译css文件.本人在win7下开发 由于国内安装sass遇到了一些困难,后来不得不网查询,后来终于解决了,这里介绍一下 1.要安装sass环境必须要先安装rubyIn ...

  10. Python 2.7 因为少写括号导致的 SyntaxError 错误

    贴代码: # -*- coding: utf-8 -*- # 控制缩进tab数量 def GetTabStr(tab_num): tab_str = "" for i in xra ...