Categories
读书有感

重温概率论和线性代数

年底的节奏比较舒缓,就有更多的时间来重新拾起一些东西。先是百无聊赖的浪费了一些时间看剧打游戏看小说,基本就是一种不动脑子的打发时间的模式。后面觉得着实无聊了,开始想有什么可以看的。不知怎么的,就动了重温数学的念头。搜了一下网上的各种公开课,发现MIT的线性代数(Gilbert Strang)和Harvard的概率论基础(Joe Blitzstein)评价比较高,就打开youtube开始跟课。

线性代数我其实偷了个懒,没有去跟那个完整版的,而是简单地看了一下Strang教授今年发布的2020版。一共只有五部分,每一部分大概一刻钟,我看之前还在想这个是怎么做到的。看完了,就明白这75分钟的高屋建瓴之处了。大一的时候学线性代数,虽然分数不错,但是其实学了一堆计算却不知所云。后面学到高等计量开始频繁地用到线性代数,才多少有了一些事后的感悟。现在再去看线性代数,觉得这东西真的挺美的,一点一点地串联起多少问题。

话说到这里,多少有点“我吃了七个烧饼发现饱了,是不是直接去吃第七个就好了的”味道。我需要略带羞耻地承认,我大学以后的数学基本都是靠学经济学才学会的(学会指的是有一些理解而不仅仅是记忆公式和定理)。大一一上来的微积分,动不动各种极限和证明,直接懵掉了。概率论学了什么完全不记得了,印象中好像只有一本很薄的小册子,各种证明,然后考试一片茫然。线性代数也是,死记硬背了一堆证明却不知所云。

类似的,我对计量经济学也有差不多的体验。其实第一次学(初级)计量经济学的时候也是一脸懵,第二次学(中级计量)稍微好了一点,后面一遍又一遍地学计量(或者广义地说,线性模型),我才逐渐开始理解回归模型。回头看,这实在是一个成本巨大而痛苦的过程。可是代价如此之高是因为老师教得不好呢,还是因为这些东西本来就难?我现在已经没法回到原点去体会另外一条路径了。只是重温这些基础课程的时候,更容易跟着这些大家公认优秀的教师的思路,来站在更高的层面欣赏数学本身的美,而不仅仅是当作工具。

数学这种学科,学懂了和没学懂差别太大了。学懂了,再厚的教科书都觉得如若无物,要用的时候信手拈来(英文我习惯用internalize来描述这种状态)。没学懂的话,基本就是记住了一堆程序化的操作流程(procedure)却忘记了他们的来龙去脉。这种差别会深刻地影响日后的学习或研究。这两年面试了上百人,我所在意的其实不是一个面试者记住多少公式和模型(比如我允许他们随时google),而是他们是不是真正理解他们用到的模型本身。把统计模型学成了一堆procedure其实是一件非常危险的事情。

概率论这门课我是老老实实地跟完全程的。毕竟是一个学期的内容,34节课,每节课接近一个小时,加起来就有三十多个小时。我并没有快进或者跳跃(主要是在电视上放起来快进比较麻烦),所以陆陆续续花了四五天的时间才把全程跟完。如果是第一次学这门课,这种节奏几乎是不可能的,因为新的信息量其实可能很大。只是我对于这些内容多少熟悉,所以实践起来更像是复习直觉而不是学习知识。这也是让我可以有机会去由衷地感慨原来概率论可以如此简单明了。我开始以为我会经常走神,尤其是已经非常熟悉的内容。结果很多时候,我居然全神贯注地又听了一遍那些熟悉的定理和公式。Blitzstein确实把这门课讲得很深入浅出。印象最深的是他在推导正态分布的时候,明明是那么无趣的定积分和极坐标变换问题,居然可以讲得那么好玩。又一次验证了高斯发现正态分布时候那种“天赐”的感觉。数学的美往往就在这种时刻。凭什么,一切繁琐的符号最终化为这么简洁优雅的记号?

正好在2020年的最后一天和新年交界的时点,看完了这门30多个小时的课程。让我忍不住记录一下,这种别致的、超级满足的跨年方式。

