Skip to content


概念化”增强学习”(二)

就像做通信的都绕不过信息论,要研究增强学习也跑不掉MDP。

增强学习的基础理论:马尔科夫决策过程(MDP)

通过MDP可以符号化地定义一个多状态带时延反馈的增强学习过程。一个MDP包括一个状态集合S,一个操作集合A,一个反馈函数R:S×A->R,以及一个状态迁移概率函数T(s,a,s’): S×A->S。可以结合前文的图1里来理解这里符号的意义。

这个模型的求解很简单,要输出的最优策略\pi其实是一个状态到操作的映射函数S->A,即在什么状态下应采用什么操作是确定的(根据短时平稳性假设,至少是短时确定的)。为得到这样的策略,我们首先需要定义在状态s时不同操作所能获得的期望收益,并把这个收益最大化。以下公式即定义了这个期望最大的收益(这里使用的是无限视野带衰减的目标函数):


获得这个最大收益时所采取的策略:


这两个迭代式,在T和R都已知的情况下,可以通过初始化,然后迭代计算使得结果收敛,过程跟pagerank的计算差不多。而根据是对V*进行迭代还是对\pi进行迭代又产生了值迭代和策略迭代两种算法。性能上稍有不同,结果是一致的。值迭代又可以演化出增强学习的代表性算法Q-learning。

MDP是一个很理想化的模型,它假设了我们事先对环境的完全了解(转移概率函数T及反馈函数R),而增强学习要解决的问题恰恰是对环境信息的未知。虽然MDP模型并不具有现实可用的意义,但通过它我们定义了一整套的符号系统以及问题解决的途径,极大地简化了对问题的描述与求解。在理论上解决了一些抽象层面的问题后(如收敛性、计算复杂度),要把它推广到现实的应用,只要着眼于解决对T及R函数的估计或替代即可。那些看似没有实用价值的数学模型的意义就在于此。

一般情况下MDP的求解

在现实应用中,MDP的环境模型(T及R函数)的参数是未知的,所以增强学习的过程可以化归为一个参数估计问题,只要能通过逐步得到的数据迭代地修正模型参数或算法参数,就可以直接利用通过MDP推导得到的结果。要实现这个目的,也有两种方式:model-based(学习模型的参数并把估计得到的模型应用于策略输出)和model-free(不断根据数据输入调整策略的输出,而无需估计具体的模型)的。两种实现方式各有千秋,一般来说model-free的方法需要更多的迭代步数才能收敛,但需要更少的环境知识,而model-based的方法则正好相反。由于这里主要是概念性的描述,欲求更多细节与方法实现的,可参看文后的文献。

增强学习潜在的应用场景

由于增强学习解决的是一类问题,所以它在自适应控制、机器人控制、博弈等等领域都有广泛的应用。从增强学习与有监督学习的对比可以看到,增强学习特别适用于那些没有启动数据的环境。搞推荐系统的朋友,这个时候你是不是瞬间就想到了冷启动问题。

博弈论的情景

以我粗浅的理解,可以把博弈论所讨论的问题理解为群体式的增强学习。每一个agent都与其它agent交互,并把对方的反馈视为环境的输入,agent必须学习在这个环境里最优的生存法则。比增强学习更为复杂的是,这个时候的环境是非稳定的,你在调整策略的同时,其它agent也在调整着自身的策略。一个著名的例子是囚徒困境的实验,多位社会精英为自己的agent设计出理想的增强学习型算法,但最后获胜的却是最简单的策略:以牙还牙。个中的奥妙颇是耐人寻味,在multi-agent博弈的环境里,非线性的因素是不可建模亦不可被预测到的,回归到最基本的策略往往能得到出人意表的效果,虽然它缺乏学习(实际也可能是群体学习筛选的结果),它却也省去了过拟合的烦恼。延伸来说,如果你不能掌控一个系统的复杂性,用启发式的策略做一些力所能及的事情,比你搭建一个同样复杂的系统试图去理解它是更为合理的。

