Categories
经济、IT观察与思考

一些审视

大概有一个多月,一直在酝酿这么一篇文章。有很多的东西想说,却每每到口边欲言又止。总归沉淀的久了,该说还是要说说吧。

1. 关于大数据

我是莫名其妙的就被拽入这个领域的。虽然我也经常在一些不得不包装的场合不停的用到“大数据”这个词,但说到底我还是觉得它是硬生生的被炒作出来的。从2011年到现在,有幸在国内国外开了无数的跟“大数据”有关会议,有小有大,有偏学界有偏业界,可是越开越麻木。以至于到最后,我关心的问题就成为了几个:

  • 有什么新的数据被搜集了吗?(比如江南春去扫小区垃圾桶..);
  • 有什么新的领域被攻陷了吗?(比如某些传统行业,如劳动密集型的制造业、餐饮业、个人金融);
  • 有什么新的数据产品出炉了吗?(比如基于数据魔方的新的应用)。

曾经有人戏谑般的问我,“你一个做分析的关心这些high level的东西干啥?”,我的回答很直白,“为了保证不让自己失业”。当然这话有五分打发之意,归根到底的原因可能是,我在寻找灵感,在试图最大化分析的价值,在别人的失败中学习经验(输家往往比赢家更有意思)。换言之,我没打算一直做分析。自从在eBay深度接触了某些做事极端细致的同事之后,我觉得这个领域做到极致也怕就是如斯了。拼不过。

有些问题越来越不关心,因为从分工的角度来看绝非我的比较优势。比如,XX架构改善了数据库存储、查询;XX模型经过某些改进获得了几个点的提升;XX产品可以支撑更大量的数据和更好的实时并发性(这些东西对我来说,有就用,没有也不强求);XX平台实现了XX算法(没有成熟的接口我是不会去碰的)。可能对于数据分析模型的理解(此处单指统计或者机器学习模型),我已经过了那个狂热的沉浸于美好的证明或算法无法自拔的阶段。从一个更高的角度来看,基础设施尚未建设完成(更广泛的数据源搜集、聚合,以及强有力的分析平台建立),谈那么多奇技淫巧有什么用?每每看到BI这个词,就想吐酸水...平心而论,eBay的基础设施建的还是比较好的,一个数据仓库就有几百人的技术团队在维持。

总结一句话:路漫漫其修远兮,做的好的就那么一两家。单单靠分析赚钱没那么容易,先把人才的缺口补上吧。

2. 关于分工和角色

说分工之前,先说说现在的工作。在eBay,听起来很曼妙的两个音节,却很不幸的在它的海外研发中心。若我是个工程师研发产品也就罢了,可惜还在分析这种需要跟业务部门频繁交流的岗位。当然做什么事情都有好和不好的一面,没有绝对的。只是当你还可以选择的时候,当你处在一个不同的职业发展阶段的时候,会有不同的诉求。

回头看,如果我知道现在的工作是这样的模式,我还会在一开始如此选择吗?会的,我很无奈,但没有更好的选择(当时下决心一定要去一个英文环境)。“不畏浮云遮望眼,只缘身在最高层”。那个时候位置太低、浮云太多,很多事情看不清楚。我觉得我很幸运,毕业之后的两份工作都没有让我后悔过。

eBay对我的最大改变就是,让我重新拾回了很多技术细节。比如,对于分布式的理解越来越深,parallel SQL 越写越熟,R的某些包越用越顺手,Shell和SAS被重新拾起,诸如此类吧。这也是我当时离开咨询的目的——做pre-sale support、跟客户天天腻在一起,没有脚踏实地的感觉,每天脑袋瓜子里想的都是“客户到底是怎么想的”,每天都在做各种各样的利益分析。时间久了,觉得每天都在跟演戏一般。

可是在分工链上,技术绝非我最擅长的。开什么玩笑,一个直到研究生都没怎么受过正规编程训练的人,怎么可能拼得过那些国内顶尖学校CS或者EE出身的、一直专注于此的精英们?就算勉强加上模型这块儿,就算凭着还算可以的数学基础我事后补修了很多门机器学习和统计学的课,我也不觉得我能胜得过那些一早儿统计和计算机兼修的有志之士们。太多东西不是纯粹智商和努力可以弥补的,时间是不可逾越的鸿沟。当然如果下定决心一直做下去,也未必没有成就——可是要我抛弃心头挚爱的经济学,做与之完全无关的事情,我做不到。

有个很好玩的词儿叫做“street sense”,我也不知道怎么翻译为佳。有点类似于soft skill的感觉。在我的同事中也有少数这方面很强的人,能明显看到他们的成就卓然不同。对我来讲,这样的感觉或许更佳吧。

3. 关于积累

工作久了,很多人就会跟你说“工作经验比学历更重要”。我的感觉是,看哪个是短板吧?两个还是均衡发展比较好。要不在labor economics之中,也就不必把experience和years of study都作为回归变量了。

工作经验是个很神奇的东西。一方面他会加快你做特定事情的效率(指数式),一方面他也会束缚你的思维。周围看到了许多从技术转到管理岗一开始很不适应的案例。思维方式完全不同嘛。

我个人喜欢把工作经验分为两部分:广泛适用的经验和内部适用的经验。在一个企业一个部门,其实积累的更多更快的是更适用于本部门的一些经验,这两种经验发展不均衡在那些一毕业立刻进入一个企业、一直没有离开过的人身上尤甚。实话讲,如果想在一个大企业里面很快的发展,内部经验尤为重要。Fit the culture。而广泛适用的经验其实对于适应更多的环境、岗位更重要。把赌注都压在一个篮子里面是不明智的...

