本文是我在清华大数据产业联合会上的讲座内容,整理成文字,跟大家交流。
整个内容分五个部分:(1)数据处理与代数;(2)关联运算及描述;(3)序运算与离散化;(4)层次数据与交互;(5)云数据组织
本文介绍基本概念和背景;中间三部分都是数据分析的内容,是重点;最后一块研究得还不够深,但也涉及到关系代数,就放进来一起谈谈。
先从编程序谈起。
编程到现在仍然不是一件轻松的活。这里我们不去谈那些由于需求不清或变动而导致的困难,那是软件工程的目标。有一些问题,完全没有歧义,你明确知道解法,使用你最熟悉的程序设计语言,但这个程序仍然不好写。
比如计算一支股票连续上涨了多少天,计算利率变动时房贷还剩余多少本金。想完成这样的运算,都还是要写很多代码才可以。
最近股市不错,今天有不少例子是和股票相关的。
本质上讲,编写程序的过程就是把解决问题的思路翻译成计算机可识别的精确的形式语言的过程。举例来说,就象小学生解应用题,想清楚每分钟进水多少出水多少,鸡多少兔多少等,最后列出四则运算的表达式,也就是精确的形式语言,就可以解决问题。用计算机解决问题的过程是类似的,拿到一个问题,想出解法,然后还要把解法翻译成计算机能理解能执行的动作才能完成。
那么代码为什么难写呢?
其中很大一部分原因是用来记录解法的形式语言和人的自然思维相差很远,它不能直接描述我们的思路。你必须按形式语言规定的思路来完成,这样经常会导致你告诉计算机该怎么做比做本身还要难。也就是说,翻译问题解法到形式语言的过程,这个难度经常远远超过解决问题本身。经常需要受过专业训练的人员,也就是程序员才会做,而我们的精力应当更多地放在解决问题而不是翻译解法上。
进一步,这里面主要的原因,我认为是形式语言采用的代数体系不好。
什么是代数体系呢,通俗一点说,就是定义了一些数据类型,并在这些数据类型上规定一些运算,并且保证这个运算是封闭的,也就是不能算出新类型的数据,逻辑要自洽,也就是不能算出矛盾来。
这里的数据类型有些象面向对象的类,但又不同。面向对象更强调的是类的继承和重载能力,而这里更强调的是运算。
广义地说,我们做数据处理都是在相应的代数体系下做运算。就像我们平时基于数做四则运算。如果我们在这些数上定义的运算不方便,就会造成很多麻烦,比如,如果只有加减法,没有乘法,人们上街买菜都会成问题了。
形式语言中采用的代数体系将非常严重地影响数据处理的效率和能力。我们举两例不够好的代数:罗马数字和汇编语言。用罗马数字做通用的加减法都很困难,只适合做加1减1这类过于简单的运算。
mov ax,3
mov bx,5
mul bx,7
add ax,bx
这是用汇编语言写出来3+5*7这样的运算,你必须把这样一个算式翻译成寄存器的运算,因为汇编语言只有类似字节这样的数据类型及运算。这显然非常麻烦,如果是浮点数运算则完全不知道该怎么办了。而使用高级语言就方便得多,因为高级语言中直接有了整数、实数这些数据类型及四则运算。从这个意义上讲,FORTRAN是个伟大的发明。
我们用计算机分析数据的目的是找出事物之间的关联,而事物是由其属性决定的,这在技术上表现为结构化数据。数据分析处理的需求绝大多数都是已经或即将被结构化的数据。
非结构化的数据,在存储上可能是大头,但关联运算并不是很多。有一些很专业算法,比如说图象识别,很难把它归到数据分析的类别中。其他日志、地理信息等的分析都是要做结构化之后才能做。
大数据来了,很多人都说结构化数据的时代已经过去了,我不这么认为,结构化数据仍然是数据分析处理的重点。
提到结构化的数据就要说关系代数了,关系代数是专门为结构化数据发明的一种代数体系,是现代关系数据库的理论基础。关系数据库是应用最广的一种数据库。虽然近年来,尤其大数据概念出来后,关系数据库有各种各样的问题,但仍然很强势。
结构化数据是计算机广泛应用之后才大量出现的数据类型,传统数学中很少涉及这种数据类型,关系代数是少有的几项专门为计算机科学发明的数学。计算机应用中有大量的数学,但大多数都是几十年甚至几百年前被数学家发明的。现在热门的数据挖掘,用到的概率论、图论、线性代数基本上都是这种,没有计算机学术界什么事。
关系代数是在结构化数据的集合上定义的一些运算,集合交并差,以及过滤、分组、连接等运算。关系代数中对关系的定义比较抽象,属性构成的集合称为关系,然后再研究关系的集合上的运算,这个不好懂。我们这里就用通俗地说法,简单地理解成有属性的对象集合,或者用程序员常说的术语,有字段的记录集合。
提到关系代数就要说SQL,SQL是关系代数的形式语言。我们说,这个形式语言没有达到它的设计初衷。
SQL的设计初衷是什么呢?它希望让普通的业务人员、不需要太懂技术的人员也能用起来。为什么这么说,因为它长得像英语,在它之前的程序设计语言都是形式化较强的,其中的单词只是符号。而SQL很象英语,甚至有些句子可以作为英语来读,希望懂英语的人就可以使用。但是,这个目的没有达到,稍微复杂一点的查询用SQL都很难写,需要很专业的人才能做出来的。数据库中大量存在着并非由于性能因素导致的难以计算出来的信息。
稍扯远一点,许多SQL教科书都会声称,用SQL写代码,你只要说明要做什么,而不用关心怎么做,说的很高大上,但其实都是胡扯。前两天我看SAS的书也这么说,不过这些胡扯倒不影响这些产品的伟大性。
事实上,任何一种程序设计语言都在某个层面满足这个说法,用汇编语言你也不用关心电子流是怎么流转的,而用SQL你仍然要关心表中的数据是如何组织的。
SQL的不足,我总结是这样几条:
分步这个比较容易理解,一个问题一步做出来总比分几步做出来要难,SQL不是不支持分步,是不提倡。
其它问题会在下面的讨论中涉及。
从这个意义上讲,关系代数还有很大的发展空间。它到现在也就四十年时间,与传统数学领域相比还很年轻,远远不像业界所说的那样,已经把结构化数据搞完了,其实差得很远。一个类比,现在的关系代数有点像三百年前搞微积分一样,可以搞的东西很多,门槛也不高。三百年前的微积分,现在大学低年级的学生都能够理解,而当前数学前沿的东西,你不读二十年书,根本就没有办法和人对话。计算机科学理论还处于可以有很多事可做的阶段。