小公司和大公司有一个很大的区别,就是我是要为了生存的。不可能一个项目做上3年时间,然后结题,然后再评估。通常说,如果6个月没出成果的话,你这个公司就死掉了。所以从资金,从人员、从工程上来讲,都是非常紧迫的。过去这4年里我们一直在这样高压力的情况下,资源非常有限的情况下,怎么能够把活干出来。不考虑任何条条框框,只要能把活儿干出来就可以了。所以今天我讲的东西,我想有一个副标题叫“穷人的知识图谱”。就是说我没有那么多钱,怎么把这个东西做出来。
成本和质量的矛盾
大家提到知识图谱的时候,可能更多想到的是,它是RDF啊,或者是图数据库啊,Neo4j等等。再往上走,本体啊,逻辑啊,把这样一些东西称为知识图谱。实际上,我们在实际工作中用的时候不见得要这么教条。我们通常从原始数据开始,那种脏的数据,比如从网上扒来的数据,或者我们做股票知识图谱的时候,从股转中心抓来的数据、从证监会抓来的数据,这都是非常肮脏的数据,各种各样的噪声,里面可能还有扫描的,完全没有办法做自然语言处理。我们要把肮脏的数据清理成干净的数据。这一步做完可能百分之八十的工作就做完了,后面的东西都是锦上添花的东西。
我们拿到干净的数据,不是一步就跳到知识图谱上面去的。很多时候,我们的应用场景并不需要我们做这么深度的挖掘发现。在结构化数据和非结构化数据之间我们会做一个平衡,有的时候进来的数据都是非结构化的,我们要对它进行一定程度上的结构化。至于这个结构化要做到什么程度,是由应用决定的。结构化的结果可能是JSON的,也可能是excel表格,也可能是其他的格式。这种不太完美的结构化就可以说是知识图谱了。再往后,我们通过实体的提取、关系的提取、实体的对齐、实体的消歧、实体的链接,把它变成一个图谱。再往上是本体、逻辑,各种不同的阶段,一步一步往上走,实现数据质量的提升。
如果我们能够不计成本的话,我们可以把数据的质量一步步往上提升,提升到逻辑那个最高的程度。这也是70年代的时候,我们做知识工程的那种理想:所有的东西全都是逻辑的。其实在五六年之前,还有很多工程是这样做的。比如说在美国有一个高考(机器人做高考题)项目,韩老师(韩先培)今天也讲了中国搞的高考项目,美国那边有个类似的项目也是这样的。他们当时就完全是用逻辑的方法来做,完全用人工来写逻辑表达式。但那个项目最终因为成本的问题失败了。
所以我们在做这件事时,必须非常认真地考虑成本,这对工业界特别是初创公司最关键。因为这件事情特别重要,所以我要把这两个字放得大大的。如果今天回去以后,大家把我说的所有话都忘掉的话,也请记住这两个字。这两个字决定了项目成败最关键的一件事,就是你能不能活下来。
这是一些很不幸的前辈们,他们在没有办法控制成本的情况下,因为种种原因牺牲了。我们这里默哀一下。我们怎么能够避免他们的下场?上面的图最后这里有个点点点,可能现在大多数做知识图谱的公司在3年或5年之后也会到它们里面去。我们怎么能够让自己不进去呢?
降低成本的基本思路
这里我给一个“重”的知识图谱项目的示意。下面有七步,叫斯坦福七步法,这是一个以前叫本体开发的方法。是一种比较经典的、瀑布式的开发方法。当然了,传统的本体工程里面也会说,这个并不是瀑布,是迭代。但是这种方法首先强调,还是要有一个类,先有类然后再有属性,再有实体,然后有实体上的各种约束。还是要一步一步走。它的假设是,可以预先知道很多东西。但大多数情况下,我们根本不知道。我们甚至连用户的需求是什么都不知道:用户总是要一匹更快的马。所以你听他的肯定是错的。像这种方法,之所以在以前能够成功,因为它是政府的项目,通常几百万到几千万美元的,3年、5年、10年时间做完的项目,会有很多的大学啊,大公司啊,一起做。一开始光定下这个schema,可能需要一个工作组花一年时间来做。这样一种“重”的开发的方法,今天在web上面,在初创公司里面,这样是不行的,熬不过critical mass。我们要是这样做,就会死掉。
我们期望得到的是更轻一点的开发方法,能够使你付出一些成本就可以拿到一定的回报。这是理想,现实不一定做得到。我们能够降低成本的一个核心就是,我们能不拘泥于传统的这些方法往前走。从现在的创业领域我们借鉴一个概念,大家可能听过的一个词,叫Lean Startup,就是精益创业这个想法。在实践中,我们会发现,成功的公司基本上都遵循了这样一种方法往前走,一步一步地,从一开始不清楚应该怎么做,从一开始只有很少的资源做很少的事情, 然后慢慢资源越来越多,做更多的事情,所以我们希望有这样一条曲线,up-front cost,就是初始投资,尽可能小一点,然后就能拿到一些结果,这个结果能够对用户产生一定的价值,但不是所有的价值。然后能够让我们bootstrapping(步步为营,逐步提升),往前走,拿到更多的钱拿到更多的人,然后满足更高的要求。
但实际中的曲线可能是一个波浪的,甚至有可能某个阶段变成负的价值,都有可能。我们希望能够让各种失败尽可能快点,这样发现错误就能快一点。就是有这样一个loop(循环),Build-Measure- Learn,大家在其他地方可能也看到过。我们去构造一个系统,去发现,去做快速的验证,它是不是有可能是成功的。其中大部分实验都失败了,只有少数告诉我们一些道理。然后,我们反馈回去改变我们的系统。
我今天主要讲的,是在知识图谱这个大系统构造的过程中的几个子领域上,我们有没有可能去用这样的方法,依托于成熟技术,在成熟技术上面做一些迭代,帮助我们降低成本。这里我提到5个领域,其实也可以合并成4个领域,就是知识提取、知识存储、知识表示,后面两个信息检索和人机交互可以统称为知识检索。我觉得这4个领域在一起才能够构造好一个完整的知识图谱的应用。仅仅只看一个领域肯定是不行的。这也是我们早期犯的一个重大的错误,就是在我们2001年前后的时候,我们当时想做语义网,我们觉得知识表示就可以解决所有问题,但是我们想错了。现在到了2015年的时候,可能我们走到另外一个极端上去,不相信知识表示,我们非常相信知识提取,非常相信深度学习或者分布式表示,这可能也不见得对。一个完整的知识图谱的应用一定是多种方法的运用。从工业上来讲看,我希望能够把这些成熟的技术尽可能地组合好。这就跟SpaceX发射火箭一样,它每个组成技术(Component)其实不见得是非常先进的,很多都是NASA很多年前就做出来,但是它把这些技术组合得很好,创造出一个非常神奇的系统。把知识图谱技术拆开来看,也是一样,每一个组件都不是那么神奇,但怎么把它组合在一起,这是很神奇的。
另一点我想强调的是我们以前做知识工程的时候,进入了一个误区,就是我们觉得我们服务的对象是机器,更多想的是做更好的推理机让它更好地发现知识,或者做一个更好的索引让机器更好地做数据库的查询,或者做更好的知识提取。但实际上不是这样子。当你去真正去做一个项目的时候,发现最主要的成本是人,是你的用户、你的合伙人、你的投资人,然后更多是我们自己、员工。所以怎么能够让人能够更好地去阅读知识、产生知识,这才是我们应该学习的教训。不光是知识工程的教训也是软件工程的教训。
所以这里我引用了软件工程的两位大师,他们以前说的话:
傻子都能写出计算机可读懂的代码,优秀的程序员写出的是人能读懂的代码— Martin Fowler
程序是写给人读的,只是碰巧能被机器执行— Abelson and Sussman
其实知识图谱或者其他的知识表现方式也一样,它们并不是为机器准备的。它的维护成本更多是人的成本,要更多考虑对人友好来做这些事情。
我首先讲一下知识提取的成本,再对其他4个领域一一介绍。
知识提取的成本
关于知识提取方面,我讲这3个方面,就是人工和算法,统计和规则,还有知识提取的粒度。
提到人工和算法,这也是一句名言,我已经忘了是谁说的了。我最近在很多talk中都会提到,就是:有多少人工就有多少智能。基本上我们看见的那些让我们眼前一亮的东西,都是人做出来的,不是机器做出来的。各种各样的规则,各种各样的ontology,Siri那些让你笑的小笑话,都是人做出来的。算法真的很难去做高质量的结构。即使算法做出来,一定也要人工去进行验证、确认。算法能做什么?当原始的结构都已经很好,有高质量的时候,算法可能转移这个结构,从一种格式转移成另一种格式,从Wikipedia的Infobox变成DBPedia,这是算法能够做好的事情。但要把文本里面的关系提取出来,Open IE,这些东西从研究角度是非常有意义的,但是它们离实用还有相当远的距离。
第二个是统计和规则。在工业界,大家都不会说一个秘密就是正则表达式是最重要的一件事情。你现在要写文章,正则表达式是发不出去的。但正则表达式重要到什么程度呢?最近Micron公司已经开发了一个正则表达式的(硬件)处理器,就是真正工业界非常重视正则表达式一个很重要的标志。正则表达式只是其中一种啊,还有各种各样的规则,其实是非常关键的,林老师(林德康)刚刚也说了。
我们能够应用到统计的时候,我们要考虑很多前提。
样本有多大?样本量很小的话统计就不管用了。
我们有没有训练集?对于大公司而言,比如说做Distant Supervision,或者做那些分布式表示学习,它还需要一些准备的工作,人工的工作。对于初创公司或者小团队而言,未必能这样。
准确率要求有多高?搜索引擎正常情况下,它的正确率能够达到30%。但是我们觉得ok。对于问答引擎我们的要求有多高呢?对于不同的应用场景,比如说像这个小冰机器人陪聊的,错一点没什么,但如果是在医疗和法律领域就完全不一样了,你不能错。金融领域呢99%都不可以,正确率必须要有百分之百。在很多问题上面,这个时候要考虑到统计能不能做到百分之百?肯定做不到。
还有一个就是源数据的质量,决定了你最后能够拿到多少东西。源数据的质量如果很高的话,统计方法的效果就会很好。如果不行的话,就得花很多时间做data cleaning(数据清洗),这也是要成本的。
最后一点就是粒度。大家看到经典的教科书的知识图谱的定义的时候,会说是一堆实体,实体之间有关系,然后实体有属性。但实际上在工程应用当中未必一定要达到这样的粒度,因为要达到这种实体的粒度,是需要非常多的成本的。在每一个环节,我们都要付出巨大的代价,都是几十万、几百万、几千万的钱,往里面扔进去。所以从一开始的文档,到篇章,到段落(可能是图表),到句子、词,然后到实体,根据自己的应用场景,我们可能到某一个阶段可以停下来了。比如说用户他关心这个公司的商业模式是什么,这个商业模式通常是一段话,我们只要把这段话给定位出来,我们不需要到实体层面。所以这个“实体”是可以打引号的。在图上面的商业模式本身就可以作为一个实体,大概跟我们平常意义上的实体不太一样。所以在不同的使用场景下,我们不需要拘泥于说一定要实体,或者属性这种东西,够用就行。
下面一句话是我说的:最低成本的结构依靠中学语文。控制成本最核心的问题就是如何能够接近于人的认知,大多数人的认知。大多数人的认知水准是什么呢?就是中学语文嘛。高中是一个人的智力的最高点,高考过去最后那一天,在那之后大家都在走下坡路嘛。高中语文告诉我们,怎么去写作,分段落,分句,每段第一个句子是最重要的。在这里面有丰富的结构,丰富的信息,这种语义信息其实是最容易挖掘出来的。其实有很多人已经发现了也在用了。比如说以前我跟另外一组人合作,做一个Purple Semantic Mediawiki,它的用途就是这个wiki上每一段话我都可以在另外的wiki页面里引用。它每一个段落有自动生成的purple number,这是一个自动生成的URI,然后可以在另一个页面,只要你引用了这个URI,它自动就过来了,也是动态的。因为这是metadata(元数据),所以你可以查询,你可以把几个段落自由的组合在一起,就是有所谓的语义在这里头。
知识表示的成本
下面我们讲一下知识表示的成本。知识表示分成几个层次来讲,从最低层的就是我们有一个东西,给它起名字(命名),然后把这些东西关联在一起(元组),最终我们要发现这个关系背后的关系(本体)。
我觉得降低知识表示的成本的核心就是怎么适应人类的认知的惰性。因为我们大多数人其实都不想动脑子,包括每一个人在大多数时间也是不想动脑子的。而且人的智力的分布的不均衡性是远远大于人的体力的分布不均衡性的。这个有非常多惨痛的教训,包括以前我们做知识系统的可用性实验的时候,发现了大量反面的例子。就是专家开发出来的系统,哪怕是那种大学生级别的用户,都完全没有办法用,因为还是有认知的gap在那里头。我们怎么能够尽可能地降低这种不适应性?
另外我们每一个人都有自己的世界观。这种认知惰性、还有不一致性的核心,是我们大家的世界观是相互冲突的,我们能不能尽可能地隔离这种世界观发生冲突?我们能不能尽可能降低必须的、开始的投入?
在知识表示这三个层面上,从开始的命名到元组,到本体,我们都需要考虑这三个因素。
先讲命名的问题,这里要引用另外一位大师的话:计算机科学里只有两个困难的事情:缓存失效和起名字。
在做基于RDF的建模的时候,每一个实体和每个关系都用URI网址的方式命名,这种方式有好处也有坏处。跟它对应的是用字符串进行命名。用URI命名是高成本的方式,维护成本和构造成本都会比较高。字符串成本相对小一点。URI是一个全局的东西,URI是唯一的:因为它是唯一的,它也是全局的。所以在全球任何一个地方的浏览器的你都可以得到同样一个资源。字符串是多义的,也是上下文相关的。 “苹果”这个词在不同的context下面,它的意义是不一样的。URI是面向机器的,机器可读,人很难去记下来一个很长的URI。人是可以读字符串的。URI的好处是便于互联,所以linked open data强调用URI。字符串是难以互联的。另外还有一点是政治上的考虑,每一个URI都是有主人的,因为它有一个domain(域名),每一个domain都是有组织或者个人去拥有它的,字符串没有主人,要相对自由一些。
所以在怎么去对资源进行命名的问题上面,我们要综合考虑。很多情况下可能URI是一种过早的优化,如果我们能够用字符串保持尽可能长的时间,会降低我们的构造成本。URI的另外一个问题就是它承载了两个功能,一个就是命名(Naming),还有一个就是寻址(Addressing)。命名一个资源然后找到一个资源,其实这两件事情相互之间是冲突的。
最近我在看一篇文章,叫Reference by Description,知识图谱之父Guha写的,他提出来一个解决方案,之前我也想到过类似的这种方法,牺牲命名的一致性。有时候允许我们犯一点点错误,也许我们找URI、找一个资源找错了,但是因为我们牺牲了这个唯一性,我们获得了系统构造成本的极大降低和可维护性的极大提高。其实这也是当年NoSQL兴起的时候的一个想法,因为以前数据库里我想要强一致性,就带来很多问题;NoSQL兴起以后,我们不要强一致性,只要最终一致性(Eventual Consistency),也行。所以我觉得现在从URI往前走,可能到另外一种新的知识表示的方法。这种牺牲URI,牺牲这个一致性,来换取工程上的极大的好处,这个很值得去看一看。
第二点就是元组,我们有了实体之后,我们把实体关联在一起,形成一个结构。我们最常用的就是主语-谓语-宾语(s p o)这种结构,我们把它称为一个三元组,就是RDF或者现在的知识图谱大家都经常用的。但是长期以来我们知道,三元组非常难以表达定语、状语和补语。林老师早上提到了这个Marriage建模,我为什么不直接说张三和李四的关系呢,然后非要构造Marriage这个关系,因为Marriage它有一个时间的这个状语,就是说什么时间到什么时间。我们在传统的这种建模里面,为了表达三元组以上的东西,这个四元组、五元组的话,我们会用reification,这种奇技淫巧,这种东西会极大地降低我们的知识库的可维护性和可读性。所以我称三元组是尼安德特人的语言。这什么意思?我们在座的都是智人,如果有尼安德特人举个手——感觉没有 :D。为什么呢?因为他们被我们吃掉了。语言学家有一个假说,为什么我们智人会把尼安德特人给消灭掉?尼安德特人其实也有语言,也有宗教什么都有。但他们的语言有一种本质的缺陷,他基本上只能说主语谓语宾语。我们”清华打北大“,他可以说这句话对吧。但是我们智人可以说得更完美,说我们”清华的学生,我们明天早上8点钟,每人带根棍子,到北大去“。这样的语言,是尼安德特人没有办法说的,因为是超出主语谓语宾语。所以RDF是尼安德特人的语言,也是为什么我们智人用它非常地别扭。
可能的另外一种解决方案我认为是JSON,特别是现在有了JSON-LD,融合了JSON和RDF的优点,部分地弥补了他们的缺点,形成了一个在表达力和可读性、可维护性之间的一个折衷。这个东西也是刚刚开始兴起,本身它还有很多不足的地方,也还没有成为一个特别被广泛应用和支持的格式。但是我认为这是一个方向。还有就是一些Document Graph Database,就是能够支持JSON的图数据库,我认为值得看一看的。因为它可以有效地降低输入输出的成本和理解的成本,而且我们又可以获得图数据库的各种各样的优势。比如OrientDB就支持这种。这些数据库比较新,也有种种问题,我并不推荐大家在生产系统中用。但我觉得很值得去探索一下。也可能有其他的解决方案,在后面我也会继续提到。
然后再往上走,我们现在有了元组以后,我们就想知道能够产生元组的元组,就是本体。本体,这是一种世界观,因为我们对事情如何分类如何命名,其实是一种政治的考虑。所以引用另外一句名言就是“语言是有军队的方言”,本体是有钱的偏见,这就是为什么这些本体都很难被其他组织利用。所以我们尽可能的在设计的时候啊,要避免这种冲突。
知识存储的成本
最后我们再提一下存储。因为时间有限,可能会跳过一些。在存储的过程中要考虑到,知识图谱里面其实还是会有大量的非结构化数据,所以我们需要一个混合的解决方案。另外还要考虑到维护成本和效率的问题。综合来讲,如果我们不是特别需要一些推理的功能,其实一些现代的关系数据库就够用了,比如说PostgreSQL,它本身也支持JSON。需要图的时候可能Neo4j也是挺好的选择。
知识检索的成本
最后一个讲知识检索,知识检索主要是两方面的成本。今天有很多老师提到了这个问答,其实从关键词检索,到这个问答检索中间有很多步,词联想、同意词,上下位,属性和短关系,长程关系,我们把这些东西都可以称为语义检索,取决于我们需要付出多大的成本。
最后一个可能大家一般不太会注意的问题,就是在知识检索的过程中,其实除了机器的成本,人的成本也是非常重要的一件事情。可能更多时候人的比机器的成本还要高,因为人是有有限的注意力、记忆力和时间的。有一些新的工具可以帮助我们做,比如说像分面浏览器就是Faceted Browser,我认为这个技术也很值得探讨,它可以有效地帮助我们减少探索的时间。就相当于当年为什么有数据库的时候还要有电子表格呢?因为电子表格解决的是人的问题,数据库解决机器的问题。探索引擎可以帮助我们解决人的问题,它是有可能创造一个像电子表格那样巨大市场的一种工具。
总结
最后总结一下就是我们要迭代,知识库是给人设计的。降低成本的核心是考虑人的因素。
注:本文根据鲍捷在清华大学的演讲整理而成
以下为演讲录音:
发表回复