4. 关于野心

我一直觉得我是一个不安分且具有野心的人。不过时间会把人的奋斗精神消磨,尤其是在一个很容易就活的比较舒服的环境中。

可是当太多事情不能控制,一切浮华便如过眼烟云,与己无关。

Categories
日常应用

无知的比较:R和Teradata SQL(附赠TD经验几枚)

今年夏天的时候,刚刚开始被SQL虐,写了一篇很无知且更多是吐槽意味的blog post: 关于R的若干SQL等价问题。当时被若干朋友批评,我还浑然不觉个中精要。现在用Teradata也有半年多的时间了,越来越习惯了SQL的表述方式,也越来越体会到Teradata作为一个强大的数据仓库系统,是有多么的伟大...这感觉,就是只玩过几个G数据的乡下人进城,猛然看到各路英雄都是动辄几个T的数据,只能暂时以原来落后的思维方式、勉强挥舞着新型工具...好在个性不是特别愚钝,终究还是可以慢慢地领悟到T级数据的奥妙之处,终究用着新武器也越来越顺手了。

这一段时间,也充分证明了我是master in economics而绝对不是 in cs。数据库系统的原理终究学的不深——我哪儿知道MySQL的SQL和Teradata的SQL差了那么多呀...后来慢慢的去听同事传授TD使用经验,慢慢的去看老板传过来的代码,慢慢的一次次处理掉 no more spool space的错误和一次次接到SQL语句效率低强制退出的警告信之后,才逐渐地越来越了解TD的原理和脾气。工欲善其事,必先利其器,这些都是沉重的学费。

所以各位如果没有看过那篇「无知者无畏」状post的,就不要看了。直接接受我诚挚的道歉然后看下文吧。Teradata下简称TD。绝非专业知识,只是个人有限的了解,不对之处请及时批评。

有次跟同事聊,问他们为什么不在本机上装个TD测试用...然后被狠狠鄙视了一番——TD没有单机版!天生就是架在云上的。这东西还真是个原生的分布式数据仓库。

TD和oracle的关系也比较简单:一个是数据仓库,一个是数据库,功能设计什么的压根就不一样。这么说吧,oracle支撑的是ebay的网站运行,所以必然涉及大量的查询、插入、删除等请求。更麻烦的是,以ebay的访问量,这些请求都是同时过来的,这就要求系统并发性要好一点(专业人士可以绕道了,我只是浅薄的知道一点东西...)。体验过12306买火车票排队的大家,想必都知道这个系统并发起来的厉害。ebay若是也来个排队,消费者还不疯掉...

为了应对这样的任务,oracle的数据库设计自然是要按那「三大范式」来。这个就不多说了,再说就暴露了...

TD则是把oracle的数据定期地导出来存着,所以除了简单的复制数据之外,还要对数据进行一定程度的清理和整理,并不完全是最最原始的数据。然后到了食物链上端数据分析师手里,面对的数据很多都是已经弄的很整齐的了。说是食物链上端,只是因为这大概是分工中需要用到原始数据的最后一拨人,且这拨人用到的最多的就是查询(甚至是整表查询)和计算,所以我们写SQL的时候更多是考虑到这些需求,利用TD在这方面的性能优势——我已经很少在SAS或者R里面进行数据整理的工作了,性能跟TD完全不是一个量级的。

下面是TD使用的若干经验,不过这东西只有自己碰壁了才知道个中真滋味,我就是缩短一下解决问题的进程,不用太折腾到处搜来搜去。

No more spool space。当你的SQL没有语法错误,那么最常见的运行不下去的情况就是 no more spool space了,这大概是每个用TD的不管新鸟老鸟都会经历的痛苦历程。这个错误就像R里面报"cannot allocate a vector of size ***",或者你玩游戏正high的时候系统告诉你内存不足。解决的思路就是"空间换时间",就是看你具体怎么换了。

1. 多表join查询的时候,就要看这些表是怎么merge的——TD会去算是一大一小join,还是两个大表join。前者TD会复制小表到每个大表的"节点"上(大表肯定要分块存起来嘛),所以可以事先加collect statistics on *** column ***。后者就要费点脑子了,争取两个表的排序(PI)一致,这样TD join的时候就不需要对两个表都重新排列了是不是(merge join)?每一次重排都会占掉大量的临时空间呢。再者,查询结果储存到另外的永久或者临时表里面,就要注意primary index(简称PI)的选择,不要让TD再把查询结果重排...

2. 除了看primary index,有时候还要去注意partition by。有些已经建好的超级长的表需要去看是怎么真正"分块"存储的。对于partition by 的字段设定一个where条件,会让TD很快的知道你要查询和join的是哪些部分,大大缩短范围。一般说来,最常见的partition by就是时间了,缩短一个时间范围也不失为良策嘛。

3. 擅用cast()可以避免很多跟数据类型有关的错误,这个就不赘述了。

4. No space on ***说明没有永久表的存储空间了,这个就得去删过于古老的表和去要新的空间了。

5. 每段SQL不要太长,join不宜太多。熟悉TD的脾气之后,就张弛有度了,擅用临时表。

6. 多用group by少用distinct。

7. 最后终极野蛮办法,如果实在是没法两个大表join又没有partition by的话...手动按PI拆其中某个表吧。

----例行碎碎念----
那些在LinkedIn上endorse我R的朋友们,我真心感觉承受不起呀!至今依旧觉得我的R很烂,代码只停留在"可运行"的水平,效率大都很糟糕,基本就是折磨CPU的...哎,非科班出身终究是有莫大的差距呀。