坑 4 思维工具

这一章会侧重科学研究中比较重要的思维工具,但绝大多数讨论还是来自科学哲学。了解科学哲学的发展后再去了解下数学思维在数学史中的变化,毕竟原理能否数学化是判断科学学科是否成立的重要标准。不同于数学思维,接下来的统计思维则是科研中最通用的一种方法论而基于抽象能力的模型思维则是现代科研必不可少的重要工具。本章最后会讨论启发法,这大概是在信息不充分条件下最重要的科研思维工具。

4.1 科学思维

虽然做科研一般都不讨论哲学,太多形而上的东西,说也说不清道也道不明还无法证伪。但懂一点科学哲学还是很有必要的,不然很容易研究着研究着就会觉得自己做的东西是垃圾,是谋生的工具,虽然从某个角度看也没错,但科学哲学无疑是应对这种心态最好的心灵老鸭汤。

首先,哲学是解决人与世界关系的学问,而科学在词源(scientia)上是知识学问的意思,追求的是正确的东西或真理。哲学很多时候与哲学史等同,提的问题几乎万古长存,各流派解读的保质期也很久,因为没法验证也就不存在伪的可能。科学跟科学史或者说博物学就完全不同,是一种探索自然的理性精神,很多知识会被更新,了解科学史会更博学但并不增加科学知识本身,因为对于一件事科学上的描述几乎唯一。当我们认为自然是可知的时候,科学就是探索其原因原理的认识方式并提供方法工具。

科学方法论构建于三个基础之上:观察或实验、数学还有逻辑工具。观察与实验要做到可重复、可比及随机;数学提供量化评价工具;逻辑工具包括不限于归纳演绎、分类类比、公理化及假说演绎。科学提供的一定是系统性规律性的知识,任何学科如果没有自己的理论系统、数学模型与验证都只能算知识或经验,谈不上科学化的学科。科学哲学主要关注哲学史里跟科学相关的世界观、认识论与方法论。

4.1.1 古希腊

哲学是爱智慧这个梗就不多说了,扯古希腊也显得俗套,反正有了古希腊人才有了理性跟逻辑的提法。古希腊前面的历史可理解成经验性知识的发展,知识多了就要有规律总结出来,逻辑和理性可看作用来生成规律的知识。其实哲学就是认识世界的知识,泰勒斯有一套,毕达哥拉斯有一套,赫拉克里特有一套…大家能自圆其说就来一套,对不对另说,不服就辩论,赢了就是真理,输了就是谬误。逻辑与理性最早就出自于这些街头巷尾的辩论,两套理论对比,总得有两方都认可的法则才有结果,理性或许就是这种普遍性知识的产物。

不过辩论有诡辩这一说的,苏格拉底看不下去了就说你们这些人都觉得自己对,但有可能是不对的,反正我自知我无知(这句可能是世界上最有智慧含量的句子,还有一句:天下没有免费的午餐)。苏格拉底不怎么关注解释万物,有点回归个人或社会的意思。到了柏拉图直接就理想国了,世界形物均为理型的影子。再到了亚里士多德就不怎么废话了,直接取消理型世界的存在,认为万物有因,这个因就是所有问题的因,寻找到最终因,真理就明了了。亚里士多德这个看法后来发展成第一推动问题,宗教界觉得只有全能的主有这能耐,就把亚里士多德的理论吸引到宗教哲学里去了。

同时,我们现在所提到的科学源于日本,可理解为分类的知识,而最早对人类知识体系分类的就是亚里士多德。他还很神奇的将自己的目的论揉到这个分类里去了,亚里士多德分类体系很完整,能解释的东西很多,所以后来几百年大家就都用了这个体系。其实这时候科学知识更适合分到亚里士多德所谓的自然哲学这个科目里,这个科目特指自然现象的规律及探索方法。这里需要注明的是数学更多是工具,数学化不一定就代表科学,另一个需要注意的是逻辑学,亚里士多德的三段论十分精彩,以至于要不是后来哥德尔横空出世,任谁也动不了根基。

4.1.2 中世纪

中世纪黑暗吗?如果看天气应该跟现在差不多,但这个黑暗的印象大致源于天主教对知识的垄断,而知识也反过来服务宗教,而宗教理性在一定程度上促进了我们对世界的认识,所以盲目对立宗教跟科学没必要,很多前期知识都是不少富有宗教热情的理性人士总结的。只不过知识很多种,科学在那年代连个独立的名字都没有,大体可以分为偏形而上学的自然哲学与偏事实的博物学,所以你看,牛顿写本书叫《自然哲学的数学原理》,跟现代意义上的科学没啥关系,所以你管他信仰什么呢,而博物学的英文是 nature history,只是后来伴随各学科发展基本都理论化为专门的学科了。这个时候,科学知识跟形而上学还是分不开,很多知识有严谨的数学形式但你无法证实,很多天文学知识就这德行,你去看看托勒密日心说体系,圆环套圆环的也能解释现象,那哥白尼的日心说为什么就流行了呢?因为是真理?因为结构简单?还是因为他用了别人看不懂的语言写出来的?或者说反对者死绝了新理论就流行了?总之,没有实证的理论流行起来不会是你想的那么简单,但一般来说,人们都喜欢简单且解释面广的理论,宗教也这样,毕竟他们认为美的东西都是上帝赐予的,而简洁就是一种美。值得注意的是这种简单为上的奥卡姆剃刀原理就是中世纪末神学家提出的,现在也经常被科研工作者提起。在科学这个提法之前,用一套知识来解释世界是各代学者所向往的,才不管验证什么的,理性重于事实。

中世纪产生了奥古斯都的教父哲学,吸收了柏拉图主义,认为理性要服从信仰,上帝只能信仰,不能认识。其后出现的经院哲学(代表人物托马斯·阿奎纳)则更多吸收了亚里士多德的思想,认为理性有助于信仰,认识提供了客观性。不过总的来说,中世纪神学成了唯一的学问与意识形态。学者吸收了古希腊哲学中形而上的部分,但对于探索自然与事物规律兴趣不大,更多放在神学经典的理论化抽象化上,例如针尖站多少天使的讨论之类,虽然也算理论问题,但对改善生活质量意义不大。

4.1.3 文艺复兴之后

历史的发展是伴随知识的增长的。大航海时代为人类的知识提供了一个海量来源,文艺复兴带来了人性的解放,宗教改革让生活走出了政教合一,经验开始比逻辑更为人接受。英国的培根开创近代唯物论与经验论学派,提出实验是获取知识的途径,打击了经院哲学过分看重逻辑与教义而不重视现实事物的观点;而欧洲大陆的笛卡尔则开创了二元论,创立唯理论学派,其基本出发点在于如果你的存在只因为你思考与怀疑才会出现,不思考啥都不存在,所以思考就是第一推动,依赖感知世界的经验不如理性思考更接近上帝,在这里笛卡尔反对的是经院哲学里对教条的推崇,主张怀疑与思考。

虽然这两派都是反对经院哲学,但却开启了欧洲大陆的唯理论与英国的经验论的争执,争论核心在知识的构建是从理性出发还是从经验出发,这两种观点打架几百年。在经验论学者看来,经验是一切知识的来源,感性认识很重要,归纳很重要。培根的继承者霍布斯基于伽利略的力学提出了机械唯物主义。洛克则制定了经验论的认知论体系。发展到巴克莱就成了“存在就是被感知”,再往后到了休谟则发展成了彻底的怀疑论,他批判归纳方法论的循环论证,认为除了感觉什么都不可知,终结了古典经验论。而唯理论学者则认为理性来自于自明之理,可以把握事物本质,只有理性推导或演绎出来的知识才可靠。斯宾诺莎则强调了伦理道德的意义,提出几何学考察自然、心灵与情感。莱布尼茨则批判了洛克的经验论,系统化了唯理论。

到了康德的时代后,综合经验论与唯理论就很重要了。知识需要有普遍性且可以发现新内容,分析可以解释事物而综合可以把经验扩充。这样我们就需要一个科学可以成立的认知根基,一个逻辑分析可以立足且给经验扩充空间的基础认知概念。康德认为先天综合判断就是这样的根基,人的认识活动既不单纯是经验也不单纯是概念,本质是认识主体对经验概念的运用,在这个过程中依赖先天知识形成认识对象,也形成普遍必然知识。

那么什么是先天知识?可以理解为感性直观或数学,时间、空间是先天的,也是数学对象本质,时空先验保证了感觉的客观性与经验的实在性,感性世界能感知到的现象背后存在物自体。那么我们如何获得知识,需要知性或抽象能力,感性给了我们直观材料,而知性通过概念思维对象来形成具有普遍有效性的知识,从感性与知性结合角度康德提出先验逻辑,区别于只关注形式的形式逻辑,先验逻辑看重内容。而知性理论的综合就是理性,无条件、绝对、完整的东西。理性可以把知性推广到经验之外,是可以超越经验的。科学研究活跃在感性与知性之间,科学知识就是先天综合判断的结果,但物自体与绝对理性都不在科研范围之内。黑格尔在其后认为主体客体应该是辩证统一的,绝对精神统一一切,不过科学在黑格尔体系里就没什么科学,概念成了一切本原,无穷的辩证统一滚滚向前。在黑格尔哲学体系里部是自洽且不可证伪的,但很多宗教理论也是类似的,为了保证理论完整性而抛弃事实验证的哲学可以被称为形而上的理论,这跟科学已经没了关系。

到了19世纪末大家都不争了,因为实证主义一统江湖认为从经验中提取逻辑,然后再证实就好了,那些形而上的东西就不管了。此时科学哲学抛弃掉了神学的虚构与形而上学的绝对,只关心经验现象与事实及其背后规律。这时候科学哲学才独立出来,而观察式的经验也开始让位于实验式的事实,人们不满足于被动接受知识,开始主动去寻找真相。

4.1.4 逻辑实证主义

当人自己把握了主动权,原有的常识知识就要被逻辑重新检验,而无法检验的就划到形而上学这一类里留给做宗教神学的人去讨论。换言之,从柏拉图开始的将现实世界与理想世界的区分被打破了,原来的哲学家都醉心于构建理想世界而不关心现实生活,而逻辑实证主义则要求通过生活的事实来寻找真相。换句话,经验事实及逻辑推理被结合用在真理的探索上了。而经验事实的崛起则伴随着归纳法的崛起,事实成为知识的唯一来源,科学开始渗入并改造哲学方法论,这一转变真正让科学有了真理探寻的光环,一举扫清神秘主义与宗教束缚,直到今天还在深刻的影响着每一个科研工作者。值得一提的是,逻辑实证主义出现时正值数学遇到集合论悖论与物理学遇到两朵乌云,实验结果矛盾造成的理论危机其实是逻辑实证主义可以发展的诱因。此外,逻辑实证主义也深受马赫的新实证主义(一元论与反对力学绝对空间)、彭加莱约定论(约定是理论与经验的产物,对约定的选择自由而不任意,由经验引导)及罗素维特根斯坦的逻辑原子论(基于原子命题与事实来构造知识,哲学主题是命题的逻辑分析)影响。

逻辑实证主义是现代科学哲学中第一个也是唯一一个完整严谨的体系。石里克是主要代表人物,其主旨在于让哲学与自然科学密切联系,在新物理学而不是亚里士多德或康德体系上构建认识论与方法论。逻辑实证主义重视证实与观察,推崇可检验性,反对原因,推崇常规性与描述性,抛弃掉以太、原子、电子等理论对象,拒斥形而上学与过度思辨,强调逻辑分析方法。