Categories
读书有感

重读《凯恩斯传》

说来也有趣,这本书陪着我居然漂洋过海了好几番。我虽然对宏观属于一知半解的状态,但是对于凯恩斯这么一个传奇人物还是始终保有着足够的好奇心的。

IMG_1912

顺手翻了一下落园以前的日志。好怀念那种读遍各种书籍的日子。那时一点点不成体系的思维,还有那种对哲学朦朦胧胧的感慨,现在都更顺利的串联起来了呢。

已经记不清六七年前第一次读这本书是具体怎样的体会和感悟了,现在重新翻开却也颇为有趣。想看凯恩斯的同性到异性恋的转变,想看凯恩斯从对于哲学和概率的着迷到参与政治事务投身宏观政策,想看凯恩斯和熊彼特的“既生瑜、何生亮”。

那就先从哲学和概率论看起吧。

IMG_1893

这一段还是蛮好玩的。说的是老生常谈的相关性和因果关系。当年还是一个有点“群魔乱舞”的年代,大家对于统计的概念还有些模糊。从哲学的角度,对于演绎法和归纳法的适用范围和可信度还有一些争论不休。凯恩斯这里说到了计量经济学最重要的一个观点——ceteris paribus(其他条件不变),而他自己也说起来“部分均衡在实际上很难成立”,也就是就算我们的模型甚好、发现的是局部的因果关系,这样的因果关系有多少可推广性(external validity)还是需要打个问号。而有趣的是,在这个时代概率和统计还没有分的很开,大家还在从哲学的层面讨论概率存在的根基。

然后又看到一段他和拉姆齐的八卦。拉姆齐是个英年早逝的天才,想想他二十出头刚入剑桥就赶上和凯恩斯的《论概率》争论,主观概率和客观概率的争论,归纳法和演绎法的争论。

IMG_1915

从拉姆齐的角度,归纳法是一种“思想习惯”,评价思想习惯的唯一方法就是看这种习惯是否“行得通”...不管归纳法在认识论中的地位如何, 它是一种有用的思想习惯。

这里倒是蛮契合我对于各种定量模型的评判标准...有用。很多为了追求计量上的那一点点依概率收敛、而不管估计量本身的效率如何,在我看来有点舍本逐末。今天边看边在一旁记笔记感慨,有的时候我们为了检测那么一点点弱弱的信号,投入这么大的样本量,测出来的东西不知道到底有多准。这就好像用一个超长焦的天文望远镜,追踪一颗银河系的小行星,稍不留意这行星的轨迹就没了...若不借助赤道仪等等辅助设备,真的是各种手抖。

凯恩斯和莉迪亚的八卦就不说了,对于凯恩斯来说,莉迪亚就是一枚坠入凡间的精灵吧。

Categories
事儿关经济 经济、IT观察与思考

从a/b实验到机制设计、商业决策

本文只代表我自己的不成熟的思考,请勿过度解读。

试想如下两个场景。

  • 场景一:我们做了一个随机试验(random experiment),通过各种实验数据分析我们得出了结论是ATE(平均效果)为1%的提升,对应的p-value是0.09。所以这个东西10%显著,应该推广。
  • 场景二:我是一个风险投资者,我现在有100个项目可以投或者不投,每个项目都有其预期收益和对应的风险。我需要通过各种投资组合实现收益的最大化。

正常的来讲,上面两个场景分属于两个领域:实验分析和金融投资分析。好像之间并没有太大的关系。如果大家做实验分析就知道,大部分paper关心的都是如何得到一个干净的average treatment effect estimate,哪怕是为了降低variance做一些variance和consistency之间的trade-off,我也是在大原则不变的情况下。第二类文献我不是特别熟,但是通过有限的金融投资学的知识,我大概知道做法就是一个线性或者非线性、随机或者非随机(这里的随机是stochastic而不是random)的最优化过程、关注的更多是一些本身不可控的因素。

