K-Nearest-Neighbour 算法简介

###background 元旦放假前,team的同事们想要一起学习一些技术,然后一起做些小东西,有人提到将物理墙上的卡,通过手机拍照,识别出其中的卡号,然后与电子墙同步状态。这是一个非常有意思的主题,会涉及到很多方面的知识,其实有好几个topic,只不过我对人工智能/机器学习等比较有兴趣而已,所以就先自己研究下。 几天下来,关于数字识别的基本的流程已经清晰了,关于图片的预处理及边界标定等都差不多就绪了,剩下比较重要的是识别本身了。在这个过程中,遇到了一些很有意思的算法,我自己也花费了好几天才弄明白,所以整理了一下,这一篇先介绍下第一个,也是最简单最好用的KNN算法。 ###K-nearest-neighbour简介 KNN是机器学习中最简单的一种无值守的学习方法,但是在实际场景中,效果却经常非常好。一般来说,在样本较多,分布均匀的空间中,KNN会收到很好的效果。但是由于KNN会计算空间中的每个点与需要标定的点的距离(甚至需要计算额外的权重信息),所以计算量会较大。 假设所有的点都均匀的分布在一个平面内,此时的平面密度(单位范围内的点的个数)非常大,而每个子平面内的点的分布与所有点在整个平面内的分布相当。在子平面S中,有一个点Y,则离点X(to be classified)最近的Y很可能与Y同在子平面S中。 比如取出空间中与X距离最近的有5个点(K=5),其中3个属于C1类,2个属于C2类,则根据少数服从多数原则,X点被归类为C1.这样的一个缺点就是如果空间内的点分布不均匀,那么会有一些误差,如果上面这个场景经常出现,那么分类会越来越偏离(有一个偏心的硬币,投掷100,000次,有90,000次正面)。这样就有引入了对KNN的另一个扩展方式,加入权重的KNN: 当然这种形式的KNN不是很精确,由此引申出了带权重的KNN:可以为每个点都赋予一个权值,每个权值与新的点X的距离有关,通常会取距离的倒数,这样与X最近的点有较高的权重,而较远的点具有较低的权重,这样在投票(voting)阶段可以相对的提高精确度 ###KNN的一个python版本示例 ####背景(高斯分布) import random def gauss_list(mu, sigma, count=100): return [random.gauss(mu, sigma) for _ in range(count)] 生成一个随机数数组,数组中的元素符合高斯分布,如 ran = gauss_list(-2, 1, 10) print ran 运行结果如下: [-1.3277188634970218, -2.1034487392146817, -0.5924407591392826, -0.30376289085064045, -2.191337071105794, -1.9781081550478732, -3.7937155472105673, -2.538102349796847, -1.3728510997834549, -2.766669661625006] 更进一步,我们可以用这种方式生成平面中的一些点,这些点可以根据分布情况分为两组,一组是以(-4,0)为重心的500个点,另一组是以(4,0)为重心的500个点: def gauss_cluster(center, stdDev, count=500): return [(random.gauss(center[0], stdDev), random.gauss(center[1], stdDev)) for _ in range(count)] def make_random_data(): return gauss_cluster((-4, 0), 1) + gauss_cluster((4, 0), 1) data = make_random_data() ####绘制高斯分布...

January 3, 2013 1 min

为什么每个开发人员都应该使用Mac系统