但不久大家发现不对头,因为不确定什么叫做可证实,单纯基于经验如何证实全称理论?本质上就是逻辑实证主义所采用的归纳法不如演绎法严格,得到的结论有局限性,不够严谨。在逻辑实证主义阵营里,卡尔纳普注意到了证实的经验问题,改为了确证,也即是将证实卡在当前认识水平内,只要后面有新证据出现就更好进行条件确证,类似贝叶斯定理。卡尔纳普另一思想贡献则是语义分析,严格区别语言中的语义与形式,消除误解。

逻辑实证主义后期的代表人物是亨普尔,提出了科学说明理论,认为科学是用科学定律来回答为什么的问题。亨普尔强调相关性与可检验性要求,引入概率来体现归纳规律的说明力,认为定律和现象之间的演绎有效或高概率支持。不过因为反对因果强调逻辑形式分析,导致相关性在说明上的困难,在解释历史与日常事件上也显得脱离实际。

4.1.5 否证主义

面对逻辑证实主义,波普引入了更多批判性的思考。其出发点在于认为演绎法试错作为验证手段比单纯经验证实要靠谱。大家都提假说,然后验证它,出现反例就把假说否了,不能否证就不科学,这就是证伪。一时间大家都接受了,神马佛洛依德,历史唯物主义都因为自洽但不能证伪给踹出科学圈了。证伪也可理解为试错,如果连错都理论上不存在,那就肯定不是科研可以搞的,大都是循环论证。这里奥卡姆剃刀再次登场,认为越简单的理论就越容易检验,复杂如哈奇森效应的现象与理论不值得研究。

不久又有人感觉不对了,一方面演绎法很难产生新知识,另一方面貌似假说是无穷无尽了。证实比较费事,证伪容易但很多理论就垮了。为了调和这个矛盾,否证主义给出的答案是演绎法虽不能产生新知识,但假说的产生不是无缘无故的,而知识的进步应该通过大胆猜想的确证与谨慎猜想的否证来完成,一个推翻的理论必然联系着新理论的提出,这时不断发展的,而科学的任务就是处理进步问题而非回答真理问题。形而上学也并不完全被排斥了,因为假说的提出有时就是没有事实证据的。进一步讲,波普尔将世界分成世界1,也就是物理世界,世界2,也就是精神世界,然后又分了个世界3,也就是客观知识世界。这种三分法其实是将柏拉图的理型世界进化了,同时也留下了世界2的个人空间。每个世界都在进化,这就是科学发展的轨迹。一口吃不成胖子,我们就去试错吧!猜想与批判这一否证主义的核心思想也是当下科研中比较闪光与巧妙的实验设计动机来源。

4.1.6 历史主义

前面那些理论的提出者大都数理化出身,推理证明构建系统很在行,但没案例不成啊,得解释得了现象啊。其中一些人翻了翻了史书,发现很多发现不是通过证伪得到认可的,也不是建立在大量归纳的基础上,而是具有“历史性”。也就是逻辑不怎么灵光,然后他们就说咱以史为鉴吧!拉卡托斯就搞出了个硬核软核的理论,大意说一个理论是有生命力的,硬核部分无须质疑,有保护带,一时半会死不了。需要缝缝补补的是外围软核,什么时候硬核也不行了,就退出历史舞台了。这个解释保全了科学理论体系,也就是堵了民科的路,要知道民科最喜欢证伪,一个错误就否了整体,现在拉卡托斯说不成,得慢慢来,有历史的。理论是互相连接成一个纲领的,出现了反常并不可怕,可以理论自身发展来接纳反常。当一个纲领无法发展或出现另外的纲领可以解释更多事实时,此时会逐渐淘汰掉退化纲领,其分界标准在于对新事实的预见性。

不久又有人感觉不对了,我怎么知道现在的硬核到底对不对?拉卡托斯这时就呵呵了,交给历史评价吧!库恩在这个背景下提出了范式,他本身有较强的历史功底,手头案例多,所以有了科学共同体这个说法。大意就是一个时代的真理主流说了算,这伙人挂了而接任的更多采取了另一种解释现象更多的理论,那这个理论就上位了,就革命完成了。前面那个时期比较压抑就叫前科学,后面上位了就是常规科学。之后又有新现象解释不了了就有了危机,这时候新理论又出现了,再搞一次革命就舒坦了。范式是来区别前科学与常规科学的,范式通常是一套当前时代科学共同体所使用的理论体系,而这个理论体系要比之前的更能解释更多的问题也更严格。这理论比拉卡托斯那一套通俗易懂,那年代搞政治的一看有革命二字纷纷表示深有体会,大力推广之,所以范式着实火了好一段时间,不过此时理性主义已经让位于非理性主义。

库恩的范式革命是格式塔式的转换,历史上一共也没发生几次,真正有益的是他对范式定义时要求要有自称科学的学科要有自己的理论体系与假设且对现实世界产生作用,这个理论自身并不要求科学家的态度是客观的,但范式自身要是客观的。这时候,大家都不愿搭理真理性这茬了,因为都清楚对错问题是历史性的。同时范式也把形而上学彻底请回到科学体系中了并认为对科学的发展是有益的,要知道波普尔虽然不拒斥形而上学但本质还是批判形而上学的,所以历史主义的强调使得真理相对化。

4.1.7 无政府主义

事实上你沿着这个思路走下去发现貌似科学发展跟三国演义差不多,不在于对不对而在于认可的多不多,有没有跟你闹革命的。当然因为实证主义的余威,理性与逻辑在科学研究中是绕不开的。这时候来了个更霸气的费耶阿本德,一拍桌子,科学跟别的知识没啥区别,不能特殊对待。 后来流传到世上的就是那句 anything goes 。他信奉无政府主义,认为科学在无政府主义下比起理论上的法则与规律更鼓励进步,更极端点就成了达达主义,不对科学设定任何边界,也不坚持逻辑一元论,提倡非理性的科学观,以自由名义反对科学主义。很多人认为这货终结了科学哲学的发展,从20世纪初到六七十年代这个学科就完蛋了,这就是科学哲学的学科理论危机。

4.1.8 实用主义

逻辑委实打不过历史,原来那些搞科学哲学研究的还没死就没饭碗了,生存是硬道理。他们发挥了科学共同体的作用,把费耶阿本德斥为异类、后现代。但他说的话又绕不过去,这时候劳丹提出要回归理性,提倡进步性,而进步性应该是解决问题能力的增强,此时追求真理已经不再重要。而美国人想来想去想到了有用两个字,然后大家纷纷鼓掌。理性,历史都打不过生存这个命题。有用是硬道理,有用解释一切,然后就没有然后了。

4.1.9 其他

除此之外,由于逻辑讲求语义明确而严格,但要是日常交流用一堆符号估计谁也受不了,所以科学哲学也在语义学方面继续发展。英国人的经验论也促进了新实验主义与主观贝叶斯学派的发展,慢慢地科学哲学也开始接受一些非实在论的观点,而科学实在论是穿插在上述命题中的。

科学哲学从实证主义发展到今天,被各种新命题与发现折腾的够呛,从里面提一个片段就可以看到很多,科学是什么?它跟哲学啥关系?又对哲学发展有什么样的影响?总之,我们没有停下探索真理的脚步,答案在哪里也毫无头绪,只要不满足于现状,知识就存在进步的可能,同时须知人生苦短,自知无知是很重要的。

就科研本身而言,最开始属于观察现象然后总结规律的经验方式,后来慢慢形成学科体系与知识框架来设计实验预测解释事实,现在其实更多是逻辑与经验的混合来解决科学问题。也就是说,学科知识是基础,但问题总出在前沿也就是知识覆盖不到或部分覆盖的地方,经验论与唯理论的斗争时常出现,单纯看经验或者说观察与实验会推动问题的解决,但有时候也推不动:很多规律不一定经得起检验,还有很多规律需要的限定条件太多进而导致应用上矫枉过正,还有些学科提出规律本身产生的反馈会导致规律失效(也就是反身性,在观察研究学科中比较多)…规律不代表真相,只是事实的一种描述,所有规律都要接受且长期接受事实检验,直到被描述更精确全面的规律取代。科学靠谱很大程度是规律性进行的保障,规律保证了可预测性,但其实很多规律描述同一问题的话恰恰说明这个问题很复杂,没有简单规律。规律要有数学背书才会严格,但数学本身又不代表科学。规律间互相支撑就可以构建学科的知识体系,如果一个学科没有被广泛认可的规律,那么共识就无法建立。

4.2 数学思维

数学是关于数量关系与空间形式的学科,是数与形的学问,核心是培养数学思维。数学思维主要是证明与计算,前者锻炼逻辑推演思维,特别是基于公理体系的推演,后者锻炼计算与算法构造思维。数学不是科学学科但为科学提供思维与工具,无法数学化的科学知识很难独立为一门学科。这里结合数学史简单概览下数学思维的发展。

数学早期有很强的实用目的,例如计数与算术,古希腊时期逐渐过渡到几何公理体系。古希腊数学代表人物有泰勒斯(半圆直角定理)、毕达哥拉斯(万物皆数、黄金分割、无理数)。在雅典时期出现了芝诺(无限概念)、巧辨学派的三大作图问题(立方倍积、化圆为方、三等分角)、雅典学院(不懂几何莫入)与吕园学派(亚里士多德三段论)。到了亚历山大时期,欧几里得写出了《几何原本》,给出了世界上第一个公理体系。阿基米德提出类似积分的平衡法。后来中世纪降临,女数学家希帕蒂亚之死与亚历山大图书馆被焚标志着希腊数学的终止。

古代中国用图形数字标示规律是河图洛书。《墨经》里也出现了理论思辨的萌芽。《周髀算经》与《九章算术》是早期的数学经典,涉及了负数、无理数、方程术等概念。几何上赵爽弦图给出了勾股定理的证明,刘徽提出割圆术,祖冲之计算了较为精确的圆周率,虽然其学术作品《缀术》失传了。宋元期间有贾宪三角与正负开方术、秦九韶的大衍求一术、沈括内插法、天元术及四元术等。印度早期有巴克沙利手稿而阿拉伯世界大力发展了代数学并翻译了大量古希腊经典。数学知识伴随贸易与战争从各文明起源地逐渐汇拢到了西欧。

文艺复兴时期,斐波那契写了《算经》,介绍了印度-阿拉伯计数法。韦达的《分析引论》确定了代数符号体系与代数运算。绘画发展促进了透视与立体几何的研究。到了笛卡尔,他注意到几何与代数无法互补,同时经院哲学无法发现新知识,进而在《几何学》提出了通用数学的概念。首先把任何问题都抽象成数学问题,然后数学问题代数化,联立方程求解,求解过程用几何方法辅助。

到了大航海时代,贸易与航海的需求让很多计算问题有了实际的对应,例如瞬时速度、切线、函数极值、重心引力计算等。在此基础上,微积分的发明就尤为重要,牛顿跟莱布尼茨的优先权之争背后是英国经验主义与欧洲大陆理性主义的借鸡下蛋。然后达朗贝尔、欧拉、拉格朗日等进一步严格化微积分。后来偏微分方程论与微积分的共同发展形成了现在的分析学。不过,在18世纪末出现了悲观主义,认为数学到分析学只剩下细枝末节了。