可是为什么我突然把这两者放在一起?今天突然讨论起type i 和type ii error,然后就不自主的联系到decision making...然后突然间觉得好像有哪里不对...互联网公司大家特别特别的依赖a/b test,一方面是谁也不知道什么是正确的所以索性让数字来说话,另一方面也是有点过度相信统计学的权威、依赖各种统计量和统计模型——我并不是说我们应该剥夺这种权威,而是有的时候好像忘了为什么一开始我们需要引入这样的决策体系。

先说一下我所熟悉的决策体系:做一个a/b test,如果实验结果显著为正(就像大部分field experiment那样),我们就给予实验者相应的奖励(towards business goal)、然后整个铺开。从机制设计的角度,这是一个有效的机制:规则是透明的也是保证正收益的,每个组都在这个机制下play the game是相对公平的。可是这样的机制的缺点是什么...无数的analyst就一夜夜的浪费脑细胞在获得一个可以被认可、又可以最大化自己所属团队贡献的估计量。business side只关心那个估计量的大小,然后公司内部的裁判角色又来审查你这样做是不是统计上正确的。所以many companies end up with a group of data scientists。

可是我们好像忘了一个东西:efficiency。公平是公平了,但是这个机制是效率角度最优的么?从公司的角度,做这么多a/b test实际上就相当于一个投资组合的决策过程:我需要在哪些上面投入更多、哪些上面投入不要这么多。每一种决策都是有风险的,那么既然是一个风险和收益的最优化过程,我就应该计算所有预期收益、成本和量化风险。风险应该是一个连续的度量而不是一个简单如p-value <10%这样1或0的二维决策过程。

所以说到这里,其实当你在做那么多实验的时候,其实那些针对单个实验分析的指标甚至理论什么的就不重要的。每一个都做到极致并不代表整体是最优化的,甚至可能是囚徒困境那般谁都走不出去?suddenly I got very sick talking about type I and type II errors.  I don't think that fits the culture.

大概就是这些,最近脑子里面萦绕的就是这样稀奇古怪的想法...喵。

bottom line

想起来一个joke: statisticians are good at generalizing stuffs (when we talk about statistical tools....the answer is it does not matter! because you should be good at generalization.)

Categories
日常应用

探索R包reshape2:揉数据的最佳伴侣

前几天放出来的那个R的展示中,有说到其实学R的过程更多的就是熟悉各种函数的过程(学习统计模型不在此列...我个人还是倾向于不要借助软件来学习理论知识,虽然可以直接看codes...笔和纸上的推导还是不可或缺的基本功),然后各种基础函数熟悉了之后很多被打包好的函数就是缩短代码长度的利器了。

excel里面有神奇的“数据透视表(pivot table)”,其实很多时候真的已经很神奇了....不过我还是喜欢R,喜欢R直接输出csv或者xlsx的简洁。揉数据呢(学名貌似叫数据整理),我也还是喜欢写出来代码的形式,而不是直接向excel那样面对结果。只是感觉更加不容易出错吧。

揉数据,顾名思义,就是在原有的数据格式基础上,变化出来其他的形式。比如,长长的时间序列变成宽一点的~当然这个可以简单的借助reshape()函数了。可惜我还是不死心,想找一个更好用的,于是就自然而然的看到了reshape2这个包。

这个包里面函数精华在melt()*cast()。说实话melt()耗了我一段时间来理解,尤其是为什么需要先melt再cast...后来发现这个步骤简直是无敌啊,什么样的形状都变得更加容易揉了,大赞。

warm-up完毕,还是回到正题吧,怎么用reshape2揉数据呢?虽然reshape2支持array, list和data.frame,但是我一般还是习惯于用data.frame,所以还是说说这东西怎么揉吧。揉数据的第一步就是调用melt()函数,不用担心你的input是什么格式,这个函数array, list和data.frame通吃。然后,要告诉他哪些变量是(唯一)识别一个个体的,这句话是什么意思呢?我们先看melt()的参数:

 melt(data, id.vars, measure.vars,
    variable.name = "variable", ..., na.rm = FALSE,
    value.name = "value")