结文

到此,增强学习的基本概念与模型算是摆在面前了,应该不会有下文了,将来如果有,也会结合着我自己的实践体会来写。虽说只是一个缩略版,这些模式对于实际要做的事情也没有直接的帮助,但我们需要这样的对问题建构的范式,以设计出符合自己系统需要的模型来。

参考文献:

【1】Reinforcement learning: A survey;  Kaelbling, L.P. and Littman, M.L. and Moore, A.W.; Arxiv preprint cs/9605103; 1996

Posted in Algorithm.


概念化”增强学习”(一)

增强学习同时是一个心理学及机器学习的概念。我们很多知识的习得都是通过增强学习的机制完成的,其最基本的形态无异于你训练小狗帮你捡回扔出的网球时所采取的形式。正如很多机器学习理论都从生物认知系统或群体系统中获得启发一样,增强学习也从中汲取了营养并发展成一个独立的分支。但是跟其它机器学习领域不一样的地方在于,它更多的是一类问题(而非一些技术)的集合。

可以用增强学习领域里一些常用的名词来非严格地定义它:一个agent,处于一个变化的环境中,通过试错与环境发生交互,慢慢适应环境并使得自己从环境获得的收益最大化的过程。

基本模型

描绘这个定义最贴切的图如下:

图1

图1

图1描述的是一个agent与环境发生交互的过程:agent通过感知函数I和R来获得环境的输入,并依此从自己的行为集合B中选择操作a反馈给环境;环境依据当前的状态s与操作a,通过一个状态转移函数T(s,a,s’)跃迁到一个新的状态s’。至此完成了一步迭代。通过一步又一步的迭代,agent会慢慢学习到环境的分布或规则,从而得到一个策略——对于每种状态,都能给出收益最优的操作。是不是很像某些AI视频里小机器人在一个陌生环境里通过行走学习找到正确路径的场景。这里之所以存在一个输入函数I,而不是直接获取环境输入,是因为在某些场景里,agent对环境信息的输入感知是不充分的,如局部的、带噪音之类的,不过这里的讨论中I会是一个无差的函数。R是收益函数,简单的情景下它输出为:有(1)或无(0)。

基本假设

这个模型有两个基本的假设:1、环境是非确定性的,即状态转移函数T输出的是一个概率值,S×A->S是一种概率映射;2、环境是平稳的(状态转移函数T的输出概率分布是稳定的),或至少是短时平稳或变化缓慢的。

增强学习 vs. 有监督学习

增强学习面临的问题跟有监督学习不一样,它没有一批预先准备好的input/output数据集可供学习,它考虑的是在一个全新的、几乎没有什么信息可供参考的环境里,如何通过试错的方式来获得环境反馈的学习。因为没有离线的数据可作依据,所以,在线的实时的评估对于增强学习而言是极其重要的,这是一类一边学习一边评估的系统。

问题的求解

对于这个基本模型下的学习问题,即如何给出收益最大的行为输出,有两种求解的途径,一是通过遗传算法、遗传规划或其它搜索策略在求解空间中搜索问题的局部最优解;二是使用统计或动态规划的方法去估计在不同状态下采用不同操作所能获得的期望收益,并由此直接或间接的得到统计最优的行为输出。

优化目标

增强学习最终输出的是一个最优的行为策略,所以归根到底还是个优化问题,优化的目标函数通常有如下三种:

左式是一种有限视野的优化,它只考虑最近h步的收益期望,这个比较符合人做判断的方式,比如下象棋时的走一想三就是考虑了后续几步收益所给出的最优走法。中式应用比较广泛,是一种带衰减的无穷视野收益期望,无限的情况存在于理论的世界里,离当前时间点越远其重要性越低的假设既符合主观认识又能保证数学上的收敛,所以用于做理论推导是很合适的。右式是无穷视野的另一个版本。选择不同的优化目标函数能得到完全不同的行为策略。