不过19世纪,代数学又开始了新发展,从研究方程和具体的数到了抽象集合的运算规律,开了新天地。几何学也不在纠结第五公设,直接进入非欧几何的新世界,高斯功不可没。后来,几何学统一到了克莱因埃尔朗根纲领下,成为研究几何图形对于某类变换群保持不变的性质的学问。人们对几何的认识,从三维到高维,从平面到弯曲,从刚性到影射,只要数理逻辑上成立,皆可研究。到了19世纪末,除了集合论相容性问题,分析的严格化几乎完成。

进入二十世纪,希尔伯特公理化方法尝试了更高更基础的统一性。在此基础上,出现了纯数学、泛函分析、抽象代数、拓扑学、概率论、动力系统、随机过程、代数几何等研究方向。不过,集合论悖论及哥德尔不完全性定理给了数理逻辑进一步发展的可能。这个时期的主要进展有两个,一个是数学难题的攻克,另一个则是应用数学空前繁荣,渗透到了几乎所有知识领域。应用学科中,数理统计、运筹学、控制论、博弈论、计算机科学等都算是相对独立的学科了。数学自身正在致力于解决难题,相当一部分难题是纯粹抽象的,跟科学关系不大了。然而,科学正在不断整合借用数学工具与思维,探索世界的规律。

数学的学科发展跟科学有密切关系但本质是不一样的。科学是要做真假判断与验证的,哪怕知道这会被推翻。数学则有自己相对完备的逻辑世界,可以做到一定程度的纯公理演绎。数学基础理论无法证伪而科学理论一定存在被推翻的可能,被数学化的科学如果无法与事实接轨只能被看作假说,例如弦论就存在逻辑自洽的多个版本。科学是一个不断发展的过程,需要实验与观察来更新自己,数学可以不依赖这些。

4.3 统计思维

统计思维包括但不限于抽象、似然度、回归、因果、残差等。这里推荐《统计七支柱》、《为什么》与《女士品茶》作为统计思维的理解读物。统计思维可能是科研中最重要的一部分,更多数据分析内容见第五章。

4.3.1 抽象

最原始的统计需求就是对客观世界的抽象,跟农业最相关的天文观察要求所有测量要准确,但问题每次测出来都会有差异,那么就需要一个方法来描述相似但不一样的测量值,这就是统计聚合思想的来源。科幻小说中有照相机记忆的人是无法分析事物的,他们只能记住所有细节,而这个负担是非常重的,此时抽象的意义就很大了。所谓大数据就好比这个人,细节丰富但需要抽象,不然就是一堆数字的堆砌。这里最常见的统计学术语就是众数、中位数还有均值,都是聚合抽象描述的体现。

创立统计量是第一步,需要背景知识的辅助与对数据本身分布的描述。数据分布是非常基础的统计量构建工具。例如正态分布是随机数的集合;对数正态分布是随机数乘积的分布,为正数,单对数坐标轴是正态分布;幂律分布是出现在双对数坐标轴的直线,产生于优先连接模型或马太效应,另一种解释是自组织临界现象,例如林火模型等灾难的积蓄发生,社交从众增加了不平等,更多机会尝试会有更大方差结果出来等等。背景知识是对分布的逻辑解释,这对预测或工程应用也许意义不大,但科研需要知道为什么。

当我们形成一个统计量,其实是丢掉了一些信息的,但更有意思的是对同一个事物的描述,即便测量的准确性上没有差别,后来的观察贡献的信息并不如早期多,信息量与观测数的开方正比而不是观测数。举例来说,早期造币按批次称重,误差r,10个一起称的误差就并不是10r,100个一起称也不是100r,你称10个得到的误差与称100个得到的误差精度最多高一倍,也就是后面90个硬币提供的信息大概等同于前10个提供的信息,这个现象也是统计学里很常见的,基于此我们可以去搞采样及基于分布的理论而不至于担心丢失太多信息。

在分布属性中,方差值得特别关注,因为方差体现了数据的变动或者说异质性,而数据的变动直接影响结论的可靠性。方差分析的核心思想就是检验数据的异质性,看你设计的分类是否让组内是均质的而组间是异质的,如果我们方差分析做的足够好,应该可以把整体数据拆成一个个可解释的符合数学描述的分布。同时方差作为衡量变动区间的一个指标对于风险控制与区间估计也很有意义,关注方差就比只看单一描述提取更多的信息。

4.3.2 似然度

似然度是另一个重要统计概念,有了测量就可以进行比较,最通常的比较就是跟随机事件比,有了随机事件就可以谈概率了。此时特定分布下概率就是似然度,看看某件事在大背景下出现的可能。p值理论的根基就是似然度概率且最初的p值概念里就是仅仅去看零假设下的发生概率。1920年Fisher提出,如果A代表科学目标,X代表数据,那么定义似然度函数L(A|X)为出现X的A的概率密度函数,X已知,找这个函数最大时的A,一阶导数为0找到参数,二阶导数描述准确性,但这里面最大的问题在于对于方差估计是有偏的,特别是数量少时,而维度高了这个问题就很严重了。

抛开这个,基于概率的推理本身就是统计学很特殊的世界观,简单说就是只要概率不为零,一切皆可能。休谟认为奇迹是违反自然法则不能发生的,但 Richard Price 用贝叶斯理论推导认为即使发生概率很小,多次实验后也会发生奇迹,在这里经验法则跟统计规律就出现了对立。传统世界观是决定论的、逻辑的,但统计世界观是概率的,不可知的或可更新的,值得注意的是,这种不可调和的差异也存在与量子力学与经典力学的世界观之间。很难说那种是世界本来面目,只能说这是两种认知角度,可以矛盾地存在于同一个人身上。

有了面向背景目标的似然度,统计学可以解决外部比对问题,也就是跟预设分布去比较。然而,现实问题更多是数据内部的异质性所要求的内部比较,很多耳熟能详的统计方法例如t检验,方差分析,Bootstrap等都是用来解决内部比较问题的。1908年, Gosset 用 Cushny-Peebles 数据展示单样本t检验,他考虑了样本方差在样本数较少且总体方差未知时如何估计,引入了自由度与样本方差,得到一个近似正态分布的t分布,这篇论文印错了数、分类也错了、引用年份也错了,但最后结果还可以有历史意义的。但这篇论文出版后很长时间无人问津,Fisher在1912年毕业后将这部分内容写信给 Gosset 后来转给 Pearson 但都没看懂,后来 Fisher 提出双样本t检验并结合相关系数与方差分析写在了1925年教科书 《Statistical Methods for Research Workers》 中,到这里这个相对通用的内部比较方法才开始真正流行。再往后Tukey 提出了jackknife,Efron 提出了Bootstrap,都是从样本内部进行比较来估计差异变化。值得注意的是数据量越大,内部比较出现的随机相关就越多,特别是时间序列,这是很容易遇到的研究错误。此外,涉及时间的随机过程,最简单是二项分布,一维随机游走会穿过原点,距离符合幂律分布,如果概率占优,应该少量多次而不是一把梭哈。随机行走可用来判断网络规模,如果随机行走回原点概率很高,那么网络规模就不大。

4.3.3 回归

回归思想应该是统计学作为世界观最直接的体现,一般人看世界是发展的或静止的或规律决定的,但统计学家看世界是自带回归视角的,也就是说,凡事都会回归到本来的样子,规律性是松弛有度的,凭运气赚的财富与名声都可以凭能力天花板赔出去。

用进化论来说,最初其理论体系是不完整的,里面假设了同一个亲代会产生不同的子代,如果不断产生,这个变异累计会无穷大,出现怪物,实际代际间差异并不大。这里的矛盾是等比法则,例如身高体重比如果稳定可以在知道父母代身高体重与子代身高的情况下推出子代的体重,这样子代的高身高一定意味着高体重,但现实数据并非符合这个强规则。

这个问题最早被高尔顿钉板所发现的。高尔顿板现在虽然常用来解释正态分布,但当年高尔顿设计这个是为了展示一个遗传悖论:如果第一代的后代会产生一个分布,那么多代之后这个分布会越来越宽。打个比方,父母身高170,孩子180,孙子185,那么如果存在长高遗传的话,总有个N代孙子身高一层楼,毕竟每一代都会产生一个均值为这一代身高的分布,你肯定找的到更高的下一代,如此反复就应该出现巨人子孙。现实则是不论哪一代,身高分布基本稳定,人群中很高的人后代也高但不会那么高,很矮的人后代也矮但不会那么矮,这就是向群体均值回归与两代人身高相关的现象。如果关注极端小部分会发现其主要来源是不极端的部分;相反不极端的部分也会有来自极端部分的回归。

# 代码源自animation包quincunx函数
op = par(mar = c(1, 0.1, 0.1, 0.1), mfcol = c(4, 1))
nmax = 10000+15-2
# 15层钉板
layers = 15
# 10000个小球
balls = 10000
# 模拟三层钉板
layerx = layery = newlayerx = newlayery = NULL
flagi = ifelse(layers%%2, 1, 0)
for (i in 1:layers) {
        if (flagi) {
                newi = ifelse(i%%2, 1, 2)
        }
        else {
                newi = ifelse(i%%2, 2, 1)
        }
        layerx = c(layerx, seq(0.5 * (i + 1), layers - 0.5 * 
                                       (i - 1), 1))
        layery = c(layery, rep(i, layers - i + 1))
        if (i > 1) {
                newlayerx = c(newlayerx, seq(0.5 * (newi + 1), layers - 
                                                     0.5 * (newi - 1), 1))
                newlayery = c(newlayery, rep(i, layers - newi + 1))
        }
}
# 模拟小球过钉板
ballx = bally = matrix(nrow = balls, ncol = nmax)
finalx = newfinalx = numeric(balls)
# 第一层钉板
for (i in 1:balls) {
        ballx[i, i] = (1 + layers)/2
        if (layers > 2) {
                tmp = rbinom(layers - 2, 1, 0.5) * 2 - 1
                ballx[i, i + 1:(layers - 2)] = cumsum(tmp) * 0.5 + 
                        (1 + layers)/2
        }
        bally[i, (i - 1) + 1:(layers - 1)] = (layers - 1):1
        finalx[i] = ballx[i, i + layers - 2]
}
# 第二层钉板
rgx = c(1, layers)
rgy = c(0, max(table(finalx)))
newballx = ballx
diag(newballx) = finalx
for (i in 1:balls) {
        tmp = rbinom(layers - 2, 1, 0.5) * 2 - 1
        tmp = ifelse(newballx[i, i] + cumsum(tmp) < rgx[2], tmp, 
                     -1)
        tmp = ifelse(newballx[i, i] + cumsum(tmp) > rgx[1], tmp, 
                     +1)
        newballx[i, i + 1:(layers - 2)] = newballx[i, i] + cumsum(tmp) * 
                0.5
        newfinalx[i] = newballx[i, i + layers - 2]
}
# 绘制钉板与分布图
plot(1:layers, type = "n", ann = FALSE, axes = FALSE)
points(layerx, layery, pch = 19)
hist(finalx,breaks = 1:layers,main = "", xlab = "", ylab = "", ann = FALSE, axes = FALSE, xlim = rgx, ylim = rgy)
plot(1:layers, type = "n", ann = FALSE, axes = FALSE)
points(newlayerx, newlayery, pch = 19)
hist(newfinalx,breaks = 1:layers,main = "", xlab = "", ylab = "", ann = FALSE, axes = FALSE, xlim = rgx, ylim = rgy)
双层高尔顿钉板对回归现象的演示,第一层产生的离散分布通过第二层钉板并未出现进一步的分散