其中id.vars可以指定一系列变量,然后measure.vars就可以留空了,这样生成的新数据会保留id.vars的所有列,然后增加两个新列:variable和value,一个存储变量的名称一个存储变量值。这样就相当于面板数据的长格式了。直接拷一个作者给出的例子:

原数据:

head(airquality)
  ozone solar.r wind temp month day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6
dim(airquality)
[1] 153   6

然后我们将month和day作为识别个体记录的变量,调用melt(airquality, id=c("month", "day"))

head(melt(airquality, id=c("month", "day")))
  month day variable value
1     5   1    ozone    41
2     5   2    ozone    36
3     5   3    ozone    12
4     5   4    ozone    18
5     5   5    ozone    NA
6     5   6    ozone    28
dim(melt(airquality, id=c("month", "day")))
[1] 612   4

嗯,这样数据就变长了~然后,就可以随意的cast了...dcast()会给出宽格式的数据,比如我们想把day作为唯一的识别,那么:

names(airquality) <- tolower(names(airquality))
aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE)
head(dcast(aqm, day ~ variable+month))
  day ozone_5 ozone_6 ozone_7 ozone_8 ozone_9 solar.r_5 solar.r_6 solar.r_7 solar.r_8 solar.r_9 wind_5 wind_6 wind_7 wind_8 wind_9 temp_5 temp_6
1   1      41      NA     135      39      96       190       286       269        83       167    7.4    8.6    4.1    6.9    6.9     67     78
2   2      36      NA      49       9      78       118       287       248        24       197    8.0    9.7    9.2   13.8    5.1     72     74
3   3      12      NA      32      16      73       149       242       236        77       183   12.6   16.1    9.2    7.4    2.8     74     67
4   4      18      NA      NA      78      91       313       186       101        NA       189   11.5    9.2   10.9    6.9    4.6     62     84
5   5      NA      NA      64      35      47        NA       220       175        NA        95   14.3    8.6    4.6    7.4    7.4     56     85
6   6      28      NA      40      66      32        NA       264       314        NA        92   14.9   14.3   10.9    4.6   15.5     66     79
  temp_7 temp_8 temp_9
1     84     81     91
2     85     81     92
3     81     82     93
4     84     86     93
5     83     85     87
6     83     87     84

或者对于每个月,求平均数:

 head(dcast(aqm, month ~ variable, mean, margins = c("month", "variable")))
  month    ozone  solar.r      wind     temp    (all)
1     5 23.61538 181.2963 11.622581 65.54839 68.70696
2     6 29.44444 190.1667 10.266667 79.10000 87.38384
3     7 59.11538 216.4839  8.941935 83.90323 93.49748
4     8 59.96154 171.8571  8.793548 83.96774 79.71207
5     9 31.44828 167.4333 10.180000 76.90000 71.82689
6 (all) 42.12931 185.9315  9.957516 77.88235 80.05722

当然还有更强大的acast(),配合.函数:

library(plyr) # needed to access . function
acast(aqm, variable ~ month, mean, subset = .(variable == "ozone"))
             5        6        7        8        9
ozone 23.61538 29.44444 59.11538 59.96154 31.44828

嗯,基本上数据就可以这么揉来揉去了...哈哈。怎么感觉有点像数据透视表捏?只是更加灵活,还可以自定义函数。

此外还有recast()可以一步到位,只是返回的是list;colsplit()可以分割变量名...函数不多,却精华的很啊。

--------------------
题外废话:我的小册子哎~只能这样零零碎碎的写一些了,事后再统一整理进去好了。不要鄙视...

Categories
事儿关经济

把结论假设出来?——记郁彬讲座

一如前篇日志所述,这次帝都之行最大的收获就是有幸聆听了郁彬大神(Berkeley统计系主任)的讲座——还是自由交流式的,让人受益匪浅啊。走出来第一感觉:我要去读Ph.D。