Exploration vs. Exploitation

在Reinforcement Learning这个范畴里讨论学习问题通常都绕不开这个tradeoff问题,通俗地说这等同于每朝的太祖都会面临的问题:稳守江山还是开疆辟土。用一个k-arm bandit可以很形象的说明这个问题的普遍性。所谓1-arm bandit即我们常说的老虎机(水果机、赌博机),投一个硬币,按一下按钮或扳一下手柄,根据机器滚动组合的三个图案来决定你获得奖励或两手空空。k-arm bandit就是这次你面临k台老虎机,并且它们获奖的概率是不一样的,至于概率是多少,就需要你自己去试了。我们简化一下问题,假设你不用投硬币,但你只有n次玩的机会,每次玩你会获得1或0个奖励,那么为了你的收益最大化,你应该采用什么样的策略?

策略分析

直观的说,如果你已经预先知道了各台机器的获奖概率,你应该完全采用Exploitation式的策略,集中投注于概率最大的那台机器。在你完全没有一点关于概率的信息时,你应该先采用Exploration的方式去对各台机器做探索性的测试,以期获得足够的信息让你化归到最简单的Exploitation式策略。从算法的角度上去求解这个问题,通常有两种途径,一种是规范化的方法,把一些成熟的模型引入进来解决问题,如动态规划,学习自动机。另一种是特定性的方法,它们多是一些启发式的算法,如贪心算法,波尔兹曼搜索等等。

其实,k-arm bandit同时还是符合RL模型的最简单的形态:单状态的RL模型——你永远都只会面临同一种状态,以及k种操作的行为集,并且环境是稳定但非确定的。这个简单的模型在很多的机器学习和应用数学的领域都有讨论。

参考文献:

【1】Reinforcement learning: A survey;  Kaelbling, L.P. and Littman, M.L. and Moore, A.W.; Arxiv preprint cs/9605103; 1996

概念化“增强学习”(二)

Posted in Algorithm.


2011,从doublo到muggy

曾经荒芜人烟的莱布斯大陆,在公元2011年8月的倒数第二天,长出了这片土地上的生命之树。它的第一个枝丫,被命名为doublo。

最初它是这样的:

一开始,她只是颗小树苗

三个月后,它变成了这样:

后来它变成了这样

不久的将来,我会写下“豆菠萝往事”这个标题,详细记述发生在这片大陆上最初的人与事。但今天的记忆,从doublo的破土开始。几个关键词,描绘了这段独特旅程让人无法忘怀之处。

3P

3P(3 Programmer),是hanshuo对我们在doublo上线前夕的新工作方式的戏称。由于项目牵涉到flash-js, js-backend, backend-algorithm之间双向的繁复接口,到后期我们已经无法单独或结对地开发。所以在上线前最后一周,hanshuo, qiubo和我在每天下午四点之后就会把自己关在一间小黑屋里,做最后的冲刺。上线前的几天,设计师tifa也加入了其中。那个具有特殊意义的下午,上线时间从2点推到了3点,从3点推到了4点,从4点推到了5点,最终6点才完成上线。从昏黄的灯光漆黑的屏幕前抬起头,从每个成员的脸上,我看到的是创造者的快乐。

这个关键词的背后,是适当的团队规模,是灵活的协作和高效的沟通。

3P

会心一击

会心一击,是那个昏天黑地的年代我沉浸时间最长的网游——MU里的一个概念,也是doublo第二期的核心feature。之所以提到它是因为在我最初对doublo的设计中并没有“会心一击”这个模式,只是我这个实质上的算法攻城师,在后来阅读着一个个用户反馈时才开始从开发上考量它的可行性以及产品上它存在的价值。事实上很多现在看来无比正常的产品和技术上的决策,在最初的时候,它们要么根本不存在,要不早被我弃之一角。但你只要走出了第一步,终归会有和它们碰面的机会。

