怀念 Jett

​之前笔者写过不少文章,其中不仅包括技术和数学文章,还有一些日常学习工作的心得,甚至还写过几篇关于旅游的流水账,但是却很少写关于人物的文章。最近我打算写一篇关于人物的文章,用于纪念在工作中一起战斗过的伙伴 Jett。

许多年前,我还在学校读书的时候,就有前辈告诉我,交朋友的时候基本上就只能够在学校,离开了学校之后在职场中想交到合适的朋友是比较困难的。当时作为一枚职场菜鸟的我,也只能够表示对这句话的认同。直到在工作后遇到了 Jett,我对这个观点就有了自己的看法。

屏幕快照 2019-08-10 下午10.02.49

我是2015年7月作为校招生进入公司,Jett 则是2015年10月通过社招进公司的。当年虽然两人身处同一个部门,但是由于不在一个中心,也不是同一条业务线,并且这两个中心平时也没啥日常工作的交集,因此我和 Jett 同处一个部门许久却互相不认识对方。就好比在学校里面,虽然身处同一个院系,甚至同一栋宿舍楼,由于种种原因而不认识对方。

随着工作时间的增加,到 2016 年的时候笔者就已经过了新手保护期。所谓新手保护期,就是每一个新人其实都有一段适应公司的过程,公司也会给人一定的保护时间,但是一旦过了这个时间就不算新人了。大约到了2016年5月份的时候,部门内部启动了一个用机器学习的方法来做安全对抗的项目。当年的安全中心并没有机器学习的从业者,因此需要从其他中心抽调人手去支持他们的项目。在一些机缘巧合之下,我作为数据团队的代表,就和安全团队的同事们同在安全大数据项目组。在公司里面,机器学习的人员通常都是和开发人员通力合作,各司其职,共建一个项目。在项目初期,其实 Jett 也不负责与我对接,后续随着项目的进一步发展和迭代,Jett 就成为了安全中心与我对接的人。

虽然 Jett 是和我对接的人,但是 Jett 主要也是负责平台开发,之前 Jett 在进入公司之前好像没有做过前端,但是在项目初期好像做了一些前端方面的工作,在邮件里面得到了领导的赞扬。这个应该是我对 Jett 的第一印象了,那就是一个靠谱的开发人员。当时虽然是成立了项目组,但是还是作为一个试点的工作来做,无论是算法的调研和平台的工作,都由我们两个来完成。这些项目在初期都是一大堆人在里面,但是随着项目的进展,人数都会越来越少,然后领奖的时候又出现了一大堆人。在项目的初期,我当时应该也只会 SQL,连 Python 都不算很熟悉,更没有开发过大型项目了。即使是作为一个试点的项目,其实个人也有着巨大的压力,毕竟这个方向在公司当年还处于一个相对不那么清晰的状态,也不知道该怎么做,甚至也不知道有什么资料可以查。不过作为一个 PHD,虽然写代码的能力不行,但是读论文和搜索资料的能力还是有点的。当时记得花了很多时间在网上找来找去,总算找到一两家号称做这个方向的创业公司,运气够好的是当时它们居然都发表了相关的论文。后来把它们的论文整理成资料和PPT,跟相关的同事沟通了一下,就打算复现这几篇论文。

屏幕快照 2019-08-10 下午10.01.49

当然,做项目总是有着各种各样的风险,况且当年本人的技术实力确实也不怎么样,写过不少的 SQL,做过很多数据分析的工作,查过一些数据方面的问题,至于其他方面也就那么回事。在项目的调研阶段和初期,大约是5月份-8月份,其实也没有什么特别大的产出,主要也是在积攒技术经验,把 Python 的各个工具库熟悉了一下。不过在公司里面总是有考核的,到了9月份的时候压力就比较大了,毕竟最终还是要对上线的效果负责的。在9月底的时候,我和 Jett 被拉去星巴克喝了一杯咖啡,然后被下达了任务和命令,也就是在十月份完成机器学习的效果指标。

屏幕快照 2019-08-10 下午9.59.46

既然被拉到星巴克去喝咖啡,也就是说明在9月份的时候,模型的效果都不算太好,估计再这样干下去也没有办法完成既定的目标。不过目标这种事情制定的时候都是根据当时的情况来制定的,很有可能会随着时间的变化而产生变化。虽然说目标总是在发生变化,但是整体的大思路是没有改变的。当时,作为开发人员的 Jett 问我要不要修改 XGBoost 的模型源码,我连忙说不用不用,其实就算让我改,我也没有本事修改别人的源码。既然不会修改模型的源码,那就只能够从数据和特征来入手了。在机器学习领域,只要把数据和特征处理好了,基本上就能够保证模型的效果和质量。于是 Jett 和我当时把成千上万条数据一起看了一遍,结果是发现正负样本有一部分混在了一起,于是模型的效果无论如何都做不好。

屏幕快照 2019-08-10 下午10.05.45
XGBoost 的 Github 主页

对于在校学生而言,通常来说都是 Python 跑完模型,然后得到一个模型文件,用它继续离线预测就可以得到最终的结果。但是在工业界,很多机器学习项目都需要进行上线的工作。这种时候只靠一个机器学习人员的战斗力是无法解决问题的,不可避免地需要有开发人力的介入。此时 Jett 发挥了作为一位开发人员的强大战斗力,一个人就能把线上的代码全部完成,没有让我撰写任何一行 C++ 的代码。在码农界有一种“结伴编程”的说法,也就是两个人共同搞一份代码,共同搞一个项目。我是负责数据处理和离线模块,Jett 是负责平台开发。有一次在核对数据的时候,把 Python 的预测结果和 C++ 的预测结果进行核对。也就是为了交流方便,那次我把 Mac Air 搬到了 Jett 的桌子上,两个人并排坐在一起,一起核对数据的准确性和可靠性。