图 4.1: 双层高尔顿钉板对回归现象的演示,第一层产生的离散分布通过第二层钉板并未出现进一步的分散

另一种理解方法是:每个人的身高都有固定部分跟变动部分,固定部分是都一样的,遗传来决定,这样代际变化可以用亲代子代变动部分的不完全相关来解释。同时,达尔文的自然选择就可以构建在遗传上了,至此人口平衡与代际变异就可以有统计模型来和谐相处了,否则不论是强相关还是不相关都不能解释现实数据。回归思想可以说是统计学的中庸之道,这个将效应区分为固定跟临时两部分的思想也构成了经济学里消费函数的根基,人们消费固定部分是收入而不是短期刺激,因而政府短期加大开支并不能刺激消费,这个指导思想帮助弗里德曼拿了诺奖。

多元回归问题在多元统计方法之前都是用几何学跟数据分析来解,最多两元,高尔顿提出相关系数后,皮尔逊等人发扬光大为多元分析。

4.3.4 因果

因果问题很长一段时间一直是统计禁区,从学统计第一天我们就知道相关不代表因果,那么问题来了:如果相关性是个逻辑死胡同,知识如何增长?打个比方,我看到人群中某个基因的高表达与某种疾病的发病率存在相关性,怎么解释?是发病导致基因突变还是基因突变导致发病?一般到这一步就需要控制实验了,也就是说我们把控制实验当成因果关系的确认而对观测数据持谨慎态度。但这实验怎么做?找一组人,用 RNA 干扰 沉默掉他们的基因看是不是得病?现代伦理不允许。用动物模型?物种差异咋办?仿真?我们搞清楚分子层面的构建机制了吗?目前相对公认的结果来自分析流行病学,金标是队列研究、临床实验与病例对照实验。严格意义上只有临床实验最靠谱,但那就真成了拿人做实验了,治疗目的问题不大,但研究目的就存在伦理问题。自然科学里控制实验容易些,很多时候因果性不言而喻(也因为这个缺乏了统计思维)。社会科学与医学就必须解决从观察结果中发现因果性的问题,不然永远只能讨论现象,因果分析就来源于此。

其实在研究回归问题时,高尔顿曾为此迷惑不解,主要是遗传意义上讲不通,高了后还是高,但没那么高,后者暗示遗传上的因果并不完全成立。但他学生皮尔逊则很简单认为这种回归也好或相关也好就是概率的,因果关系是相关的一个特例,统计学不能也不应该讨论因果性,进而奠定了后面研究中相关不代表因果的基调,用严谨性与概率锁死了观察研究,这个表述到今天还活跃在科学研究的各个领域。

其实皮尔逊虽然从概率角度澄清了单一因素在解释现象的局限性,但他自己也发现了很多伪相关或随机相关,更麻烦的是他的学生赖特在豚鼠研究中构建了多因素路径模型来解释遗传问题。赖特在豚鼠遗传问题上假设了遗传、发育、环境与随机四种来源并用路径代数分析估计了各自影响的比重,虽然赖特自己并不认为他在用相关推导因果,但 Juder Pearl 认为这是第一次用图论来进行因果关系的探索。赖特定量算出了豚鼠子代体重增长中遗传的贡献,然而这个方法在之后的50年里被统计学界打压了。统计学家认为赖特的方法只能就事论事构建逻辑关系来进行考察,但当时的统计学主流是用“固定程序”解决问题,而大量的精力耗费在了“固定程序”的理论与细节构建。统计学家在跟别人合作时通常会让对方把数据转化为他们能处理的分布进而应用标准方法来分析,但这严重忽视了现实世界的复杂性并造成了大量统计方法的误用。现在我们知道赖特实际做的是把专业知识形成的假设因果关系进行了定量分析,而脱离专业知识的统计学正是其目前被应用导向的计算机科学超越的一个原因。在我看来,因果分析是联系统计学、专业知识与计算机科学的一个关键方法与思维工具,科研里探索的就是因果与机制,定量考察因素影响的因果分析方法是一个重要步骤。

到此我们回顾下相关,如果不能说明因果,又能说明什么?两个因素之间因果也就是一个到另一个,但相关之所以说明不了因果,其实是因为存在第三种因素或更多。但简化下三个因素之间的关系其实大概就下面这四种:

  • A导致B,B导致C \(A\rightarrow B\rightarrow C\)
  • A导致B跟C \(A\rightarrow B, A\rightarrow C\)
  • A跟B共同导致C,控制C后A跟B相关 \(A\rightarrow C, B\rightarrow C, (C): A \rightarrow B\)
  • 随机相关

这里我是用箭头表示因果,用括号表示控制。第一种很明显就是直接因果关系,这里因果关系是传递的,如果你控制了中间那一个,因果关系就阻断了,这是所谓的中介效应;第二种我们会观察到B与C相关,然而这种相关在控制A后会消失,A就是我们经常提到的混杂因素,例如巧克力消费量与诺奖得主数相关,背后是因为他们都跟国家经济发展水平相关,当国家经济发展水平一致时,巧克力与诺奖间的相关性就会消失。这两种接受过统计学教育的都比较容易理解,第三种就不那么直观了。

糖尿病会导致血糖高,吃糖多也会导致血糖高,正常我们是看不到糖尿病与吃糖多相关的,因为这是两回事,健康人吃糖多也会血糖高。然而,当我们控制一个高血糖浓度区间去看糖尿病发病率与吃糖行为时,他们就相关了,也就是高血糖的人既可能是病人也可能临时糖吃多了,如果我们只看一个时间点,很容易发现吃糖与糖尿病的相关。也许你会说吃糖就是导致糖尿病,但如果我们看的是I型糖尿病(遗传原因主导)呢?你也会发现相关。这种相关只在控制了血糖后出现,不控制两个没有相关性,这种相关是对撞关系在控制后导致的。很多人做研究喜欢在模型里加上尽可能多的协变量,这个方法可以处理第二种情况,但协变量如果是第三种情况控制后会把不相关的两个因素搞成相关的,这个情况很多研究人员意识不到会导致错误结论的出现。第四种情况也存在,特别是高维数据,这就是因果分析与p值问题的连接点,多重检验里如何排除随机相关或显著性已经是当前学术界意识到的问题了。

也就是说,当我们看到两个变量相关,除了因果与混杂,还存在对撞与随机相关,对撞是不恰当控制变量导致的而随机相关则对高维数据是一个灾难。因果分析所要做的就是区分这些并正确估计或探索变量间的关系,理清楚了这些基本关系,也就可以通过演绎法探索相关背后的因果了。

这里有个概念要说清楚,那就是控制。什么是控制?控制就是让某个因素恒定,在线性模型里就是加上一个变量,此时拟合后其他变量的拟合系数就是控制了这个因素后的效果。当然,如果存在非线性关系例如交互作用,控制就会复杂些。控制的神奇之处在于我们不需要事先处理而仅仅是分析时加入考虑即可。Juder Pearl 引入了 do 演算的概念来补充概率论里条件概率对控制干预的先天不足。P(A|B)与P(A|do(B))实际计算可能是一回事,但在因果图里就很不一样了,do 表示一种单向干预而概率论里的条件概率没有方向性。举个例子:

\(A \rightarrow B \rightarrow C, D\rightarrow A, D\rightarrow C\)

现在我们想知道A与C的关系,目前走 ABC 路径是通的,AC路径会因为存在混杂因素D也是通的,那此时你就无法认定A与C之间是否是因果关系,这个时候要做的就是对D进行控制,阻断A与C间的混杂因素途径;同时如果对B进行控制,阻断A与C之间B的中介途径。这样之后看A与C间的关系就知道剩下的因果关系了。其实更严谨的方法是 Rubin causal model(RCM),也就是 Donald Robin 提出的因果分析框架直接计算,不过用因果图更直观些。

因果图里这个过程叫做 do 分离,用 do 的控制行为隔离掉非因果影响。当我们根据推测的变量间关系画出因果图后,do 分离就可以很直观的看出来。例如面这个关系:

\(A \rightarrow B \rightarrow C \leftarrow D \rightarrow E\)

这五个变量的关系中A与E间的通路被C阻断了,所以我们什么都不用做可以直接相关判断A 跟E的因果关系。然而,如果我们对C进行控制,B与D因为对撞结构控制后相关,此时路径就通了,此时我们无法直接考察A与E的因果关系,但如果我们接着控制了B或D,路径再次被阻断就又可以讨论了。

也就是说,如果我们打算考察两个变量因果关系,首先要根据实际情况画出因果图,然后 do 分离掉所有两个变量间的路径,此时两者的相关就是因果。这个方法很直观,当变量间关系很复杂时,我们依然可以通过考察通路来找出控制方法。由于神奇的贝叶斯定律可以让你调转条件概率的方向,所以代数上你可以在一定条件下将控制过程转为条件概率,这也就实现了从观测数据里提取因果关系的目的,这套演算过程就是 do 演算,配合因果图使用非常方便。从图里手工推导 do 演算的公式对科研人员要求过高,不过现在软件已经可以代劳,你只要画出因果图,软件就可以告诉你两个变量间因果关系推导的条件概率公式,代入你的数据就可以看到结果了。

下面我们看下因果分析的案例来加深对因果分析思想的理解。先看代际遗传,高尔顿的因果图就是:

\(遗传 \rightarrow 身高\)

并且认为相关系数是1,但如果身高同时被遗传与环境决定,那么相对稳定的环境贡献了回归现象而遗传则解释了相关性。科研实验中的控制变量法或随机本质上就是对所有可能的混杂变量或中介变量进行控制来阻断考察变量间的非因果关系。然而此时我们也明白了如果控制的是对撞变量,那么实际上我们有可能打通原来不相关变量间的通路。在这里 do 的含义一定是基于因果的而不仅仅是无条件控制,这个洞见非常有价值。

我们再来看吸烟与肺癌的案例,虽然很多人都知道我们最终是通过Cornfield不等式与希尔标准来接纳的因果关系,但用因果图来理解的话其实就是 Fisher 认为存在遗传因子即导致吸烟,也导致肺癌。Cornfield 不等式的实质就是认为如果存在这个遗传因子,那么其与吸烟的相关性应该与肺癌的相关性同步增加,然而现实数据中肺癌风险在吸烟者那边高了9倍,也就是说这个基因在吸烟者那边也得高9倍。在 Fisher 单挑其他统计学家的那个年代其实没有找到这个基因,有意思的是后来真的找到了这个促进吸烟的基因,只不过对风险贡献没那么大。一个更典型的案例出现在观察数据中,研究人员发现吸烟母亲的低出生体重婴儿存活率比不吸烟母亲的要高,好像吸烟提高了低体重婴儿的出生率。这里因果图是:

\(吸烟 \rightarrow 出生体重 \rightarrow 婴儿死亡率\)

当我们控制了出生体重后,会发现吸烟降低了婴儿死亡率,这明显反常识了。这个问题其实是五年前才解决的,研究人员提出了一个先天缺陷作为出生体重与死亡率的混杂因素,此时吸烟与先天缺陷都会导致出生体重低,如果我们控制出生体重,相当于打通了这条路径:

\(吸烟 \rightarrow (出生体重) \leftarrow 先天缺陷 \rightarrow 婴儿死亡率\)

又因为先天缺陷跟婴儿死亡率相关,所以吸烟与婴儿死亡率间存在了一条控制后的非直接因果通路。具体来说,如果先天缺陷比吸烟对低体重影响更大,造成高死亡率,那么我们只看低体重婴儿的话就容易把原因归结到吸烟而不是先天缺陷之上,到此观察数据的矛盾就解决了。本质上因果图可以帮我们探索新知识,而传统统计分析则更多就事论事而导致矛盾。不过直观归直观,其实 RCM 在推导上更严谨,不过我估计外学科理解因果分析还是会收敛到因果图上,直观可视化在技术推广上总是占优。这个阶段工具很关键,哪个软件简单易用,其背后的模型就可能最终胜出。

接下来知名案例就是辛普森悖论了。当我们整体看两组数据时会有差异,然而当我们将数据分层后这个差异就会消失或逆转。具体到辛普森悖论就是一组新药对人群整体有益,然而当我们按性别区分时,这个药对男性也好女性也好都没了益处。现在比较流行的解释是基于一个数学事实:部分的比例之和与整体的比例之间没有必然联系。在辛普森悖论中,对照组病死率女性为1:19,男性为12:28,服药组女性为3:37,男性为8:12,这样我们看到 \(1:19 < 3:27\)\(12:28 < 8:12\),这样不论男性女性,对照组病死率都低于服药组,药物无效。然而我们不看性别时,整体是\(13/47>11/49\),对照组病死率比服药组高,药物又有效了。这里形成悖论的关键在于人们会理所当然认为部分比例的差异结果会传递到整体,其实 \(\frac{A}{B}<\frac{C}{D}\)\(\frac{E}{F}<\frac{G}{H}\),但\(\frac{A+E}{B+F}\)\(\frac{C+G}{D+H}\)间是不能传递这种关系的,数学上就不成立,所以我们的直觉给出的悖论是惯性思维的错误。

表 4.1: 辛普森悖论
总康复 总死亡 总病死率 男性康复 男性死亡 男性病死率 女性康复 女性死亡 女性病死率
对照组 34 13 0.28 16 12 0.43 18 1 0.05
服药组 38 11 0.22 4 8 0.67 34 3 0.08

不过这只是解释,不解决最初的问题,到底这药有用没用。这里就又牵扯到因果图了,我们得知道性别对服药与结果的影响,也就是说得知道性别的角色。首先,性别不是服药与发病结果的结果,毕竟不是变性药;其次,性别是否决定服药?经过调查发现,女性确实比男性更容易记得服药;最后,性别是不是会导致结果,调查也发现男性容易患病。好,这样分析后性别就是服药与患病的混杂因素,因此服药与患病间不形成 do 分离,我们需要控制性别。怎么控制呢?很简单,就是分开性别讨论然后按性别在人群中比例加权,最后的结果就是辛普森悖论中的新药对整体其实是有害无益的,悖论解决。我们回顾下这个过程会发现,悖论的解决实际上是依赖了因果图构建过程中外部信息的整合,单纯看数据不看背景知识的纯统计探索在这种场景下会陷入悖论。所以说因果图或因果分析其实就是引入更多的背景知识,只是当前懂专业知识的与懂统计学的还没进行很好的学科融合。

不过性别不总是共同原因,也可能是中介。这个也比想象的常见,简单说就是下面的结构:

\(A \rightarrow X \rightarrow B\)

当我们打算估计 A 到 B 的净效应时,X也作为中介在起作用。比较经典的案例就是伯克利录取问题,整体上呈现对女性的性别歧视,然而分院系看却大都是女性占优势。这个案例经常跟辛普森悖论放到一起讨论,但因果图上是不同的。辛普森悖论里性别是混杂因素,伯克利录取里,A是性别,B是录取结果,而院系则是作为中介存在的。性别不同的学生会选择不同的院系,而不同院系录取率本来也不同。通常关于这个现象的解释是女性会选择难录取的院系,这件事造成了整体与结果的不同。

不过解法上倒是类似,因为控制了 X 之后就中断了这个路径而可以直接估计 A 与 B 的关系。但控制 X 相当于得到的是这个 X 下的录取率,要想知道全局影响,还是要加权平均。传统分析里直接效应间接效应的讨论无法区别中介与混杂因素,因果图则可以很好区别出来进行解释。不过中介问题的复杂性不在这里,如果存在一个对中介与结果的混杂因素,对中介进行控制就是错的。举例来说,如果居住地会影响院系与结果,例如某个州大学的甲院系就是只录取本州男性与外州女性而乙院系则只录取本州女性与外州男性,那么我们对院系的控制实际上打开了性别与居住地的后门路径而造成了错误估计:

\(A \rightarrow X\rightarrow B, C \rightarrow X, C \rightarrow B\)

这里C代表居住地,此时我们控制 X 会导致:

\(A \rightarrow (X) \leftarrow C \rightarrow B\)

这条 A 与 B 间的因果路径打通,结果就是 A 对 B 的估计中还是存在混杂。这里我们也能看到悖论的魅力,如果条件发生改变,解决悖论的方法也要随之改变而不是简单控制就能搞定的。有时候完全不控制可能就是最好解决方案而过多的控制会让结论无法被理解,这点对机器学习里 \(y = f(x)\) 的简单逻辑框架来说是灾难性的,更多的特征值不见得拟合效果更好,反而让你说不清楚结果与变量的关系。当然,现在主流似乎也不打算说清楚。

既然说到辛普森悖论,就顺道聊下这个悖论的变体。最古老的变体是田忌赛马,为了保证整体上取胜,我们可以在部分作战采取放弃策略,这个在军事学发展中阵地战战术中比较常用,说白了就是在战力不占优的条件下通过兵力在防线上的调配来取得一定效果。这种作战方式个太古典了,现代战争的变体是海陆空高科技兵种配合作战,早就脱离了电视剧里对着砍的策略(但对着砍有戏剧性与视觉冲击力),当前作战形式基本都是地面小队配合空中扫荡与坦克掩护,你要是敢把几千人排到一个开阔阵地上等对砍搞决斗,就等着无人机包饺子吧。这很可能是互相博弈的一个结果,因为双方将领如果都明白辛普森悖论原理,那么肯定会最大化自己的优势去打对方的弱势。而现代战争是科技战,人数啥也说明不了而更多是劣势,所以不超过10人的小队突击在对战中灵活性最高且容易发挥科技领先优势。现代公司发展中,很多大公司采用传统上的多级体制其实就是在搞阵地战,技术上如果信息流通顺畅,小组制应该是整体取胜策略,我们已经看到很多互联网爆款产品最初其实都是来自小组而不是靠人数,当然后期巩固成果是完全另一类可持续策略了。在政治学里也存在辛普森悖论:杰利蝾螈。这个概念指的是通过划分选区来操纵选举结果的一种策略,通过把铁票仓分到对方的边缘选区可以在代议制选区民主里赢得多数票,民主的一人一票不代表整体不能被操纵,这对大杂居小聚居的西方移民国家尤其重要,如果争夺中间派不切实际,那就把极端分子渗透到中间派选区搞事情。

杰利蝾螈示意图(两个党派的30人分为3个10人组投票,按分组结果得两票以上获胜。如果分组按照党派在人群中的比例(中间图)则蓝党会在三个分组里都获胜,但如果控制分组(右边图)则可让红党派在两个分组里获胜,从而整体上获胜)

图 4.2: 杰利蝾螈示意图(两个党派的30人分为3个10人组投票,按分组结果得两票以上获胜。如果分组按照党派在人群中的比例(中间图)则蓝党会在三个分组里都获胜,但如果控制分组(右边图)则可让红党派在两个分组里获胜,从而整体上获胜)

前面说的都是辛普森悖论的分类变量比例版,很自然,这个悖论也存在线性模型版。也就是说,一组数据做回归,变量系数是正的,但是我们把数据切成两部分,其同一变量的系数就会变成负的。这个线性版的成因除了跟前面比例版一样外还存在另一个成因,那就是噪声。当参与回归的变量只能解释数据变异中一小部分时,其回归估计参数的不确定性会被未知变异所主导,如果分割数据的方法与未知变异混杂,那么变量的方向就会不稳定。这里还是要强调下参数估计一定要包含不确定性,如果不确定性高不代表结果不靠谱而更可能是数据结构还没搞清楚或数据量不够。其实这种信噪比不够的问题与前一章所述的可重复性危机有关,也许我们花大力气估计清楚了一个微弱变量的效益,这是否值得?学术上当然值但现实意义就不好说了。

除了我上面提到的,经济生活中也有辛普森悖论,例如股票指数走高里不代表每个板块都高,这就联系到风险控制与对冲了。辛普森悖论告诉我们存在整体收益而部分损失的可能与部分都受益但整体依旧损失,整体与部分数学上其实没关系,数据上就要看背景了,最好用因果分析来探索下究竟是什么导致的差异及加权后整体究竟怎样,当然,如何加权,用什么加权,逻辑通不通其实有时是艺术而不是科学:你把因果箭头反着来能说通也会产生一个估计,自圆其说不解决科学求真的问题。

前面我一直在说加权,感觉好像搞清楚因果关系后剩下的就是加权平均的计算,其实实际也是这样。因果分析还有种做法就是通过计算个体因果效应后计算整体平均因果效应(ACE)来做的,这个平均过程也可看出某种加权,就是做了跟不做后的净效应。不过这仅仅是计算层面,不包含因果假设。

\[ACE = E[Y{i,1}] −E[Y{i,0}]\]

因果图另一个应用是工具变量。当然工具变量在计量经济与公共卫生领域里有不同的表述,但本质上就是如果我观察 \(A \rightarrow B\) 时存在 C 同时影响 A 与 B,那我们就找一个不受 C 的变量 X,这个变量直接作用于 A,此时我们计算 A 与 X 的相关性与 B 与 X 的相关性,根据下面的因果图:

\(X \rightarrow A \rightarrow B, C \rightarrow A, C \rightarrow B\)

X 与 B 之间没有直接因果,在效应计算中,X 与 B 的相关只会来自于 A 的中介,也就是 A 与 X 的相关性与 A 与 B 的相关性乘积,如果我们打算估计 A 与 B 因果效应,就是用 B 与 X 的回归系数去除 A 与 X 的回归系数。这个过程中因为 C 跟 X 间没有因果通路,所以相当于跳过了混杂因素的讨论。这个路径影响等于回归系数乘积的代数技巧使得计算上非常清晰,但还是牢记工具变量的选择不是探索的而是因果的,需要背景知识。有了工具变量,研究人员就从无穷的相关与混杂中解放出来而可以通过因果图构建来求解目标因果关系。当因果图很复杂时,你需要去控制一些变量或引入工具变量实现你关心变量的 do 分离,进而估计净效应。