“会心一击”原指造成最高伤害的攻击,它可遇而不可求,你只能边打边等待那耀眼的蓝色字眼跃于眼前。这里,它代表了我的信念:只要出招,也唯有出招,你方能找到命中要害的“会心一击”。

上岛咖啡

那个阳光明媚的下午,在和平西桥的上岛咖啡,我捧着笔记本坐在靠窗的沙发上,带着与这里并不相衬的焦虑。那天的主要目的是和已经在另一个公司的qiubo利用这仅有的一个下午的时间完成muggy的flash版名片。然而,那时我还肩负着另一个很重大不得不完成的任务,那个任务的牵绊让我如此忧心忡忡,以致我甚至跟hanshuo和tifa说出“如果这周上不了那可能永远都上不了”这般丧气的话。最后在那个奇迹一般的下午,那项任务的大部分需求居然都被搞定了,随后我们又一道完成了muggy名片的flash版本。走出咖啡馆时,已经晚上十点多,初冬的寒气可以迅速在行人的头发上形成一层薄霜,而我把这看做让人走得更快的动力。

那个下午的咖啡,浓缩了labs成员在这件事情上的额外付出,无论hanshuo的加班加点,还是tifa利用节假日完成的设计。为了这个大家都热衷去做但只是一定程度上的“业余兴趣”,每个人都在多付出一点。

走出这片我在2011年徘徊许久的大陆,回到那些跟它有或是没有交集的生活里,下面是一系列的排比句。

这一年,我的生活方式发生了很大的变化,也开始学着更宽容地与身边的人相处。在这件事情上我经常假设的一个命题是:如果和另一个自己生活会怎样?“那一定很糟糕”,这是我常给自己的答案。所以,理解与接受他人的个性与习惯是多么地必要。

这一年的8月,在2200米的海陀山草甸上,有与自己不相干的人声鼎沸,有满眼的野花和绿草,有云海和日出,度过了自己最值得回味的一个生日。

这一年,去了平遥,走过那容易让人产生穿越感觉的古街与民房,看到了从《平凡的世界》伊始梦牵魂绕的黄土高原和窑洞,闻到了漂浮在太原上空挥之不去的煤炭气息。

这一年,看书的时间少了,但学会了更经济地看书,有些书,能极大的减少你花在阅读同类书籍上的时间。

这一年,自己翻译的第一本书《智能web算法》出版了,这应该也是最后一本。理由是翻译跟阅读和写作的体验完全不同,我目前还无法适应。好处是在苦逼地一词一句的斟酌过程中,慢慢地总结着自己曾经的经验,形成一些自己的成体系的东西来。fm、doublo、muggy算法架构的设计带给我思维上的变化正慢慢沉积下来。

于是,这一年,用笔在纸上写出了一个又一个的算法模型,一些已经实现了,一些还在完善中,一些在上线前的几天推倒了重来。问题解决之最难,不在于其理解上的艰涩和实现上的阻碍,而在于如何在无穷种选择中找到最简洁有效The One。

这一年写的博客少了很多,我给自己的借口是忙与沉淀。人不能总是重复自己,2012年再写出来的,我希望是更深入更系统的思考。

这一年的七月,我脑海中的四个实验项目开始成形。在2011年结束之前,这个构想完成了一半有多,世界末日来临之前,我有足够的时间来检验这棋局的成败。

这一年的最后一个月,莱布斯大陆启动了第三个项目,它的名字,叫巴部落。

略带磕绊地写完这篇总结后,我翻了翻去年的总结,不免有点惊讶,这是一年前的我写出来的吗?一年之间,我到底变了多少?相遇曾经的自己,是一种很神奇的体验。

Posted in Life & Thinking.


为了更新的更新

我并不乐意看到,上次的更新时间已经是两个多月前,况且这段时间里发生了那么多了不起的大事。豆菠萝都上线了,乔布斯都走了,北京最美的季节都快落光了,千年一遇的神棍节都过去了,我始终没写下一个字来,就像要在一个已经被挤干的橙子里再挤出一滴汁液那么困难。也许到年底,当一切都过去了,我会写写豆菠萝、写写唛记,还有别的更激动人心的新事物背后的故事,但不是现在。