不过核对数据只是机器学习项目的第一步,并且也是长期需要做的一步,因为数据总是会出现各种各样的问题。即使数据没有问题,也不代表最终的模型效果达标。到了2016年10月中旬的时候,我俩的压力也已经很大,每天晚上都在万利达五楼加班到十点以后。每天我都在训练模型和数据分析,Jett 每天也在做平台开发的工作,虽然我不懂他在做什么,但是总是感觉很忙的样子。而且项目经理每两天都会催一次进度,顺带着会有各种大大小小的会议。其实当时 Jett 是作为业务部门的人,压力更大的是压在他那一边。在思考了大半个月之后,在一个星期日的夜晚,我去华润万家买了一堆小本子,把整个项目的细节仔仔细细地思考了一遍,突然灵光一现,发现其实有一个优化点,于是就顺手写在了小本子上。到了周一的时候,我把小本子上面的想法去实现了一遍,结果效果瞬间提升,业务指标瞬间完成。当我把这个好消息告诉 Jett 的时候,Jett 还在 RTX 上说了一句:“等我去哭一会”。最终我俩猛加班两天,把模型往线上一扔,效果直线上升,而此刻的报表系统早已齐备,瞬间就看到了效果的提升,甩掉前面的模型五条大马路。

6EC4948295154B525FD67EAC9B309320.jpg
当年撰写思路的小本子

在2017年初的时候,模型的整体效果已经很好了,整体的路线其实已经基本走通。因此后续更多的是平台建设方面的工作,这一块做得更多一点的是 Jett,最终他还真是完成了无算法人员参与就能够自动接入各种业务的全自动流程。不过随着时间的流逝,我俩都各自都被抽调去做其它的项目,合作的时间和机会在项目成功之后就变得越来越少了。万幸的是,在2017年9月5日-2017年9月9日,我俩共同去了台湾进行了一次团建。参见《五日台湾行》。

640

640-2
2017年的台湾

后来,由于种种原因,我也不再继续从事安全方面的工作,与 Jett 的交集也越来越少。虽然后面也有吃饭聚餐等时候,但是却没有了在一个项目中一起为了一个目标奋斗的机会,心中不免有少许遗憾。随着去年的大调整,Jett 和我已经不在同一个部门。今年 Jett 由于家庭原因离开了公司,恐怕短期内已经再也没有通力协作,互帮互助的机会了。也许这个项目是我俩共同做的最后一个项目,但是当年在万利达五楼共同奋斗的时光,却是一段珍贵的回忆。

Advertisements

高考志愿—谈一谈数学专业

最近,经常在知乎或者其他平台上看到

  • “高考填写志愿要不要填写数学专业?”
  • “读计算机专业是不是需要先去数学系?”
  • “从数学系转行到金融行业的前景怎么样?”

这一类的问题。最近也正值高考填志愿的时期,于是在这里说一下自己的一些想法。

math1.png

其实这个问题很难给出一个标准的答案,因为每个人的个人条件,家庭条件,就业规划都完全不一样。推荐的结果应该正如推荐系统一样,根据每个人的情况来定制化,而不是给出一个结果供所有人参考。

一般情况下,每个人都有自己的发展方向或者职业规划,基本上进入数学系有这几个常见的原因:

  • 想做数学科研,成为数学工作者;
  • 为了转行做准备,准备研究生阶段进入金融或者计算机;
  • 实在不知道想学啥,于是选择数学试试看。
  • 其他原因。

Case 1:

第一种情况,想成为数学工作者的应届生其实只能选择数学系。目前的现代数学高度专业化,已经不是一个外行人,跨专业的人或者普通职业的人能够研究的了。本科所传授的数学知识大约也就是在20世纪中期而已,后面几十年的科研工作就很难写进本科教材了。因此,对于有志向成为数学家的学生而言,进入数学系是唯一的选择。当然其实也有大神从别的专业转过来从事数学工作的,并且也能够做得很好,但是对于绝大多数人而言是不现实的。

对于这一批少数的学生而言,最好的方式就是按照数学系的标准培养模式来做。也就是听课,刷题,复习,钻研,考试这条路,每天花十个小时学习,高强度的学习几年的本科数学。然后想办法进入顶尖高校的数学系,继续从事数学科研几年时间。最后进入顶尖高校的数学系或者科研站,从事数学研究。

GTM52.png

Case 2:

第二种情况,经常都会遇到一个问题,那就是“是否有必要先读数学,然后在研究生阶段转行计算机或者金融?”先说结论:个人感觉是完全没有必要的。理由有以下几点:

  1. 金融或者计算机同样会开设各种各样的数学课,并且是结合专业的情况来开设相关课程;
  2. 数学系并不会专门提供金融或者计算机的课程;
  3. 数学系的思维方式和培养模式与金融或者计算机不太一样。

question.png

在这里,如果是为了打基础而先进入数学系再转行去其他专业其实是没有必要的。因为其他专业同样可以提供数学课,完全可以在其他专业学好数学课,没有必要专门跑来数学系学习四年数学。当然,由于高考填写志愿,或者为了进入一个更好的大学,只能够选择数学系而放弃其他专业其实是可以理解的。但是,在本科期间一定要补充其他专业技能,否则最后还是会比较吃亏。

除此之外,数学系很少会去开设金融或者计算机方面的课程,大部分开设的还是数学课,当然也不排除有的数学系会开设一大堆计算机系课程的情况。那么就来看一下数学系与计算机系的课程安排:

数学系的课程:

数学分析,高等代数,解析几何,C++,离散数学,常微分方程,偏微分方程,抽象代数,复变函数,实变函数,泛函分析,数值计算,偏微分方程数值解,拓扑学,微分几何,概率论与数理统计,随机过程等。