因果图天然与贝叶斯分析有联系,且不论条件概率的转化,因果图跟贝叶斯网络就存在内生联系。构建因果图需要的背景知识可以类比成贝叶斯预设的网络层级,因此在求解上类似。复杂因果图实际也常常跟结构方程模型放在一起讨论,因为这两个解决的问题基本就是一回事,不过结构方程模型里并不存在控制而更多侧重参数求解,因果图除了可以玩控制变量 do 分离外,也可以接纳非线性关系。在有明确定义的结构因果模型(也就是复杂因果图)里,可解释性被放在了第一位,也就是说数据驱动的假设被模型驱动所取代,这放在机器学习领域里看起来像是开倒车了。不过因果图很难直观表示交互作用而更多用在线性模型里,所以看起来结构方程模型似乎是目前因果图用的最多的地方。

在统计学家 Juder Pearl 看来,当前的机器学习也好,人工智能也好,都卡在了因果分析的第一层,也就是关联这一层,到处都是相关且多数人似乎放弃了模型的解释性而一味追求预测与关联。他进而提出了因果关系的第二层(干预层)与第三层(反事实层)。其实这有点类似科学哲学的发展,第一层类似归纳分析与观察的实证主义,第二层则可以对应实验主义,第三层则是则类似证伪的思路,进而构想出一个不同于现实世界的客观知识的世界(波普的世界三)。不同于主流对模型可解释性的放弃,因果分析从一开始就构建在因果关系之中,解释起来相对容易(自然要因果图加持),不同数据间存在自己的数据逻辑结构,高层级的算法要能通过干预与反事实假设来发现结构,只有这样的算法才能实现强人工智能,因为人的思考就是因果的。 Juder Pearl 的哲学观里因果不是相关的特例而是反过来,相关里浸润着不同的因果,因果分析就是对这些东西的关系加以区分。

这个观点确实像是开倒车,用决定论反击概率论,但也可能是一次对当前科研的矫正。太多研究人员在大数据浪潮下放弃了可解释性而追求预测精度,且因为算力的加强,原来很多理论求解几乎全变成了数值求解。同时深度学习等神经网络的应用也让解释模型越来越变成一个笑话,不过如果我们真的不研究认识问题,那人类是否还能发现新理论与新机制?从来都没有单纯的数据驱动的研究,所有的数据驱动背后都有对问题的建模,当模型假设错了以后,数据再多也是缘木求鱼。不过是不是物理或化学模型就没问题了?也不是,理化生的知识大都是构建在还原论上的,理论会被设定在理想环境之下,这也对现实脱了节。自下而上与自上而下不存在哪个是真理的问题而仅仅就是个历史问题,因果分析可能是相互连接的一个工具。不过目前因果分析更多是应用在偏软科学与数据优先的学科里,理论优先的学科从一开始就是在讨论因果,但因为使用的是统计工具,所以内在的相关不能定因果的观念事实上是被学科自己的理论给压制了,但这也造成了对统计工具的滥用与误用。

长远看因果革命可能在两方面实现突破:一是统计学家对实际问题背景知识的接纳与考量而不是研究纯理论细节;另一方面是科学家对统计工具的重新理解,从因果图角度探索自己科学问题的解决方案。但无论如何,因果分析的思想都是很有前景的,因为这个工具是为思考服务的,现代人囿于工具人角色,缺的就是这一块。

4.3.5 残差

残差本质上科学就是通过解释剩余现象进步,而当今其实理论体系里留给重大发现的空间是有限的,所有人都在精进1%,不过都是在80%-90%的基础上的,也就是大家伙都在噪声里探索信号的模式。具体到统计模型就是对模型解释不了的部分与模型诊断的思想,有了这个思想统计学就有了不断发展的动力与自我审视的原则。从科学角度看,残差思想更重要的提示在于去思考实验设计或假设检验之外的东西,除了你关注的点也要留心那些被你控制随机化之后依然存在规律性的东西,否则科学就只有验证的功能而丧失了探索的可能。

4.4 模型思维

模型思维是一种一对多的思维方法,从相似的事实中提炼出逻辑规律,用规律来指导认知世界,这种思维的优势在于逻辑或者说理性起决策主导参考作用。当一个模型出错时,我们可以运用其他模型来研究某个事实,因为所有的模型都存在简化,所以知道模型越多越有利于理解世界里发生的事。模型都有自己的准确度与适用范围,一般而言,高准确度的模型适用范围比较精确且会形式化为公式,而低准确度模型类似万金油,无所不包但含义模糊。模型化思考是首先抽离出变量,然后确定变量间关系,最后运用逻辑推理来进行思考的过程,这对于科学探索非常重要。模型或规律的终点可能是循环的、平衡的、随机的与不确定的,要用学会概率角度而不是决定论去描述结果。

模型主要有两种,一种是基于公式的,另一种则是基于单元进行模块组合的仿真模型,前者需要你清楚的了解模型机理,后者则需要假定单元的活动空间与行为方式,然后通过模型运转来了解整体变化。下面首先讨论让模型思维可以落地的可编程思维,然后讨论个体常用的决策模型,之后是个体与整体关系及动力学模型,最后研究下常见的真实问题求解模型。这些模型思维对于科研是很重要的工具,这方面书可参考斯科特·佩奇的《模型思维》。

4.4.1 编程

编程是计算机科学的核心概念,当一件事可编程时,我们就可以设计出相对的硬件与软件来自动化这个过程,这个是模型思维在可执行角度的重要体现。对于科研人员,硬件方面一般较少涉及,软件编程却是日趋日常化。因此,我们有必要了解编程语言的一些基本概念与思想。

程序是编程的结果,一般包含一条或一组执行运算的指令,这里运算并不仅仅指数学运算,也包括所有可通过电子电路完成的运算。要实现一次运算,我们至少需要输入值、运算与输出值。运算至少要能实现数值运算、顺序执行、条件执行与循环。因此,如果你打算进行编程,你就需要通过计算机语言让计算机知道输入输出与运算过程。

计算机语言不同于日常交流的自然语言(虽然可以处理自然语言),其核心特质在于描述上的准确性。不论操作符、数据类型还是函数定义,不同的计算机语言都有自己的规范来确保人要求的抽象化与机器能听懂人的要求之间达到平衡。底层语言例如汇编语言机器非常容易懂,但人不容易将需求转化为汇编语言。高级语言需要编译成底层语言来执行,不过人相对容易将需求进行编程。这个编译过程会损失效率,所以一般学习的语言越容易,效率与准确性往往会受影响。

科研里一般用程序来处理数据,所以科研编程的语言选择往往是实现效率、处理方法与编程难度的平衡。一般来说,数据处理方法源于统计学知识,编程难度取决于学科现实问题的抽象模型而实现效率属于纯计算机科学问题,科研人员可根据自己知识背景进行选择。对于非计算机科学专业的科研人员,建议关注学科内主流编程语言,否则后期会有很多交流上的困难,或者一步到位实现程序的应用化,让用户在少量编程知识的背景下就可以应用。

学习编程语言一般首先要掌握变量类型、赋值、表达式语法、保留词、注释等基本概念,然后就是大量的交互式案例训练来熟悉用法。编程语言一般会自带 REPL (Read–Eval–Print Loop;读取-执行-打印循环) 程序,在这个程序下会识别该编程语言的语法与操作符,互动地输入输出数据与结果。在编写程序代码时,最基础的要求是搞清楚编程语言的优先级,例如括号>指数>乘除法>加减法,一般执行顺序是从左到右。

另一种使用编程语言的方式是通过独立程序实现特定功能来完成的,运行程序可以直接得到输出,人机互动是在应用层上的。 REPL 方式其实比较符合数据分析的需求,后一种方式则反映了软件工程,涉及了程序的设计、构架与封装。目前科研应用中侧重交互式数据分析而业界则更看重程序编写与功能实现,前者存在试错且探索为主,后者则更侧重目标。这个区别专业程序员或软件工程师经常体会不到,觉得用 REPL 的科研数据分析是初学者,不能算编程。但其实科研数据分析的核心就是计算与需求的互动,REPL 只是其中一种,将需求从 REPL 用户过渡成函数程序也是很重要。

也就是说,交互式与独立程序之间往往还有一个中间态,可以是脚本,也可以是自定义函数。一段代码一般是以输入为始,以输出为终,中间有函数来处理数据。在固定模式的数据处理中,一个函数的输出往往可以是另一个函数的输入,将输入输出代码按顺序、条件、循环排好就可以产生一个新的组合函数。事实上很多高级语言就在逻辑上抽象出一些常用函数来方便程序员直接调用。

同时,为了实现具体的功能,函数的输入除了数据外还有一些参数,有些是经验值,有些则可能要来自于功能本身定义。在输出上,有些函数的输出可以返回数值,有的可能就是打印到屏幕上就结束了,根据实际需求来。此外,多数语言的函数内部变量是只在内部可生产或可调用的,内部没有就可能从当前环境里找,最好不要设计这样的程序。函数或脚本对数据分析最大的意义在于减少重复工作与理清分析思路,对于软件工程则属于搭建工程部件,无论如何都是件功在当代利在千秋的事。

如果程序设计有问题,编程语言也会有对应 debug 的过程,大多数情况下是编程者的需求与机器的执行不对应导致,可以从这里入手思考修改代码。常见的错误包括但不限于语法错误、语义错误与例外。

下面重点讨论下编程思维中一些常见现象与术语,侧重理解并最好通过联系来强化理解。

  • 条件分支:函数中出现需要对数据子分类进行不同运算时的设计,不同子分类用不同条件语句进行逻辑判断,例如数值求绝对值要先判断正负。

  • 循环:同样的操作要对不同的可索引或满足特定条件的数据进行运算,这种情况要设计循环结构,例如按数据行/列求值。有些循环循环数是知道的,有些则要对数据运行结果进行判断,满足特定条件时可跳出或继续循环。

  • 递归:比较特殊的条件与循环结构,当数据不满足某条件时就执行函数本身直到满足条件,例如求解斐波那契数列之和就可以设计递归结构循环执行本身直到数据可计算的起点。递归的效率一般不高,但递归结构有助于简化思考问题的步骤。

  • 正则表达式:正则表达式是字符串处理时常用的模式识别工具,灵活使用正则表达式与条件分支可以有效处理真实数据中的混杂,强烈推荐学习掌握。

  • 数据结构:通常不同数据按照实际需求会有不同的格式,不同格式的数据处理方式会不一样,一般函数都会先验证数据结构,如果不能处理则返回错误。

  • 数据表:常见的数据处理格式,一般不同行表示不同样品,不同列表示不同样品属性且数据类型一致,数据值可以是数值、字符或逻辑值但不能是数据表。由于数据处理算法大都基于数据表开发,这类格式数据比较容易找到现成的算法函数/库/扩展包来进行处理。

  • 字典:很多程序语言支持字典,字典是一种对应关系,字典中的元素是键值-数值对,通过键值索引数值,也可以反查。数据表中搜索元素是按照数值索引顺序索引的,字典则可以用哈希表快速索引。字典可以在编程中用来构建基于输入的数据库,方便进一步查询。

  • 列表:列表属于数据表与字典的泛化,列表元素可以是数据表或列表,因此列表的数据结构不是平行的而是具备层级,有的元素可以进一步展开。列表常用来表示一组关联概念且可以数值索引,例如在回归分析的返回值中,就会包括拟合值、回归系数、残差等数据表或数值。

  • 类型:通常列表可被定义成一种新通用类型,算法可基于这个类型进行开发或泛化,例如当你调用画图程序时,其程序会首先判断你输入数据的类型,如果有对应方法则直接调用,没有则用通用方法或返回错误。有些语言中列表是不能直接操作的,这样设计就是为了防止类型不兼容而强制定义格式。

