最近的一些感悟

看了下时间,距离上次更新博客差不多三个月了,也意味着来滴滴有三个月了。梳理了下,这三个月的事也挺多的,毕业答辩、毕业、实习和工作。现在回顾这三个月,感觉转变真的很大,趁今天入职培训有点闲暇的时间,记录下这段时间的感受,也算是分享下自己的近况吧。

1. 三个月里学到了些什么?

回想三个月前,自己还坐在实验室的工位上写代码做数据分析,如今那地方早已被大一的小朋友们占满了,让人不得不感慨良多。自从上一篇博客烂尾后,就去了滴滴实习,也就是现在工作的地方。其实,前期并没做很多事情,因为毕业的事,实习也都是三天打鱼两天嗮网,到每个月底数工资的时候发现,其实一个月里也就半个月在公司。实际的工作时间虽然不多,不过这三个月下来也马马虎虎对整个项目流程有了些了解,对整个公司也有了更深的认识,随便记录点东西,留着以后回头再看。

1.1 Spark

以前虽然对spark也有所了解,然而并没有应用的场景。去组里最早的任务也就是熟悉下spark任务和相关的脚本了,期间对spark 的API有了一定的熟悉,不过到现在为止,也没怎么熟悉MLLib相关的应用和实现。最早的时候,是接手组里另外两个实习生的一些特征提取的工作,讲真,理解完代码时的一个感受是,“嗯,终于看到比我的Python写得还烂的了...",不过呢,等到自己后面写的时候才发现,自己写出来的一些特征提取代码也强不到哪去(后面再细聊这块)。

新人用spark面临的第一个问题一般就是,要不要学Scala呢???记得很久之前学了一段时间的scala,应该是2015年年底附近吧,到最近早就忘得一干二净了,记得当时Scala留给自己的印象就一个字,”杂“。深知这语言里的坑太多,于是实习期间的时候果断跳过了,平时的spark任务基本都是调的Python API,除了期间因为代码交流的原因,又复习了下Scala的语法。然而,大规模云平台上使用Python的一个问题是,包管理(据说Golang的人老习惯拿这点对比Python了)。如果要在这条路上继续走的话,我估计Scala还是得硬着头皮去掌握。。。闲暇的时候尝试了下clojure下的两个spark相关的库,一个是flambo,还有一个sparking,后者感觉还不错,写出的代码要优雅得多,不过,工作归工作,写出来的东西毕竟是要跟其他人沟通的,clojure还是太小众,也就自己玩玩而已了。

2.2 进度控制和管理

技术或者算法方面的学习不是特别多,不过这段时间学到的最重要的应该就是进度的控制和自我管理了。可能自己是自由散漫惯了,在所里的干活的时候都是看心情,早上可能都去得比较晚,完成实验什么的其实并没有什么具体的规划,走一步看一步的那种感觉吧,有状态的时候感觉效率奇高,没状态的时候基本一整天都莫名其妙地过去了。而去了公司的一个整体感受是,一整个项目的分工和拆解相当明确,个人负责自己的一块,再拼接成一个整体。其实刚开始那段时间很不适应,主要原因是总想着对整个项目都有个完整了解后,再考虑去完成自己擅长的那部分。然而,事实是我足足花了一个多月的时间去梳理整个项目,这期间自己的贡献基本为0(更要命的是我在新来的实习生身上似乎也看到了同样的现象),后来观察组里其他人的工作方式,几乎都会把任务拆解到很小的可实现的几个点上,与此同时不断熟悉上下游的代码,这样同时兼顾了杂事的处理和业务逻辑的学习。要是回到3个月前,我一定要告诉自己的一件事就是,不要贪多,step by step!

2. 写项目和做比赛的一些区别

知乎上有人讨论过一个问题你实践中学到的最重要的机器学习经验是什么,显然我还不够格去讨论这个问题,不过呢,我倒是可以分享一些关于完成项目和作比赛的一些区别。

记得有天和陈大师聊到这个话题,讨论的重点是为啥滴滴比赛的时候都是各种模型的融合,咱做项目干的都是又low又苦逼的特征拉取工作(注意关键词)。后来陈大师说了句意味深长滴话:因为这样子效率最高呀!呵呵,会心一笑,不得不承认,同样的工作时间条件下,扩充特征确实是最保守的做法。

个人觉得,做比赛和做项目的最大差别,就是特征抽取了。比赛过程里,一般数据集是给定的,我们根据数据集和问题的特性尽可能去构造出能够描述问题本质的特征体系。由于时间有限,这期间最重要的一件事不是去扩充特征,而是特征的筛选,因为在有限数据集的条件下,top级选手之间的特征差异往往并没有很大。至于筛选的方法,就各显神通了,有人倾向于根据模型得到的特征筛选,有人倾向于自动化的多模型筛选,也有人喜欢直接上神经网络的,总之,有用就行。

其次,我认为是迭代效率的差异。很久以前,我一直认为,除了特征之外,最重要的就是模型融合了,最近好好想了下这个问题,其实比模型融合更重要的是迭代效率。同样走在一条未知的探索道路上,最接近终点的往往是试错最多的团队。迭代效率越高,短时间内尝试的方案也就越多,所以,模型融合也只是迭代效率高的表现形式之一而不是全部。此外,这也可以解释为什么一些横扫各大比赛的冠军队往往更容易在一个新的赛事上获胜,经验是其一,极高的执行效率和工具化的特征生产链也是重要的一环。这段时间的实际工作里,深切感受到了前期积累的重要性,很多生产流程都相当原始,许多事都觉得有些无能为力。

最后是敢于尝试,项目相关的东西,总是偏向于保守的,而做比赛的包袱则没有那么大,许多最新的一些算法都是值得去尝试和改进的,从最近滴滴比赛的几个PPT里可以看到,还是有些队用了神经网络的一些东西,包括DNN,GRU网络等,也有不错的效果。

3. 一些工作了才发现的事

  • 个人能做的事其实很小很小,平台的重要性远大于其它。
  • 缺少主动探索的精神,对大多数人而言,“工作”,也只是一份工作而已。
  • 时间不够用,真心觉得时间才是最宝贵的资源。(现在都不推塔了。。。)
  • 保持记录的习惯很受益,每天都写写wiki,有利于减少一些沟通成本。
  • 代码积累,以前可能都是随手写写脚本什么的,信手拈来。工作后写代码很重要的一个环节是代码复用,多积累一些snippets还是蛮有意义的。
  • 测试!对别人负责,也对自己负责。

4. 近期的一些规划

  1. 重写下网站,保持更新的频率。发现公司的网没法访问blog,打算改写下后台文件的传输方式,还是回归到原始的推送到github方式算了,利用github上的hook同步到server端备份,撤掉后台管理。
  2. 熟练掌握下tensorflow,这个毕竟还是以后工业级应用的主要工具库,theano之类的还是更偏学术点。
  3. 熟练掌握下clojure并发的部分(主要是最近受了Golang的刺激......),此外就是结合业务思考下如何灵活地去写一些DSL相关的东西。
  4. 读下手头上的书,《计算机程序的构造与解释》(刚看一半,后面两章应该要花不少时间)、《计算的本质 深入剖析程序和计算机》(挺有意思的一本书,Ruby还是不太熟,应该会拿Python来重写一遍)、《具体数学》和《统计学习基础》(算是扫尾吧,保持手感最重要~)
  5. Follow下顶会上一些有意思的paper,多动手实践下~