计算机系的课程:

微积分,线性代数,离散数学,数据结构与算法,数字电路,计算机组成原理,操作系统,编译原理,计算机网络,数据库原理,软件工程,汇编语言等。

从这两个课表的对比情况来看,如果要想从数学系转行到计算机系,那么基本上要把计算机的一些基础知识课程都大致过一遍才行,否则企业为什么不直接招聘一个计算机系的,而需要一个跨专业的人呢?在这种情况下,对数学系的人其实提出了很高的挑战,因为在数学系繁重的课程下,想要同时兼顾数学系和计算机系两个专业的课程是比较困难的,需要耗费巨大的时间和精力才能够做好。

balance

在这种情况下,如果是计划研究生期间转行,就需要额外花很多的功夫了。毕竟金融或者计算机其实是有一定的课程量的,不仅要保证数学系课程的学习,还要去学好金融或者计算机其实是有一定的挑战的。但是,为了最终要转行到其他领域这也是一条必经之路。因为只有补平了自己与科班人员的差距,才能够在其他领域发挥自己的数学能力。例如在计算机领域,只有编码能力过关了,才能够逐步展示数学能力。如果基础能力不太够的话,就只能够先做补基础的工作了。

experiments

数学系与其他专业的培养模式其实不太一样。在数学系,强调的一般都是听课,刷题,复习,钻研,考试等一系列流程。在这种情况下,对于想成为数学工作者的学生是比较友好的。但是对于大多数需要转行的学生而言就不算友好了。因为其他专业更多强调实践,无论是金融还是计算机都会把实践放在第一位。在金融领域,实习或者社交其实是一个比较关键的因素,但是在数学系,这些能力是无法得到锻炼的。在计算机领域,通常接触到的都是业界相对新的东西,需要在实践中一边查资料一边干活才能够逐步掌握知识点。在数学系,也会有机会进行实践,但是时间往往比其他专业会延后许多。在数学本科或者硕士阶段,其实绝大多数人是没有能力搞数学科研的,最后的毕业论文无非也就是整理一下资料和笔记而已。直到博士阶段,数学系的学生才需要进行资料的收集,论文的阅读,从而进行数学科研的工作。整体来看,数学系从事实践的时间往往会比其他专业延后许多,如果是以就业为目的来攻读数学专业其实是不合适的。

Case 3:

第三种情况,实在是不知道想学啥,如果自身条件还不错,家庭条件也还算可以的话,其实学数学专业也是一种选择。因为在数学系期间,最终的选择面还是比较广的,主要包括:

  • 科研工作者:数学方向,金融经济方向,计算机方向等;
  • 计算机行业;
  • 金融行业;
  • 教育培训行业;
  • 其他行业。

选择面广有的时候是一件好事,有的时候不见得是一件好事。选择面太广就容易让人迷茫,尤其是对于那些目标不明确的人而言。导致的结果就是这批学生什么都去了解,什么都去学习,什么都是浅尝辄止,最终其实并没有掌握任何东西。最怕的事情就是,在数学系的时候并没有把数学弄懂,然后在其他领域又没有办法和科班竞争,从而最终荒废了自己。因此,如果实在是不清楚学什么的话,来数学系是可以的,但是肯定需要把数学弄明白。最终,突然有一天这批学生想转行或者做其他的事情,数学能力能够给人带来很大的帮助。

choice

如果萌发了转行的想法,那么最好就是找相关的人士咨询一下其他行业,或者去招聘网站上看相关的岗位需要什么样的技能,能否通过自学或者听课或者其他方式找到一份实习。然后根据自己的最终目标来反推自己当前的决定,也就是要达到这样的目标需要多少时间,多少精力才能够达成。就个人经验来看,转行是需要花大量的时间和精力的,并且越到后面(研究生或者博士阶段),转行的困难就会越来越大。因此,如果要转行的话,其实可以趁早做决定,越早决定就越有优势。

另外需要注意的一点就是,在转行期间不需要在乎数学系那一套评价指标,因为按照数学系的评价指标,不学习不科研就是不误正业了。但是对于转行的人而言,实战才是硬道理,实习才能够了解工业界的具体需求。在学校里面猛刷题或者猛看书其实只是其中的一个步骤而已,是达不到转行的要求的。

结论:

每个人都有自己的局限性,只能够根据自己的成长经历给出判断的标准和依据,并不适用于所有的人,只能建议大家根据自身的情况来选择一套适合自己的方案。毕竟人生只有一次,路也是自己走出来的。

challenge

 

时间序列的联动分析

背景介绍

在互联网公司里面,通常都会监控成千上万的时间序列,用于保障整个系统或者平台的稳定性。在这种情况下,如果能够对多条时间序列之间判断其是否相关,则对于监控而言是非常有效的。基于以上的实际情况,清华大学与 Alibaba 集团在2019年一起合作了论文《CoFlux: Robustly Correlating KPIs by Fluctuations for Service Troubleshooting》,并且发表在 IWQos 2019 上。CoFlux 这个方法可以对多条时间序列来做分析,并且主要用途包括以下几点:

  1. 告警压缩和收敛;
  2. 推荐与已知告警相关的 Top N 的告警;
  3. 在已有的业务范围内(例如数据库的实例)构建异常波动传播链;

kpis.png

CoFlux 的整体介绍

从论文的介绍中来看,CoFlux 的输入和输出分别是:

输入:两条时间序列

输出:这两条时间序列的以下信息

  1. 波动相关性:两条时间序列是否存在波动相关性?
  2. 前后顺序:如果两条时间序列相关,那么它们的前后波动顺序是什么?是同时发生异常还是存在固定的前后顺序?
  3. 方向性:如果两条时间序列是波动相关的,那么它们的波动方向是什么?是一致还是相反?