此外,应该了解一点C语言,因为C语言是多数操作系统的基础,所以多数操作系统也自带对应的C编译器。更重要的是,C语言的库很丰富,也就是工具函数比较多,换别的就得自己写。这是很有意思的路径依赖案例,事实上任何语言都应该可以拿来写操作系统,不过C是在开发Unix时候设计出来的,现在流行的开发级操作系统都是unix/类unix操作系统,加上C在内存管理与CPU交互上的先天优势,历史机遇下成为了主流。C语言源码编译运行过程是这样的:先预处理源码,调入模块,然后转换成汇编语言文件,汇编语言文件可以被汇编器转为机器码,然后通过连接器合并为可执行文件,最后加载到内存里运行。

C的核心地位还体现在很多高级语言的编译器是构建在C之上的,或者是C++之上,多数高级语言都通过限制自由度(例如不让操作内存、功能模块化等)来实现上手容易与较高的开发效率,但只要关注程序性能,肯定回去学C或C++的。GNU的GCC编译器是一个相对通用的编译器合集,可以用来编译包括C在内的多种语言。然而,GCC也是有历史包袱的,所有有人就另起炉灶单独针对C或C++重写了效率更高的编译器及其后台,这就是苹果的LLVM项目与clang编译器。但要注意的是LLVM支持的语言不如GCC多,所以如果你还要用到fortain或java编译器,那就还是老老实实用GCC吧,或者cmake的时候分别指定编译器,只要你不嫌麻烦。一般而言,效率与性能往往不能兼得。

高级语言的编译过程跟相对底层的C或C++是不一样的,Java就是自己定义了一套运行环境JVM,编译出的文件也是JVM可读的,这就提高了Java的可移植性,降低了跨平台开发的难度,当然你得保证这些平台上可以运行JVM。其实很多高级语言是解释型的,REPL里可直接运行代码,但同样会有人为高级语言写编译器来提高运行性能,这个是按需求来。我个人感觉是用REPL的人一般是应用层的,关心有没有满足自己需求的函数;用编译语言的人一般是开发层的,关心软件工程及性能。然而,高级语言里如果打算提高运行效率,也会提供C或C++的接口让程序员可以通过外力来提高自由度。过度的功能封装实际也限制了高级语言的应用场景。

说到效率,自然少不了并行计算,openmp 就是一种并行化方案,可以支撑C与C++。很多R包会通过使用 openmp 来底层加速算法,但这样的包一般都需要单独编译。目前GCC与Clang在编译器层其实都实现了对 openmp 的支持,编译时加上 -fopenmp 就可以。

其他一些概念例如云计算、单元测试、集成测试、GPU加速、功能模块化、环境容器化、接口调用、功能移植、数据库检索、前端设计、数据加密、移动端兼容等都很有了解的必要,但这是建立在牢靠的基础上的。一个简单的判断标准就是根据你的需求你会觉得存在某种设计,然后一搜索发现果然有这样的领域,从需求出发回到需求中去是编程思维的要诀,不要在屠龙之术上花费太多时间。

4.4.2 决策模型

个体行为都是有自己决策过程的,决策模型分为多准则决策与概率决策,前者可以定性分析,也可以打分定量分析,可以使用空间量表可视化多维选择。概率决策是构建在事件及其后续事件发生可能性基础上的,赋值后根据决策树反推不同选择下的期望结果。基于概率决策树可以对信息定价,推算在有无信息下的期望差就是信息的价值。

人的思维过程跟物理世界运行规则是不一样的,有的人喜欢严格按规则办事的,有的人则看心情办事,还有理性行动者。按规则办事的人可以靠规则来预测,例如博弈论里的分析与随机选择,决策越简单越容易执行。看心情决策的跟随机过程差不多,永远不要尝试预测一个随机事件。理性行动者会不断按目标函数寻优,经济学里的理性人假设就是如此,但存在边际效用递减的情况,也就是前期改善大后期改善不明显的情况。理性不意味自私,跟个人目标或价值认同符合的决策有时需要考虑群体最优。真实世界的人三种思维模式都存在,不同场合不同组合。很多时候基于规则的经验可能是最符合现状的,既不会绝对理性,也不会过于随意,大概取个中间值,为不确定性留空间。

规则模型里比较常见的是分类模型与线性模型。分类模型就是把相似的东西归到一类里去,分类越能捕捉群体里的差异,模型就会越符合现实,其实就是组内方差最小化与组间方差最大化的体现。线性模型则是通过构建拟合两个变量的线性关系来进行预测,线性模型中,R方可以用来描述模型解释度,系数正负可以告诉你效应方向,系数的量级可以表现系数的重要程度,系数的p值可以告诉你出错的概率。现实数据可以拆分成不同线性阶段,这样非线性就可以线性考察。重要系数的筛选属于循证研究,首先构建模型,然后收集数据,然后确定重要变量,然后改变变量来看影响,进而找出影响大的变量。线性模型也存在局限,例如不能识别因果,对于反馈作用无法预测,例如早先设计ABS系统是因为车距过近容易出事故,但有了ABS后实际车距反而缩小了,因为人们把ABS的影响反馈到行为里去了。

除了线性模型外,非线性模型可以看成线性模型的组合,这样就会存在临界点,不过要区分指数模型与临界点模型,他们内在动因不同,临界点前后量化属性会发生变化。在传染病模型中,临界点就是基本传染数。临界点可以通过多样性指数或熵来测量:多样性指数就是不同类型概率平方和的倒数,越高多样性越高;熵则是概率与概率对数的乘积和的负数(信息可加和并考虑概率),越高越混乱,需要信息越多。

4.4.3 个体-整体模型

当人聚到一起后,整体就会有自己的属性,系统的表现取决于环境、个体间关系与系统组织结构,与个体属性关系就不大了。单一行为的聚合模型可以考虑中心极限定理;单一规则的聚合模型可以参考细胞自动机的研究,此时已经有系统高层次动态了;个体的偏好聚合后就会出现系统高层次矛盾,例如博弈论、投票、群体非理性等。

在整体个体决策价值判断分为两种,一种是无个体最优的价值属性,例如颜色偏好,一种是越多越好或越少越好的个体与群体取向一致的属性,例如幸福度、效率质量。前者相关模型多用于政治学,例如中间选民理论里持温和派观点的候选人往往能得到多数票,但这只在单一维度上成立,也就是为了意识形态而放弃理性时会成立,当多维度出现时,中间选民需满足径向对称(radial symmetry)才胜出,否则就是无胜出结果(Plott’s no-winner result),任何可能都会出现。现实世界中,单一维度模型往往能解释大多数情况,但政客也经常通过反复无常来应对民意的波动。在单一维度模型时,提议者要尽量争取中间派,而中间派关注自己立场与现状与新政的距离,只有新政距离中间派距离小于现状与中间派距离才能争取到。同理,现状越极端,新政越有可能通过,这是现状与中间派权力间的博弈。多层级政府里法案的通过需要多方认可,这种有利于权力制衡,但阻碍效率(Voronoi 图可用来可视化选择域)。个体与群体取向一致的属性上,可采用上述决策模型,但现实世界中通常混杂个人偏好与群体取向。在一个市场里,如果竞争充分,客户价格敏感度往往比较高,如果竞争不充分,调价空间就很大,非实用品质因素例如品牌等个人偏好的因素往往主导目标人群的决策。就具体商品而言,个体选择(无最优)、社会功用(最优)与资源稀缺性(现状)都是定价要考虑的,单独考虑一个会产生系统偏见。

社会有时为了整体利益会奖励个体的行为,荣誉、品牌、学历等社会信号就是这类机制。这些信号可能对个体生存没有意义,但可以塑造社会地位。无私的捐赠、浪费式消费与精美的手工艺品都属于这类信号,奢侈品的营销策略就如此,通过营造氛围让普通商品玩不起这个游戏,也就是有钱不如有闲。我们可以利用社会信号这一非生存需求设计规则来募捐或促进社会公益事业发展,各取所需而不是简单嘲讽或批判。个体的进步可以来自自我认同,也可以来自社会认同,一个纯自我认同的个体很可能对社会公益毫无兴趣,此时要设计机制让其了解社会认同的优点,内部激励靠钱带来的个人欲望,外部激励靠名带来的模仿效应。

个体行为在群体中有两种形态,一种是同群效应,也就是被群体同化,细分也有两种,一种是直接服从整体,另一种是在周围环境压力达到自己设定时被同化,例如起立鼓掌模型;另一种则是物以类聚,也就是只跟自己相似的人聚集,如果被群体排斥就离开,例如谢林模型,这里微观的动机不同于宏观的表现。这两种状态宏观上都会造成隔离,但形成原因差异很大,一个是入乡随俗,另一个是回归舒适区。存在引导群体行为的策略,入乡随俗的可以加强引导而回归舒适区的可以强调区别,传销的人两种方法是交替使用的。在一个群体中,个人阈值的分布很重要,如果阈值多样性大且是正反馈的,那就容易出现爆炸或崩溃,然而,当是负反馈时,个体多样性阈值会让系统趋于平衡或循环,两者都有就会是复杂的。谢林的《微观动机与宏观行为》值得作为这个问题的参考。

# 谢林隔离模型,代码源于 https://simulatingcomplexity.wordpress.com/2016/01/06/building-a-schelling-segregation-model-in-r/
# 生成单元格矩阵,两种颜色随机分布
number<-2000
group<-c(rep(0,(51*51)-number),rep(1,number/2),rep(2,number/2))
grid<-matrix(sample(group,2601,replace=F), ncol=51)
# 找邻居函数
get_neighbors<-function(coords) {
        n<-c()
        for (i in c(1:8)) {
                
                if (i == 1) {
                        x<-coords[1] + 1
                        y<-coords[2]
                }
                
                if (i == 2) {
                        x<-coords[1] + 1
                        y<-coords[2] + 1
                }
                
                if (i == 3) {
                        x<-coords[1]
                        y<-coords[2] + 1
                }
                
                if (i == 4) {
                        x<-coords[1] - 1
                        y<-coords[2] + 1
                }
                
                if (i == 5) {
                        x<-coords[1] - 1
                        y<-coords[2]
                }
                
                if (i == 6) {
                        x<-coords[1] - 1
                        y<-coords[2] - 1
                }
                
                if (i == 7) {
                        x<-coords[1]
                        y<-coords[2] - 1
                }
                
                if (i == 8) {
                        x<-coords[1] + 1
                        y<-coords[2] - 1
                }
                
                if (x < 1) {
                        x<-51
                }
                if (x > 51) {
                        x<-1
                }
                if (y < 1) {
                        y<-51
                }
                if (y > 51) {
                        y<-1
                }
                n<-rbind(n,c(x,y))
        }
        n
}
par(mfrow=c(1,2))
image(grid,col=c("black","blue","yellow"),axes=F)
# 设定喜好度,此处设定为50%,也就是单元格里人周围少于四个单元格的人与自己颜色相同时,这个人就会随机搬家到另一个单元格
alike_preference<-0.5
# 模拟搬家十次
for (t in c(1:10)){
        happy_cells<-c()
        unhappy_cells<-c()
        for (j in c(1:51)) {
                for (k in c(1:51)) {
                        current<-c(j,k)
                        value<-grid[j,k] 
                        if (value > 0) {
                                like_neighbors<-0
                                all_neighbors<-0
                                neighbors<-get_neighbors(current)
                                for (i in c(1:nrow(neighbors))){
                                        x<-neighbors[i,1]
                                        y<-neighbors[i,2]
                                        if (grid[x,y] > 0) {
                                                all_neighbors<-all_neighbors + 1
                                        }
                                        if (grid[x,y] == value) {
                                                like_neighbors<-like_neighbors + 1
                                        }
                                }
                                if (is.nan(like_neighbors / all_neighbors)==FALSE) {
                                        if ((like_neighbors / all_neighbors) < alike_preference) {
                                                unhappy_cells<-rbind(unhappy_cells,c(current[1],current[2]))
                                        }
                                        else {
                                                happy_cells<-rbind(happy_cells,c(current[1],current[2]))
                                        }
                                }
                                
                                else {
                                        happy_cells<-rbind(happy_cells,c(current[1],current[2]))
                                }
                        }
                }
        } 
        rand<-sample(nrow(unhappy_cells))
        for (i in rand) {
                mover<-unhappy_cells[i,]
                mover_val<-grid[mover[1],mover[2]]
                move_to<-c(sample(1:51,1),sample(1:51,1))
                move_to_val<-grid[move_to[1],move_to[2]]
                while (move_to_val > 0 ){
                        move_to<-c(sample(1:51,1),sample(1:51,1))
                        move_to_val<-grid[move_to[1],move_to[2]]
                }
                grid[mover[1],mover[2]]<-0
                grid[move_to[1],move_to[2]]<-mover_val
        }
}
# 观察此时的单元格颜色分布状况
image(grid,col=c("black","blue","yellow"),axes=F)
谢林隔离模型模拟