##为什么每个开发人员都应该使用Mac系统 在使用了Mac系统大概10个月之后,我已经深深的喜欢上了在其上做开发的体验,精美的界面,人性化的设计,强大的硬件系统,安全而稳定的软件系统,下面我将会用Mac系统和Windows做一个简单的对比,最后会有一些推荐的工具列表。 ###Mac系统的一些好处 1. 系统非常稳定,很少发生死机或者运行缓慢之类问题 2. 即使在休眠之后,也可以飞速(与windows相比)启动 3. 内置的命令行工具非常强大 4. 大量内置的优秀软件 基本上来说,Mac系统就是一个比Windows的UI漂亮,又比Linux的命令行好用的操作系统。苹果之前的广告说他们的系统是世界级的优秀系统,这一点毫无夸张,Mac OS确实是世界上最好的操作系统,没有之一。 个人感觉,使用Mac OS能明显提高开发效率,使得用于解决真正问题的时间提高,而折腾的时间减少,使用windows系统,有很多的时间是在与系统做斗争,或者在等待系统如蜗牛般的加载,说起windows的多任务简直就是笑话,而且有很多无耻的进程在甚至在任务管理器中都不能完全杀死,更不要提病毒之类的话题了。 人们使用计算机的一个典型过程应该是:命令->响应,如是循环,这也是用Mac系统的典型过程。但是使用windows的过程是这样的:命令->等待->响应,或者命令->死机->…。我有一台Thinkpad笔记本,4G内存/250G硬盘,Windows 7系统,按说配置还算可以,运行速度也勉强能接受,但是跟同级别硬件配置用来跑Mac系统的话,效率据保守估计会提高32倍。 我觉得对一个合格的开发人员来说,命令行技能,即使不是最重要的,也应该是第二重要的,Mac下的命令行非常好用,有很多shell可供选择,Linux用户可以没有任何学习曲线的转移到Mac的命令行中(bash),如果觉得默认的bash不顺手,也可以很轻易的切换到zsh,csh之类,很多的Linux知识可以直接用在Mac上,毫无挫败感。 Mac系统中内置了很多的软件,也有一些可以免费获得的优秀软件(下面列表中有很大一部分软件都是免费的),很多人觉得Mac下什么软件都要收费,我觉得软件收费无可非议,每个软件都倾注了作者(一个或者多个)的大量心血,绝对是合情合理,特别是对于开发人员更是如此(但是,如果开发的软件如windows般垃圾而还要收费的话,那就让人忍不住要骂人了)。 ###一些工具的推荐 ####编辑器 编辑器几乎是开发人员每天接触最多的工具,也最能体现一个开发人员的品味和level,不过在Mac下有所有主流的编辑器,或者其替代品: 1. GVim 2. Emacs 3. Sublime Text 2 ####IDE 说实话,我并不喜欢使用IDE,最开始是因为在纯命令行下工作,没有可用的IDE,后来是因为它在一定程度上阻碍了初学者对编译/链接/加载整个过程的理解(所以现在还是不建议初学者直接从IDE开始学习编程),再后来开始使用jetbrains系列的IDE,除了体积较重,偶尔会有焦点缺失的bug外,基本完美,开发效率会非常高,世界顶级,没有之一 (下面里表中前两者都要收费,而且价格不菲,但是一分钱一分货): 1. Intellij Idea (Java) 2. Rubymine (Ruby) 3. Eclipse (全能,理论上你可以将器配置成任何语言的IDE) ####电子书阅读 电子书阅读我需要一个可以记录上次读到了什么地方,最近打开的书单之类的功能,正好preview都提供,因此也没有专门去找过有没有更好用的: 1. Preview (图片,PDF等都可以preview,很好用) ####笔记 个人经验,经常性的将实际开发中遇到的问题,好的设计方式,好的测试用例等记录下来是一个非常好的学习方式,另外在工作的时候,会看到一些非常精彩的文章,可以通过(read it later)记录下来,然后同步到自己的笔记本中,回家或者是休息的时候再看: 1. Evernote 2. Pocket (read it later) ####同步 我是一个不折不扣的同步控,我的dropbox中的内容在Mac Book,iPhone和windows机器上都会同步,很多资料找起来会非常方便,比如一些经典的书籍,一些图片素材等,我都会在dropbox中放一份,如果别人需要也很容易分享: 1. Dropbox 2....

January 1, 2013 1 min

git子命令之squash

There is a common scenario: we have lots of local commits related with a certain feature or a big bug, after all the works done, we want to combine them together. The git provides a handy way to do this job: git rebase I’ll take the following case as an example, say, I’ve got 3 commits locally and they are all about a restyling of some page. $ git st...

November 7, 2012 2 min

ssh forward 101

Generate the public and private key pair This step is quite strightforward, just generate the keys by using ssh-keygen: $ ssh-keygen #specify the key file name (I use the id_ plus remote site hostname) then you’ll get 2 keys locally, you can do this step in any place, but people do it on their home-dir/.ssh, after the creation, you need to change the mask of the key file: $ chmod 600 id_site...

October 25, 2012 2 min

Hamcrest里的自定义匹配器

Although we can write tests all by the default matchers that hamcrest provided, but somehow we need the code to be more readable, and maintainable, so it’s a good way to try customize our own matchers. We discussed how to TDD in last post, and in the book class we talked: @Test public void shouldGetBookInfo(){ Book book = new Book("The Ruby programming language", "Development"); assertThat(book.getName(), is("The Ruby programming language")); assertThat(book.getCategory(), is("Development")); } The default is matcher can get the job done, but not that readable, we can simply provide a customized matcher for this case:...

October 15, 2012 1 min