Remark. CoFlux 的关键点就是并没有对时间序列做异常检测算法,而是直接从时间序列的历史数据(历史半个月或者一个月)出发,判断两条时间序列之间的波动相关性,并且进一步的分析先后顺序与波动方向。

从论文的介绍中来看,CoFlux 的流程图如下图所示:

coflux流程图1

如果两条时间序列 XY 存在波动相关性,则需要输出这两条时间序列的波动先后顺序和是否同向波动。如果两条时间序列 XY 并不存在波动相关性的话,则不需要判断波动先后顺序和是否同向波动。

coflux流程图2

CoFlux 的细节阐述

已知一个长度是 n 的时间序列 S=\{s_{1},\cdots,s_{n}\},对于任意一个 detector,可以得到一条关于 S 的预测值曲线 P=\{p_{1},\cdots,p_{n}\}。于是针对某个 detector 可以得到一个波动特征序列 E=\{\epsilon_{1},\cdots,\epsilon_{n}\},其中 \epsilon_{i} = s_{i} - p_{i}1\leq i\leq n。因此,一个detector 可以对应一个波动序列特征,也是一个时间序列。因此,对于 m 个 detector,可以对应 m 条波动特征序列,并且它们的长度都是 n

在 CoFlux 算法的内部,根据不同的参数使用了总共 86 个 detector,大致列举如下:

  • Difference:根据昨天,七天前的数据来做差分;
  • Holt-Winters:\{\alpha,\beta,\gamma\} \in \{0.2,0.4,0.6,0.8\}
  • 历史上的均值 & 历史上的中位数:1,2,3,4 周;
  • TSD & TSD 中位数:1,2,3,4 周;
  • Wavelet:1,3,5,7 天;
  • 移动平均算法:MA,WMA,EWMA。PS:根据作者们的说法,在这里,MA等方法并不适用。

detectors

根据直觉来看,

  • 对于任何一条时间序列 kpi,总有一个 detector 可以相对准确地提炼到其波动特征;
  • 如果两条时间序列 XY 波动相关,那么 X 的一个波动特征序列与 Y 的一个波动特征序列应该也是相关的;

Remark. 两条时间序列的波动特征可以对齐同一个 detector,也可以不做对齐工作。如果是前者的话,时间复杂度低;后者的话,时间复杂度高。

下图是从时间序列中提取波动特征曲线的案例:

fluxfeatures.png

提炼时间序列的波动曲线特征只是第一步,后续 CoFlux 还有几个关键的步骤:

  • 特征工程的扩大(amplify): 对波动序列特征进行放大,让某些波动序列特征更加明显;
  • Correlation Measurement:用于解决时间序列存在时间前后的漂移,两条时间序列之间存在 lag 的情况,因此需要对其中一条时间序列做平移操作;
  • CoFlux 考虑了历史数据(历史半个月或者一个月)作为参考,并且一个范围内的 kpi 数量不超过 60 条;

下面来一一讲解这些技术方案,对于每一条波动特征曲线(Flux-Features),按照以下几个步骤来进行操作:

Step 1:对波动特征曲线 E=\{\epsilon_{1},\cdots,\epsilon_{n}\} 做 z-score 的归一化,i.e.

\mu = \frac{\sum_{i=1}^{n}\epsilon_{i}}{n},
\delta = \sqrt{\frac{\sum_{i=1}^{n}(\epsilon_{i}-\mu)^{2}}{n}}.

Step 2:对归一化之后的波动特征曲线做特征放大(feature amplification):定义函数 f_{\alpha,\beta}(x) 如下:

f_{\alpha,\beta}(x)= \begin{cases} e^{\alpha\min(x,\beta)} - 1, \text{ when } x\geq 0,\\ -e^{\alpha\min(|x|,\beta)} + 1, \text{ when } x< 0. \end{cases}

E=\{\epsilon_{1},\cdots,\epsilon_{n}\} 放大之后的波动特征曲线(amplified flux feature)就是:\hat{E}=\{f(\epsilon_{1}),\cdots,f(\epsilon_{n})\}.

Step 3:对于两条放大之后的波动特征曲线(amplified flux features)G=\{g_{1},\cdots,g_{\ell}\}H=\{h_{1},\cdots,h_{\ell}\},可以计算它们之间的相关性,先后顺序,是否同向。

G_{s}= \begin{cases} \{0,\cdots,0,g_{1},\cdots, g_{\ell-s}\}, \text{ when } s\geq 0, \\ \{g_{1-s},\cdots,g_{\ell},0,\cdots,0\}, \text{ when } s< 0. \end{cases}

这里的 0 的个数是 |s| 个。其中,-\ell<s<\ell。特别地,当 s=0 时,G_{0}=\{g_{1},\cdots,g_{s}\}=G,那么我们可以定义 G_{s}H 的内积是:R(G_{s},H) = G_{s}\cdot H,

这里的 \cdot 指的是向量之间的内积(inner product)。同时可以定义相关性(Cross Correlation)为:CC(G_{s},H) = \frac{R(G_{s},H)}{\sqrt{R(G_{s},G_{s})\cdot R(H,H)}}.

由于波动有可能是反向的,那么在这里我们不仅要考虑相关性是大于零的情况,也需要考虑小于零的情况。于是,

minCC = \min_{-\ell<s<\ell}CC(G_{s},H),
maxCC = \max_{-\ell<s<\ell}CC(G_{s},H).

则最小值或者最大值的指标分别是

s_{1}=argmin_{-\ell<s<\ell}CC(G_{s},H),
s_{2}=argmax_{-\ell<s<\ell}CC(G_{s},H).


FCC(G,H) = \begin{cases} (minCC, s_{1}), \text{ when } |maxCC|<|minCC|, \\ (maxCC, s_{2}), \text{ when } |maxCC|\geq|minCC|. \end{cases}