生活不断地在战备态和死猪态间切换。有时睡得几乎以为自己不会再醒过来,但闹钟是一种比日出日落更客观的存在,于是追逐着日光继续过着钟摆式的一天。有时夜半梦回,只是因为脑海中闪出了比阳光还明亮的火花,为了让它继续照明前路,用白天的精力与黑夜做着交易。

感觉一直在行走,无论是在山上,还是在办公室,区别只是拿着登山杖,还是MBP。带着罗盘,不问方向,无论是一路向北的NB,或是往南的SB,多走一程,又是不一样的际遇。

在resume的夹缝中coding,在一切high priority的ticket挤压中做着normal但自认为的big thing,但不要让blogging停止下来。

Posted in Life & Thinking.


关于个性化的产品

随着近年来互联网公司对个性化服务的关注程度在提高,开始有很多人从学术、从产品、从实现上研究推荐系统这个存在已久却颇为潮流的事物。一个产品的成功,需要建立在管理人员、产品经理及技术人员对相关知识体系里某些基本概念的共识,及由此产生的默契,避开无谓的争执与误解。

这里,我要根据自己的理解,斗胆给一些模糊的概念下一个定义。因为不管这些定义是否是公认的,每个人都应当为自己从事的领域建立一套基本而较为清晰的概念体系,为此你才可以把实践经验组织成一个可作演绎推理的系统。

何谓一个推荐产品,一言蔽之:找出用户兴趣所在,推荐符合TA兴趣的事物。这个定义包含了两方面的内容:用户建模与推荐系统。有些时候,用户建模这部分是没有的,或者只是一些简单的人口统计学信息。但拥有用户模型是一个推荐产品走向成熟的标志。

这里的用户模型又可分为行为模型和兴趣模型两部分。行为模型跟用户的访问行为相关,如用户的访问频次、在系统留下数据的多少、频繁点击模式及这些模式后面的意义等等。兴趣模型可以用一个高维的兴趣空间来刻画,这些维度所代表的意义可随着应用领域不同而变化,可以从用户的收藏行为中抽象,也可从文本信息中抽取。

推荐系统包含我们常见的“推荐算法”,以及怎样把这些算法得到的结果推送到用户面前的“推荐逻辑”。推荐算法跟我们常用的机器学习或数据挖掘算法并没有清晰的界线,基本上任何适用于大规模数据计算的机器学习算法都有可能成为你推荐系统中的候选。一个自适应的具有成长能力的推荐系统还免不了需要反馈收集和指标评价体系这些模块,这也是系统之所以被称之为系统的原因,在我以前写的一篇分析开源推荐系统框架duine的博客也有类似的描述。所以,推荐算法并不是一个专门的学科,但推荐系统的构建可以成为一个专门的研究领域。虽然大多数论文都只会讨论具体的某些或某类算法,但这不应成为你树立一个系统视角的障碍。

设计一个成功的推荐产品不单是工程师们的事,也是产品经理和设计师的事,特别是对于这么个没有太多实例可以参考的新颖的产品形式,各方面人员对基本概念的认识与认同,有助于一起协作把事情做好。

上面简短的文字,一部分是我三年从业经验的一些总结,一部分是我在翻译《智能web算法》这本书时对经验梳理的结果。

该书的第3章就是介绍推荐系统的,里面的叙述跟我的理解未必完全一致,但有助于梳理我们在这个实践性领域的思路。我随书做了一些笔记,放在豆瓣笔记上 ,有兴趣的朋友可以对比着阅读。

Posted in Algorithm.

Tagged with .


你喜欢什么编程语言?