或许以前也说过,最佩服的人就是能 show the beauty of what he/she is doing 的人。我是个极度喜欢美丽的事物的人,不论是那个领域。只要让我看到事物的美丽,那么热情就随之而来,拦也拦不住。幸运或者不幸,昨天郁彬教授恰恰向我展示了这一点。5555,顿时热血沸腾,各种激动。强心针不能长打啊,我脆弱的小心脏真不一定承受的了啊。

郁彬有些很经典的话,摘录于此:

1. “我一直努力的目标,就是不跟我不喜欢的人在一起”。多么的洒脱!是啊,你永远不可能让每个人都喜欢你,你也没必要去喜欢所有人,更没必要讨好什么。做自己喜欢的事情、让自己活得开心,这样就很好了。

2. “经济学者要负责任”。无可避免的,提到了经济学(后面紧接着还提到了social network,连中两枪的我表示格外happy)。确实,一个经济学的研究应该更负责任一些,不要制定了一个经济政策之后,无论好或者不好,都没法评价。那么,这样的事情做下去没有任何的事后风险,确实是不甚公允的。对此,我表示深深的赞同,我也希望有朝一日的经济学研究可以更贴近社会民生、更好的服务于经济发展而不仅仅是某些IQ超高人群的brain game。而且,不仅仅是更好的应用,从theory的角度也应该给出更好的应用指导。

3. “最好的证明,就是假设和结论离得比较远,让人眼前一亮。要不,你干脆把结论假设出来好了!”。确实是,很多时候我们写paper,假设一大堆,尤其是理论经济学那边。是啊,你只要承认我的假设,后面的结论肯定没有问题。关键是,这假设有没有道理呢?如果假设完全是空中花园,结论再美好又有什么意义呢?另外,如果假设和结论就差那么一两步,这样的文章又有多大的价值呢?好的theoretical的文章确实应该是,假设和结论乍看不相干,然后通过巧妙的逻辑推导严密的证明出来。这才是有用的嘛。(话说,数学家们喜欢争执的是definitions,更严格咯)

4. “相关和漂亮,我可能会选择相关”。爱美之心人皆有之,郁教授也一直在强调 enjoy the process not the results,但是很多时候 beautiful researches 并不是那么容易就可以达到的。诚然,我最喜欢的research就是, simple and elegant,但是这样的研究从来都不会是天上掉下来的,一定是不断的努力最后得到的。因此,我这里姑且理解为不能“好高骛远”,很多时候还是要静下心来慢慢沉淀,一点点突破,聚沙成塔。研究考验的不仅仅是人的聪明程度,还有耐心和毅力。一切的美好都是值得等待的。

5. 交叉学科。关于交叉学科,郁教授说了很多。她给我们分享她自己的辛酸历程,这才是今天可以站在聚光灯下的源泉。Title不是决定性因素,但是有的时候为了达到自己的科研目标不得不曲线救国。否则,空有一身本事但是科研资源不会自己找上门来的。郁教授在美国数十载,一步一步都走得那么艰辛,果然通往成功的道路从来都不会是一帆风顺的。失之东隅,收之桑榆,谁也不知道今日的失去明天会如何的pay back,但也不必因为一时的得失过于欣喜或悲伤。这大概就是,不以物喜,不以己悲吧。人生是一场马拉松,每个时刻,大家都在不停的努力,都需要一直去努力。另外,领域的选择,确实没有任何“随大流”的必要。只有自己喜欢的,才能做的卓越。还是,

做自己喜欢的事。

超级喜欢郁教授的坦率、直接和真诚。对我们这些还在、或者刚刚迈出校门的孩子们来说,这样的交流确实弥足珍贵。从来没有一个环境会是完美的,只是不同的环境会在人生不同的阶段提供不同的营养。我多少觉得,自己离开学校来到industry一段时间,是非常值得的(无法判定对错),而一开始选择一份与人打交道更多而不是天天面对数据的工作,也是让我受益匪浅的。很多事情,都要一点点的慢慢积累,路还长着呢,何必心急。只要时间不曾被浪费,就好。保持一颗看风景的心情,无论身在何方。

Thank you so much, Prof. Yu. I will go back to school and continue my research dreams one day, and hopefully, that day is not far away.