图 4.3: 谢林隔离模型模拟

个人群体的另一个重要模型是关于外部性或公共物品的,公共物品非排他也非竞争,其总效用函数是递减的,也就是后来的人可以享受公共物品但不用贡献,这会导致公共物品在人口增加后会紧缺但个人贡献意愿却因为后来者低贡献而降低。如果没有利他主义的人存在,公共物品或外部危机就会让群体不能持续维持正常运转。最常见的外部性解决方案就是税收或法律,如果不同群体间存在不同的税率会出现隔离与割裂,例如阶级固化后富人区内部大方而对外割裂,穷人区因为没有公共物品其法制也无法贯彻。单纯提供外部性并不一定会提高整体收益,存在反馈,更多的路引入了更多的车,阻塞问题可能依旧,系统分析是很有必要的,找出本质问题而不是解决表面问题。最麻烦的外部性问题是资源类问题,当资源开采速率超过一定速率后,平衡将不可逆走向崩溃,复活节岛就是一个例子,这类问题需要优先预防监控,不能等事情发生。当然,预防的悖论在于你做的越好,实际地位就越不重要。

群体间可通过机制设计来维持稳定,没有法律,社会会乱,下棋没有规则,游戏没有乐趣。机制要平衡个人多样性需求来实现整体最优,其中自愿、自发、低成本运行的机制(芒特-赖特尔图)是理想的,有些问题需要复杂规则设计来实现目的。例如在石头剪子布中,纳什均衡并不会有唯一解,有时纳什均衡不是整体最优。多数人投票中也存在这个问题,会出现投票中的独裁者,但拥王者机制则可实现整体最优,随机选一个人作为“拥王者”,这个人指定一个王来给出最终选择。又比如广告位拍卖,理性价位是价高者得的次高价,所以规矩就是如实报价然后按第二高价格卖给出价第一高的人。但事实上,不同拍卖规则下如果参与者都是理性的,最后实际价位应该是一样的,不过结果一致但听上去感受可能会不同,机制设计者要充分权衡。

文化差异也存在模型,文化是使群体生活与个人生活能进行的事物,国家文化差异客观存在,个体通过与他人协调与自己行为磨合形成,文化交汇会促进相似但不是一致。一致性会形成路径依赖与偏好加强,最后形成临界点。事物的发生靠技能也靠随机性,技能接近看的是运气。

关于个体与个体,个体与整体,整体与整体间行为的模型构建,博弈论给出了系统答案与解决策略。投票、选举、拍卖、联盟、反悔等一系列问题都是博弈论议题,说白了就是讲两方势力在一件事上为了自己的最大利益所采取的行动或决策的理论,是重要的模型思维工具。

4.4.4 动力学模型

前面的决策模型大都是静态决策,真实世界要考虑发展的过程,也就是动力学模型。事情的发展可以用马尔可夫模型来模拟,当状态有限且发生概率恒定时,事情就会进行状态改变直到收敛。概率转移矩阵就可以计算最终平衡时比例,因为是动态平衡,经常反线性直觉。这个过程跟初始状态无关,跟过程也无关,通过随机性达到平衡,但如果转移矩阵改变了,就可能不收敛了。

另一个事物发展模型是李雅普诺夫函数,它存在一个最大值或最小值,在没达到时会不断逼近,平衡时会停止波动,可根据构建的模型来估计逼近所需要的周期并优化。行为没有外部性会最终平衡,考虑外部性会复杂或随机,这个模型依赖路径与初始条件来达成平衡,平衡点固定不随机。例如美国所有州政府都倾向于削减社会项目支出的行为,因为会吸引外州穷人。

系统的发展会存在反馈与路径依赖,例如正反馈加强的波利亚过程,出现任何情况的概率是相同的,出现看似极端的情况并不意外。而均衡过程则不会产生路径依赖,是一种制衡。 路径依赖不同于临界点,熵的减少是均匀的而不是突然的。在系统中,有充足时间尝试的自组织会达到均衡。在构建系统动力学模型时,要考虑源头与汇,还有存量、流量、速率与常数。

4.5 启发法

启发法的较正式的解释是非最优非理性快速解决问题或作决策的方法,包括试错、经验法还有拟设(类似假设检验),类似直觉经验判断的混合体。一般包括两步,随机寻找与爬坡,随机寻找进行尝试,根据结果向着期望方向寻找直到达成目标或时间用尽。此时,使用者知道如何检测结果但不知道如何生成出现结果的机制。与启发式相对的是解析式问题(例如梯度优化),此时我们知道问题原因,可以根据原因来求解,例如有函数我们可以求导来算极值,而启发式则是只知道要求极值但函数未知,常用来解决黑箱难题。

启发法里也存在一组制衡:探索(exploration)与利用(exploitation)权衡。探索侧重复杂空间例如完全随机搜索,利用强调快速求解例如爬坡。启发法中一个关键步骤就是探索完一次得到继续探索信号后如何生成新参数,微小的参数改变有利于寻找方向而较大的改变有利于摆脱局部最优。也就是说在资源有限条件下,想更多探索解决方案空间就没法获取很高的求解精度,反之,在局部解决方法上反复优化就没法探索更大的解决方法空间。

不过,启发法本身的设计却可以很艺术的去探索两者的平衡。模拟退火算法的核心思想是在随机寻优结果是负面的时候也会以一定概率接纳,负面越高越不接纳,也就是尽可能引入改变来防止局部最优。禁忌搜索(tabu search)算法会预先设定一个列表,最优的结果都存到里面,存入后就不再考虑对应的参数修改方式,这个过程反复进行填满列表后最早的就可以踢出去重新考虑了。这也是防止局部最优的策略。迭代式局部搜索则从时间上做文章,先进行一段时间爬坡找到局部最优,然后进行较大的随机行走,在新位置上爬坡找最优,跟之前对比留下好的,然后继续迭代。

上面这些策略都可以用,也可以组合使用。除了这类单一状态优化外,另一类启发法则是从种群角度进行计算的,同时进行多组扰动,根据结果探索变化方向。这个思路来自生物学里的进化算法,包括遗传算法与进化策略。基本思路是设置初始种群,计算适应度,然后选一部分个体进行一代遗传,遗传过程伴随突变,之后重新计算适应度,最后留下适应度高的继续遗传。

种群初始化时要尽量多保持多样性,可以用哈希表来存储独立个体。在进化策略上,计算完个体适应度后只保留部分高适应度个体进行遗传,下一代数目与初始种群一致,例如每代10个个体,但只选2个最高适应度的遗传突变,下一代数量还是10个。当然,也可以在下一代里把第一代也都考虑进去进行筛选,如果一代不如一代,至少还保留了上一代的优良基因。突变率依赖正态分布的方差,经验法则就是如果多于五分之一子代表现更好,需要增加方差防止局部最优,如果少于则减少方差,等于则不变。

在遗传算法中,子代生成是有父母贡献一半进行杂交然后加上突变的,这里面多一个随机翻硬币来决定子代那一部分交换的步骤,此时遗传部分的可能性空间是确定的,另外杂交过程也可以对连续变量进行线性插值。在进行适应度选择上,可以根据概率去选,也可以用非参方法排序来进行选择。

在启发法特别是基于种群的启发法中,并行计算特别重要,你可以并行多组启发算法,或者在同一台机器多线程计算适应度,或者用分布式计算来分散汇总结果。如果需要多目标优化,就设计一个由多目标加权组合的新适应度指标。启发法也可以用在组合优化问题例如背包问题或邮差送信问题。此时可以先构建出一个组合,然后在有限时间内进行组分调整计算适应度,最后留下好的。蚁群优化则是先构建一组备选方案,然后计算适应度,记录各个组分的表现(信息素),重复这个过程,然后根据各组分信息素多少来选择最终组合。这个过程信息素可以挥发,备选方案也可以进行一定的爬坡,也可以用禁忌搜索来禁用掉一部分组分。同时随机数生成对于启发法也很重要。

多臂老虎机就是实际问题求解一个常见场景,多个备选方案与有限尝试次数是实际问题中常遇到的情况。我们可以利用贝叶斯方法先给每种方案一个先验收益,然后每尝试一次,更新一次期望收益,根据新的期望收益决定下一步尝试的方案,不断迭代。多臂老虎机可用来求解最佳方案,但算法实现需要足够尝试,否则新方案永远不会有出头之日。

了解启发法的相关算法对科研是有帮助的,因为科学问题的求解通常面临资源有限的情景,此时预实验或探索性数据分析就要借鉴启发式算法的思想,不仅仅优化自己熟悉成熟的解决策略,还有留足够的随机行走空间。时至今日,很多科学问题可以通过仿真手段来验证与求解,怎么设计一个探索性仿真策略也需要对启发式算法有一定的理解。

但最重要的是,启发法其实与认知偏误有时是伴生的,很多直觉性尝试都埋伏了认知偏误而容易导致陷入局部最优而不自知,而完全随机尝试的启发法其实是反直觉的。如果所有人都在用一套解题策略来攻克一个科学问题,那么尝试下从所有思路里随机选择可能会发现更好的解题策略,也就是要试错。不知道从什么时候开始,流行文化里对正确与成功的故事给予了很高的认可,很多人不能也不敢犯错,按部就班走流程排列组合在科研论文中形成了新八股的趋势。我们只能看到漂亮且显著的结果而不知道论文背后的试错过程,很多研究事实上脱离实际且不易重复,这种趋势会把科研人员的思路锁在那些四平八稳不犯错的研究而不是真正解决问题。须知,没了启发的研究就像是吃饺子不蘸醋/酱油/辣酱,入喉尚可但并不美味。