OpenParty回来,重看了一下自己的讲稿,觉得还是挺乱的,想传递的东西很多,仓促之间也没有把内容组织好,对周六冒着桑拿天赶到现场,还在一间没有空调的挤了一百多号人的房间里听我唠叨了近一个小时的同学们深感有愧。这里摘要一下,也许能同时弥补一下因为我口音不纯带来的表意不清。

其实主要是两部分的内容,一是我认为R能极大提高算法与数据工作人员的快乐程度及工作效率;二是R的发展历史中呈现出来的六张面孔。至于向量化、CRAN及PackageRank、面向对象的S3和S4、用R实现的推荐引擎等等本来不该糅在一起的内容,在我博客的历史文章里都分别有叙述,这里就不再和面了。

我不是个星座性格学的信徒,但我相信你所使用的编程语言会对你的性格产生重大影响。最初你可能会因为某些或性格或随机的因素而选择了某种语言,接下来你也许会坚守下去,又或者会叛变。只要你在这个环境,用这种语言所提倡的哲学思维一定的时间,你最初的性格倾向就会被放大,最初没有的性格因素也会慢慢的出现在你身上,到最后你会完全认同它所提倡的价值观,你会成为它的卫道者,事实上你在这条路上走的越远这个特点表现得就越明显。所以,语言之争并不单纯是计算机领域的战争,也不是工具之争,而是哲学、价值观上的战争,所以最终的结果通常是谁也不可能说服谁。

从这样的观念出发,如果你了解某个人所忠诚的编程语言,你通常也能大致猜到他是个什么样的人。勾搭一个MM,你可能需要从谈论天气(或者更潮流一点,谈论星座)开始,而勾搭一个程序员,你只需要直截了当的问他喜欢什么语言。如果答案是C,那他可能是个极其追求效率与细节的人,对自己从事的工作要求达到内存级的了解;如果答案是Java,你应该能浮现出J2EE这些高楼大厦,以及Sun公司的广告牌,他可能是习惯于在一个大团队里与人协同工作的;如果答案是C#,oh my god,哥们你这辈子只做过MS的系统编程吗;如果答案是Python,这表明他崇尚简单直接的思维方式与解决方案;如果不幸他的答案是锤子,你还是赶紧闪吧,这说明在他眼里满世界都是钉子。

所以也许是你选择了语言,但你选择的语言塑造了你。

然后这里我很无聊的来了个插叙,介绍我最近看过《你一生的故事》里也有类似的观点。用一个科幻故事来佐证,除了满足自己觉得有趣的心理外,我实在也找不到别的理由。不过这本书的作者还在《Nature》上发表过文章,至少说明他的思想还是有严肃的引用价值的。

在此基础上,我认为用R可以让你把机械的键盘敲击动作,转变为艺术性的思维锻炼。因为R的程序足够短,拥有的工具包又足够多,所以你不需要花太多的时间去实现一个优美的设计。接下来你还不需要太多的成本去维护它,因为代码的维护成本是跟它的长度成正比的,只要有可能,有时间,我们都应该写出更短的代码来。用R,你不再需要为代码的编写和维护而费心,你也不需要为了实现某个demo的功能而写出大量的预备代码,你更不需要大量的人员围绕在你身边却只是为了试验某个算法的效果,你只要按照先进的科学计算思想把你的程序设计好,这不是件容易的事,但这是件充满乐趣的事。

R是一个适用与科学计算与数据分析领域的工具,它无意取代你已经熟练的项目开发语言(如Python、Java),事实上,如下文所述,R的接口特性使得它在与别的语言结合时才能发挥出最大的威力来。同时,随着数据挖掘工作在公司内部受关注程度越高,它的作用就越大。

我不是个语言卫道者,我一直认为,不同的应用场景里不同的需求环境下,语言的表现会有差异。我也一直认为,一个有自信的黑客应当熟练掌握至少两门的编程语言,这有助于你开拓胸怀,容纳更多的价值观与思维方式。