从定义中可以看出,FCC(G,H) 是一个元组,里面蕴含着三个信息,分别是相关性,波动方向,前后顺序。FCC(G,H) \in [-1,1],越接近 1 或者 -1 就表示放大之后的波动特征曲线 GH 越相关。正值的 FCC(G,H) 表示 GH 的波动方向相同,是正相关;负值的 FCC(G,H) 表示 GH 的波动方向想法,是负相关。通过对 s<0 或者 s\geq 0 的分析就可以判断先后顺序。因此,CoFlux 方法的是通过对 FCC(G,H) 的分析来得到最终结果的。

在最后的相关性分析里面,其实伪代码正如论文中所示。先考虑是否存在相关性,再考虑基于相关性下的先后顺序和波动方向。

correlationmeasurement

 

CoFlux 的实战效果

从论文中看,CoFlux 的数据集基本上是小于 60 条时间序列曲线。其中包括 CPU,错误率,错误数,内存使用率,成功率等不同的指标。

datasets

datasets2.png

从运行时间上来看,对于一周的时间序列集合(< 60条)而言,CoFlux 基本上能够在 30 分钟内计算完毕,得到最终的运算结果。

executiontime.png

其效果的评价指标基本上就是机器学习中的常见评价指标了,准确率,召回率之类的。

评价指标

从 F1-Score 的评价指标来看,CoFlux 的效果优于其他算法。

experiments.png

告警压缩

如果对时间序列之间进行告警压缩的话,其实可以大量减少运维人员的工作量。在 CoFlux 里面,时间序列曲线被分成了三类,也就是三个颜色最深的模块。因此 21 条时间序列的告警量在实际中有可能只有三条告警。

alarmclustering

告警关联

在实际运维场景中,除了对告警进行压缩之外,也需要对告警进行关联性的分析。例如一条告警发生了,运维人员都希望知道与它相关的其他告警是什么,这样可以方便运维人员定位问题。

alarmcorrelation

构建告警关系链

在一些相对封闭的场景下,例如 mysql 数据库,通过对它里面的时间序列进行分析。不仅可以得到告警之间是否存在相关性,还可以对先后顺序,波动顺序进行分析。

mysql

 

结论

时间序列之间的联动分析是在运维领域场景下的常见技术,不仅可以做告警的压缩,也能够做告警的关联,还能够构建告警的关系链。在未来的工作中,作者们提到将会用深度学习的方法来进行关联和告警的分析,从而进一步加深对时间序列的研究。

本科学数学专业是一个很好的选择吗?

知乎问题:https://www.zhihu.com/question/319574112

选专业这件事情其实是因人而异的,很难对所有的人给出一个标准的答案,肯定是基于每个人的不同条件来给出完全不同的建议。这是一个千人千面的问题,而不是一个数学题,通常只有一个标准的解答。

就个人这几年的经验来看,无论选择什么专业,都会有这个专业的优势和劣势,好比科技是一把双刃剑,专业也是同样的道理。在这种情况下,我们就需要分析数学专业究竟有哪些优势,有哪些劣势。只有这样,我们才能够根据自身的情况来具体分析,然后决定最终是否选择数学专业。

数学专业的劣势

于是,我们来看一下数学专业的劣势有哪些:

  • 理论知识太多;
  • 实用技能偏少;
  • 转行需要时间。

下面来逐一解读以上几点。我们可以先看一下数学系的常见课表:

  • 第一年:数学分析,高等代数,解析几何,C++等;
  • 第二年:常微分方程,离散数学,复分析,概率论,数值计算,抽象代数等;
  • 第三年:实分析,泛函分析,偏微分方程,拓扑学,微分几何,偏微分方程数值解,随机过程,数理统计等。

从课表上面来看,基本上可以确定几个结论。首先,数学专业作为基础学科,其特点就是理论知识偏多,而学习到的技能偏少,毕竟所学的内容都是理论型,培养的学生都是理论型选手。因此直接导致的结果就是数学系的学生掌握了一堆理论,但是却没有办法把它们直接转化成生产力。在实战中,总不能就靠一门 C++ 来谋求工作吧。其次,既然数学系传授给学生的实用的技能偏少,那么数学系的学生在需要转行的话,就肯定要补充新的技能。在从理论派走向实战派的过程中,不仅要找好自己的前进方向,还需要花费一定的时间和精力去转行。在这里需要澄清一点,转行并不是轻轻松松,而是需要花费时间,勇气和精力的。

如果不想继续从事数学科研的话,其实还是建议数学系的学生可以早一点进入公司去实习或者工作,至少在公司能够体验一下与学术界完全不同的人生。人生总是有多种可能性的,其实可以在本科或者硕士阶段多去体验一下人生。与数学系不同的是,对于计算机或者工程类专业的学生而言,到了本科一定的阶段,都会从事某个项目或者大作业,这种时候他们就会在边看边学中得到一定的成长,实践能力的训练其实比数学系的人会早很多。其实数学系也有实践,只不过延后了许多,一般只有到了博士生的阶段才需要进行科研的训练和动手的操作,在本科和硕士阶段一般是不需要的,因为现代数学的发展已经不是大部分硕士生能够完成的了,当然优秀的人总是有的。

数学专业的优势

在讲了数学专业的劣势之后,也需要强调一下数学专业的优势,其优势包括:

  • 底层通用技能;
  • 技能不易淘汰;
  • 逻辑思维能力;
  • 转行就业面广。