下面谈谈R的六张面孔,实际上是对R发展历史的回顾。主要内容来自S语言的创始人(也是R的核心开发人员)John Chambers的一篇文章《Facets of R》,老爷子在文中按照R的时间发展顺序列出了先后加入其中的六个特性,分别是:

•     各种类型的计算过程的接口(interface)
•     交互式的(interactive)
•     函数式编程(functional)
•     面向对象(object-oriented)
•     模块化(modular)
•     协作(collaborative)

1975年,贝尔实验室开始研发S语言,目标是通过接口的形式把一些常用的Fortran写的计算程序包整合起来,而给终端用户提供一个方便的交互式的语言环境。当时像C和Fortran那样的过程式语言是很流行的,而交互式的语言接口虽然现在已经很普遍,但在当时这股风潮才刚刚兴起。所以最终这种语言的样子是:以S语言的语法来交互式的描述计算任务,但实际的计算则是由底层的Fortran程序包完成的。随着S的发展,各种各样的接口被逐渐加了进来,如数据库、电子表格及各种各样的软件包。后来S成为世界三大统计软件之一。

时间进入到80年代到90年代中期,那仍然是一个属于S的时代,R仍未有踪影。那时面向对象的编程思想正风起云涌,C++、Java等日后红透半边天的代表者也开始出现。受这股风潮的影响,S也开始加入面向对象的因素。同时,函数式的思想也开始加入,S的语言语法描述被转换为函数调用,而函数本身就是对象。过程计算的接口仍然存在,但已经被函数封装起来。后来的R同时受Lisp的两种主要方言之一的scheme的影响,在函数式编程的路子上走得更远,连赋值和循环本质上都是函数的调用。在一种语言中同时深度支持面向对象和函数式编程是有点困难的,从我的R使用体验来说,我觉得这种结合还是以函数式的实现为主,面向对象的样子则有点不伦不类的,也有可能是我对现有面向对象的形式的认识太过根深蒂固的缘故。如C++与Java之类只是面向对象而非函数式的语言,它们的方法是跟类绑定的,而不是像S和R那样,跟函数绑定。通过S3和S4的方式实现方法的函数式绑定略显晦涩,但对于丰富函数这个角色的深层次的使用是必须的。

1996年,携带着S的贵族血统的R终于出现了。它的出生几乎就是伴随着模块化和协作的特性而来的。因为R从S继承了丰富的接口形式,所以利用这些接口实现一个新的模块、新的工具包就变成一件自然而然的事,现在世界上已经有千千万万的人在为R编写着函数级别或包级别的模块。R是开源的,它鼓励世界上每一个用它工作的人写出自己的工具包,甚至贡献给别人,给更多的人带来方便。于是,就有了CRAN,一个现在为止已经有两千多个并且还在不断增长的第三方开发的开源包列表。原则上,R能做什么、渗透到那个领域,主要取决于什么专业的人在用它,用它来做什么。

从小老师就教育我们,写文章要前后照应,为了使该文不至于变成实际上可以拆成两篇的文章,我必须给两个话题找找关联。那么,从这六张面孔中,我们能归纳出R对它的追随者的性格产生什么样的影响呢?首先,它会让你产生一种包容与谦卑的心态,因为这个工具对科学计算各个领域的涉及面是何其的广泛,你基本可以想象,有一千个R用户,就有一千个领域专家,并且还是乐于分享与贡献的领域专家。然后,这个工具已经有太多为你准备好的东西,它们都在促使你去尝试它们,有一种探险与学习的心态,这样做的成本并不会太高。再三,它让你觉得自己可以在程序设计的过程中找到乐趣,因为R程序很容易写,但好的R程序需要锤炼,如《黑客与画家》的作者Paul Graham所说,一个优秀的黑客,不应当是一个泥水匠,按照既定的工序一块板砖一块板砖地把墙砌好,而应该像个画家,不断地往你的作品上添加东西,使它臻于完美。

Posted in Life & Thinking.

Tagged with .