众所周知,无论是在学术界,还是工业界,数学基本上就是一切的基础。如果计算机行业没有数学,那就是XX计算机学院与XX培训班的区别;如果金融行业没有数学,那就是文艺复兴公司与XX小银行的区别。虽然我们不能够一味的拔高数学在各个行业的作用,但是很多行业还是离不开数学的。这就是所谓的底层通用技能,无论是计算机,金融还是其他领域,都离不开数学的支持。

除此之外,再次回到那张数学系的常见课表:

  • 第一年:数学分析,高等代数,解析几何,C++等;
  • 第二年:常微分方程,离散数学,复分析,概率论,数值计算,抽象代数等;
  • 第三年:实分析,泛函分析,偏微分方程,拓扑学,微分几何,偏微分方程数值解,随机过程,数理统计等。

当年读本科的时候是这张课表,其实过了十年,也是这张课表。本科的数学课程基本上集中在20世纪初之前的数学内容,最多到了20世纪中期。而微积分的发展时间则更加久远了。对于数学系的教育而言,很难做到跳过数学分析,高等代数的教育直接进入实分析和泛函分析。就算老师能够教,学生也听不懂啊,还是只能够从基础一步一步开始。而工业界用到的数学,通常也就是数学本科三年级的所有课程就能够包括了。很难用到很多研究生方面的知识,甚至很多时候也就用用微积分和线性代数,概率论就足够了。因此,一旦学会了这些课程,则是终身受益的知识,因为数学的另外一个特点就是永恒性。无论个人发生什么,学校发生什么,世界发生了什么,数学定理就是数学定理,一旦被证明且确定了证明是正确的,那就是永恒的。个人会死亡,学校也有可能走向没落,世界也有可能发生变化,但是数学定理就像一个永恒的石头永远放在那里。

除了以上两点,数学是最能够培养学生逻辑思维的学科。在以上的本科生课程里面,几乎所有东西都是从几个公理出发,然后通过严格的证明,一点一点地得到最终的结论,并且构建出整个数学大厦。在本科教育里面,数学系的学生只要认真学习,通常来说,逻辑思维能力和数学推导能力都会得到一个很大的提升。并且在后续的学习或者工作中,数学的烙印都会深深地印在身上。

最后,数学的就业面其实是相对宽广很多,主要包括:

  • 科研工作者:数学界,金融界,经济界,计算机方向等;
  • 计算机行业;
  • 金融行业;
  • 教育培训行业;
  • 其他行业。

除了可以继续从事本专业之外,其他方向无论是金融还是计算机都可以转。

结论: 整体来看,其实如果自身条件 OK 的话,并且也愿意在本科期间选择数学专业的话。其实选择数学专业是一个不错的选择。在数学系本科这几年可以根据自身的情况来继续选择合适自己的发展方向,并且在研究生或者工作的时候选择一个适合自己的舞台。

机器学习算法工程师的日常

目前笔者已经在互联网行业从事机器学习方向三年有余,经常也被问到做机器学习算法工程师是一个什么样的体验,同时也常常在其他平台上看到其他人问类似的问题。于是提笔写下此文,供有志投身于这个行业的人参考。

日常生活

数学博士的时候,通常的日子是这样的:

根据论文或者某个讲座得到的信息来提出某个数学猜想 -> 然后开始在 Google 上搜索论文 -> 再花费几周到几个月的时间来读论文,并且思考这些论文的优点和缺点 -> 思考 -> 思考 -> 思考 -> 继续读更多的论文 -> 思考 -> 思考 -> 思考 ->…-> 放弃。。。。

在互联网公司做机器学习的时候,通常的日子是这样的:

根据行业的PPT或者业务中的某些痛点来提出技术方案 -> 然后开始收集数据,不仅要问遍组内,还要去其他组收集各种各样的需求 -> 根据之前的技术方案来进行数据的预处理 -> 撰写特征工程 -> 训练模型 -> 调参 -> 调参 -> 重新收集数据 -> 数据的预处理 -> 收集更多数据 -> 调参 -> 调参 -> 调参 ->…->放弃。。。。

1

业务理解

就做机器学习的经验来看,通常来说在做业务之前,一定要清楚的弄明白项目的业务需求是什么,弄清楚这个问题是什么比一开始就写代码重要得多。意思就是在回答问题之前,一定要把问题的内容弄清楚。有的时候,虽然看上去是一个很大的需求,但是实际操作起来的时候使用一些简单的办法也能够达到项目指标。有的时候,虽然看上去很简单,但是实际操作起来并不是一件容易的事情。从之前做理论数学的经验来看,通常数学里面的一些问题是是非题,不能够添加条件的。在 PDE 等方程领域,定理的条件越多,表示定理越不值钱。不过在工作中,这些条条框框会相对减少很多,只要能够达成项目目标,无论是添加样本,添加特征,添加服务器数量其实都是可以的,并且要把机器学习模型业务指标有机结合才能够达到最终的项目指标。

2

一般搞数学科研的时候都是单打独斗,通常来说都是自己干自己的事情,别人也没办法帮自己。但是在工作中是不一样的,工作中除了干好自己的事情之外,周边的很多资源其实是可以在一个合理的范围内去争取的。无论是人员的数量,还是人员的种类,只要最终能够达成项目目标即可。无论是算法人员,还是开发人员,产品经理,最终都是要为一个项目的结果负责的。之前听过一句经典的话“失败的项目里没有成功的个人”,因此,无论怎么做,最终都要保证项目尽量成功。

3

数据清洗和特征工程

而在机器学习算法工程师的日常生活中,除了上面的小段子之外,其实最重要的是样本层和特征层的处理工作。在学术界,都是使用开源的数据,别人都已经完全标记好了,学术圈的人通常来说只需要在这些数据的基础上提出更好的模型,更创新的算法即可。但是在工业界就完全不一样了,不要说有人帮你标记数据了,有的时候连数据在哪里都不知道,数据的质量如何也不知道,因此更多的时候是进行数据的处理和清洗工作。之前做一个项目的时候,准确率和召回率始终上不去,但是等把样本里面的脏数据清理掉之后,模型的效果瞬间提升了一个档次。在脏数据面前,再好的模型都是没有用的,在训练模型之前,一定要先看一下数据层的问题。

4

除了数据的问题,通常来说在一些场景下,样本的数量并没有那么大,因此深度学习等方案不一定特别适合。在这种情况下,一般就会使用传统的机器学习方法,并且会使用一些基于业务的特征工程。这种时候就需要机器学习从业者对业务有一个精准的理解,只要业务理解得好,有的时候写一些简单的规则就可以解决问题。特征工程也是机器学习里面的一个重要问题。

持续学习

在人工智能这个领域,无论是 CV,NLP,还是机器学习,里面的技术迭代都是非常快的,而且是需要相对专业的人才能够从事这些领域。在这种情况下,机器学习从业者的持续学习就显得尤其重要,几年前的技术在新的业务场景下就未必适合,可能需要使用其他的模型或者框架才能够更好地解决问题。所以,除了完成日常的搬砖工作之外,建议每天抽一点时间来阅读论文,保持对业界技术的跟进和迭代。不过这个行业鱼龙混杂,有的时候论文或者 PPT 里面的技术框架其实没有办法复现,能够精准地判断哪些方案好,哪些方案差绝对是算法工程师必备的关键能力之一。

5

编程能力

如果是在工业界的话,编程能力是非常重要的。因为从事算法的人通常来说会有一些算法上的优化,工程上的改进,数据分析之类的工作。在这种情况下,首先需要有一定的业务直觉。而业务的经验积累需要通过各种各样的基础数据提取,在海量的数据分析工作中逐渐积累的。在这种情况下,提取数据的工具就是必须要掌握的,例如 SQL 等。其次,分析数据的工作也是必须要具备的,无论是使用 SQL 来进行分析,还是使用 Python 来做数据分析,都是自行编程解决的。再次,在从事机器学习方向的时候,不可避免的就会进行算法的效果对比。而在这种情况下,算法的效果对比是需要机器学习从业者通过写程序来实现的。最后,工业界的算法通常来说都强调上线,如果能够自行把离线,上线,效果验证,ABTest都做完,其实是最好的状况。在这种情况下,通常 Python 就不太够了,需要使用 C++ 或者 Java 等其他编程语言。因此,熟练使用多种编程语言也是一个算法工程师的能力。

6

常用工具

在互联网公司里面笔者用过的机器学习工具大概有这几个:

  1. XGBoost:做分类的工具,提供离线的Python训练和在线的C++调用功能,方便机器学习从业者训练模型和线上部署;不仅在推荐场景可以用,在安全,运维等领域都有着用武之地。
  2. Tensorflow:这个也不用多说了,深度学习的经典工具之一,离线训练和在线服务都是不错的。
  3. ScikitLearn:单机版本的机器学习工具。方便学生在校学习知识,文档详细感人,关键是还开源。其实在工业界,如果数据量不大的话,其实用 ScikitLearn 就基本上够用了。
  4. Pandas:表格类数据或者时间序列数据的经典工具。尤其是在时间序列的处理上面有特别独到的优势,应该还有其他功能,但是笔者暂时了解不多。Pandas 的接口和函数特别多,每次遇到问题的时候可以搜一下,其实比自己重头写好得多。
  5. Spark:在大数据的情况下用得比较多,通常是推荐系统一类的,海量样本的前提下,单机版的模型根本搞不定,因此会用分布式的工具。
  6. SQL:提数工具。如果不掌握这个的话,基本上什么都做不了。。。。。
  7. FbProphet:稍微小众一些,Facebook 的开源工具之一,在时间序列预测的场景下才能用到。

7

工作感受

给自己压力。一般来说,转专业求职是一个艰苦的过程,但是入职之后的生活则更加辛苦。因为公司的考核是每半年甚至两个月就一次,所以,在这种情况下,任何人都需要有一个上手的速度。有的人因为在学校学过相关的内容,或者之前实习过,因此上手的时候比较快;但是有的人转专业就面临上手慢的情况。其实这些对于应届生来说都可以理解,毕竟所有的人都需要有一个适应的过程。在这种情况下,在工作的初期一定要给自己一定的压力。意思就是说:在刚工作的第一年,每三个月就要让自己有一个飞速的提升;在工作的第二年,每半年就要让自己有一个提升;后续的话,每一年都要让自己有提升才是关键。因此,无论是本专业还是转专业的同学,都建议在前两年工作的时候,多给自己一些压力,只有这样,才能够让自己有更好的进步空间。

对业务的理解。公司里面有很多东西并不是直接使用开源代码就能够发挥作用的,在公司里面无论做什么事情,最重要的一点就是对业务的理解。在对业务的理解方面,老员工相对于新人来说确实有着不少的优势。其次,在做业务的过程中,通常都会经历很多的坑,无论是别人主动挖的,还是自己踩坑踩出来的,都是自身宝贵的财富和经验。而这些经验只能够通过靠做大量的业务来获得。如果要想长期保持自身的优势,通过长期的训练和学习确实是一个有效的办法。无论是天才还是普通人,要想提升自身的技术,不花一定的时间去学习是不可行的。因此,无论在任何时候都不能够放弃让自己学习和充电的机会。

勇于接受新的挑战。公司里面除了已有的项目之外,通常来说都会开启各种各样的新项目,在这种情况下,如果有机会做新的项目,也就是别人没有做过的项目。这种机会已经要把握住,因为对于新人来说,能够接触全新的项目肯定是好过维护已有的项目的。但是几乎所有的人都是从维护旧的项目开始的,只有旧的项目做好了,才有机会拿到新的项目。

不要永远抱着已有的方向不放手。在公司里面,业务方向总会或多或少的发生变化,随着部门的调整,方向的变化,所做的内容总会发生一些变化。在工作的时候,最好不要抱着我就是来做这个方向的,除了这个方向之外其他的内容我一概不想做。因为当时的工作岗位未必能够提供你想做的方向,但是说不定能够提供其他的研究方向。有的时候,在公司里面,根据方向的变化来调整自己的工作内容也是一个必要的技能。而且,在公司的时候,一定要多做一些有挑战的项目,只有通过这些项目,才能够让自己的技术壁垒更加深厚。当然,在求职的时候,每个人都有着自己的想法和选择,所以,在求职的时候,是可以选择一个自己喜欢的方向来做的。

8

经验总结

通常来说,在干了两三年算法工程师之后:(以下是从其他地方看到的小段子,出处忘记了~~~)

  1. 能够熟练写各种脚本;
  2. 80%的时间在写脚本;
  3. 能够说出几种机器学习算法的名字;
  4. 轻松完成各种脏活累活(叫小弟做);
  5. 对无法解释的结果已经习以为常,能够强行解释一波,让领导信服;
  6. 调参前,都会去寺庙烧柱香;
  7. 桌上堆着很多崭新的技术书籍,没怎么翻过,大概都会有一本叫做《统计学习方法》的书。

9

 

2019年的博客

个人使用时间最长的博客平台就是 WordPress,从 2011 年开始算起,大约有 8 年时间了。

当年笔者还在南京大学本科读数学专业的时候,就见到大神 Terence Tao 建立了个人的网站:What’s new(terrytao.wordpress.com),并且后续数十年如一日的更新个人 Blog。在他的 Blog 上面,除了常见的数学基础知识和课程安排之外,更多的是当前数学界的一些新发展和新方向。由于数学系的博文或者论文除了文字之外,更多的是各种各样的数学公式,而这些数学公式使用公式编辑器一类的东西来处理是极其繁琐的,只能够使用 LaTex 等工具来写。恰好的是,WordPress 除了能够支持日常的文本编辑之外,还能够使用 LaTex 来对数学公式进行撰写,也就是说用户只需要在编辑框内写 LaTex,就能够编译成数学公式。因此,WordPress 对数学公式的支持是相对友好的,这对数学系爱好写数学博客的学生,工作人士提供了非常便利的条件。

除了整理数学公式比较容易之外,WordPress 上面还可以相对方便的选择各种各样的主题,这样的话刚注册的新用户也可以较为容易的上路,不用一开始就陷入编辑网站等一些繁琐的事情上面。同时,WordPress 上也有各种各样的小工具,包括日历(可以查看发表 Blog 的时间),文章的目录,比较受欢迎的文章或页面,文章的类别等内容。用户可以根据自己的爱好自行选择栏目,从而可以轻易地搭建出一个个人网站。另外,WordPress 可以统计出 Blog 的点击数量,包括每天,每周,每月,每年的具体点击数量。

第一次使用 WordPress(zr9558.com)正好是攻读博士学位一年,除了日常的科研工作之外,也打算写点东西来记录一下自己的成长。后续读博士期间也逐渐的写了一些数学方面的文章,不过后续回想起来其实应该在读本科的时候就开始写 Blog。如果这样的话,当年所学过的各种数学知识,整理过的各种资料都会更加清晰一些,也更加容易保存一些。毕竟写 Blog 的一个重要目的是给自己回顾用的,看看这段时间自己的积累是什么,自己学到了什么知识,相比去年成长了多少。其实,有的时候偶尔去浏览一下 Terence Tao 的博客,虽然也看不懂,但是可以明显地感受到“大神”的努力程度。牛人尚且如此努力,我等凡人有什么理由不努力呢。

当年在 NUS 读博士的时候也承担了一些教学的工作,并且也会给学生们讲解习题课。但是每年讲课的内容其实都差不多,于是在讲解习题课的时候,尤其是大学数学(MA1505),曾经做过一份 Tutorials,也就是把习题课的内容写在 WordPress 上面。不仅可以在课堂上方便地给学生们讲解,也可以让学生在课后方便的复习。时过境迁,当年听课的学生(还是大一)早已本科毕业,后面可能也会有学生看到这份资料,希望对大家有所帮助吧。链接在这里:MA 1505 Mathematics ITutorials

后面进入公司之后,有的时候工作繁忙,整理 Blog 的时间就会减少许多。但是一份工作除了能够给人带来必要的薪资之外,更重要的是给自己不停地积攒经验。无论是现在还是将来都可以让自己在职场中更加值钱。因此,除了日常的搬砖工作之外,也要时刻注意自己的成长和经验的积累。而搬砖的经验会随着项目的结束和时间的迁移在记忆中逐渐淡忘而去,于是,适当的记录就成为了必要的工作。俗话说得好,“好记性不如烂笔头”。因此,隔一段时间(通常来说可以设定为一到两个月的时长)就整理一下经验就显得尤为重要,也是提升个人技术和经验的方法之一。但是在整理 Blog 的时候,一定要注意 Blog 的质量,只有不断地提炼自己 Blog 里面的内容才能够保证文章的质量。

不过现在的 Blog 远没有当年受欢迎,在各种各样 APP 横行的时代,已经比较少有人主动去看别人的 Blog 了。不过在使用搜索引擎来搜索某些关键字的时候,有的时候还是能够看到一些高质量的 Blog。在学习这些 Blog 的同时,其实也可以互相比较一下,取长补短才能够使自己的博客越做越好。其实,无论有没有人读自己所写的内容,都要坚持写下去,因为:

即使最后没有人为你鼓掌,也要优雅地谢幕,感谢自己的认真付出。

zr9558's Blog