-
Notifications
You must be signed in to change notification settings - Fork 499
第一期w2:知识表示
(鲍捷,2016-06-14)
知识表示(Knowledge Representation,KR,也译为知识表现)是如何将结构化数据组织,以便于机器处理和人的理解的方法。从结构推导出新的结构,这就是推理。传统上KR属于逻辑的分支,但在实践中我们会用很简单、可读、可维护的数据结构。
经典的教科书中的KR,主要关注的是如何方便机器处理。但是在现实的工程中,如何方便人的理解也是极为关键的。在工程实践中,人才是知识不能被处理好、不能快速交换、不能规模化的核心。
知识表现的瓶颈不在于机器处理能力的不足,而在于人的认知能力的不足。因此,我们在学习知识表现方法的时候,要始终牢记知识的可读性、可维护性要远远比它的表达力、计算速度重要。知识是为人阅读而设计的,只是偶尔被机器执行。
作为工程师,我们时时刻刻把可行性放在心中。传统的知识图谱的KR,从逻辑和推理讲起,有一阶逻辑(first-order logic)和描述逻辑(description logic),后来又有逻辑程序(logic program)和生成规则(Production Rule)。但是我反对从逻辑开始理解知识图谱。语义网和知识图谱是关于数据的,关于结构促进数据的流动,用结构化数据增进其他系统的自动化能力的。逻辑只是很小的一个插件。
语义网,或者现在的知识图谱,在应用中,核心问题不是“应该怎么样”,而是“不得不怎么样”。语义推理对数据质量的要求很高,在工程上成本就承受不了。现实的应用,只能逐步提高数据的质量,从数据清洗开始就要承担巨额的投入,然后做实体抽取,实体链接,对齐,消歧,关系抽取,对齐,词库提取,本体建模,这每一步都是海一样的银子砸进去。
然后在推理中,推理规则都需要人生成。现在机器生成规则的能力很弱,几乎不可用。仅仅是属性和直接关系的查找可以机器做,稍微复杂的长程关系都需要人来写。这在工程部署中有巨大的困难,因为这样的工程师很少,写出来的东西可维护性,性能,普适性都成问题。所以现实中的系统,很少有做推理的。即使是做推理,也很少是一阶逻辑推理,一般也就是if then else,命题逻辑。很多时候还要容忍数据中的噪声,和正则表达式等结合在一起用。所以学术派的推理机,一般都用不了。
所以我们会了解RDF和OWL,但是并不推荐使用这些W3C标准作为工程的选择。我们认为JSON和关系数据库是工程中成本较小的解决方案。在某些特定场合,图的表示也是合理的。这会在之后的“知识存储”的章节继续讨论。
其他一些我的个人观点
- 我对关联数据的看法 http://baojie.org/blog/2014/12/21/on-linked-data/
- 语义网的工具演化 http://baojie.org/blog/2014/02/12/semantic-tool-evolution/
- 语义网不需要描述逻辑 http://baojie.org/blog/2013/02/05/semantic-web-and-description-logic/
在知识提取之后,如何表示知识?其实知识并不神秘,只是一些数据之间的关系。在计算机中的表示,就是数据结构。传统上,我们把那些能够导出新的关系的关系(比如“爸爸的爸爸是爷爷”,这里面“爸爸”和“爷爷”都是关系)看成知识。但是在目前的知识图谱实践中,并不会有严格的区分,我们把各种结构都可以看成广义的知识。
不过不是所有的数据结构我们会用知识工程的方法来处理,比如集合、哈希表、队列、堆栈、链表等等,一般丢给软件工程去处理。另一类特殊的结构,二维表,我们丢给数据工程去解决。当然数据工程和知识工程之间没有严格的界限,二维表和复杂知识结构表示之间也有交叉,暂留后述。
知识表现的数据结构,一般来说是那些“复杂”的结构,最常见的就是图(graph)和树(tree)。
知识表现的图,是“有类型的边”(typed edge),分析方法和一般的图论和社交关系图谱中分析的无类型的边很不相同。传统的Web结构只有“链接”这一种关系。在2000年代中,语义网试图给链接加上类型说明,如某人主页声明工作于某公司,这就有“工作”关系。这里,类型就是边的“元数据”(metadata)。后来,发现在应用中还需要给边,当然还有节点,添加更多的元数据,这就形成了有类型的边构成的图谱结构,上面每个边和每个节点都拥有元数据。
图的知识表现,演化出两个流派。一个是RDF图,一个是属性图(Property Graph)。RDF图是W3C的官方标准,得到了政府资金和一些大公司的大力支持,但是最终市场表现平平。属性图是草根自发的,最终得到了市场的认可,现在主要是中小企业、创业公司在用。RDF图是科学顶层设计出来的,属性图是工程实战中总结出来的。它们发展轨迹的不同也再次证明,好的架构一般是总结出来的,不是凭空设计出来的。
RDF图的基础是三元组,用URI命名节点和连接节点,有严格的语义,约束比较多。属性图没有严格的语义,可以比较自由地声明节点和边的属性。RDF的优势在于推理,但是三元组的组织使稍复杂的关系的表达很困难,具体后述。属性图不定义推理,但是可以通过查询语言(如Gremlin)来做模式(pattern)的查找和图上的遍历(traverse),可以实现特设的(ad-hoc)的推理。也待到图数据库部分细说。
用图表示知识,丰富的知识结构主要表现为图上的边,各种推理算法就是在图上推导出边的算法。在传统图论里,有可达性(reachability)推理,有大量的优化研究。一些基本的传递性的推理,如分类树(taxonomy),是可以转化为图可达性推理的。但是大量的其他类型的推理,没有成熟的工程系统和算法可用。现有的图数据库,都局限很大,工程上成本很高。
图表示的另一个问题是对混合表示不是很友好。因为知识提取的成本是很高的,所以现实的工程中我们很难一步到位生成纯结构化的数据表示,我们的数据往往是结构化和非结构化(主要是文本)混合的。其中结构化的比例,结构化的质量,可能是在应用的过程中逐步提升的。开始的时候可能文本的比例比较大。虽然RDF图和属性图上的节点都可以有文本属性,但是图的索引还是与文本索引大不同,在实际使用中需要依赖集成Lucene之类的全文检索引擎。由于文本不是“一等公民”,很多建模难以实现,比如在RDF里文本不能作为三元组的主语。
由于图表示很复杂,最广为接受的知识组织其实是树(taxonomy,hierarchy)。这是人的认知决定的。计算机发展这么多年,界面元素的组织,被广为接受的也只有树、列表、表格。那些看起来很复杂的知识库,其基础也都是树。
所以树形的JSON最终脱颖而出,不是偶然的。它符合人的认知,满足了结构化和非结构化混合表示的需要,兼容现有的工程实现。JSON表示被称为“文档”(document),2009年以来兴起了很多文档数据库(document database)。最近又有了PostgeSQL和OrientDB这样混合关系与文档的数据库,可以实现可读性好、工程兼容性好、表达力也还够用的知识表示。
JSON是很简单的数据格式。JSON成为Web API的事实标准,部分实现了当初语义网的一些目标。但是几年前,我和一位语义网领域的知名教授聊到语义数据的表示问题,我提到了JSON,他表示没听说过。这让我很震惊,学术界何以对工业界数据表示的事实标准如此不关心呢?
我们做研究,一定要从实践中来,到实践中去。实际的数据是什么样,用什么样的成本能获得这些数据,这都不是随便能假设的。JSON在和XML的竞争中胜利,基于JSON的REST服务框架在和基于XML的SOAP的竞争中胜利,不是偶然的。因为JSON和REST更符合人的认知的需要,生成他们的成本低,理解他们的成本低,工程师容易理解,最终就用起来了。所以现在XML和SOAP虽然是“国际标准”,但在Web上用的人很少,JSON和REST这些“野路子”一统天下。这和属性图数据库超越RDF数据库是一个道理。
在Python中使用JSON超级简单,JSON和Python的字典很像,可以转换。看官方文档即可
掌握下面这些库会让你处理json和字典的时候更开心
- attrdict https://github.com/bcj/AttrDict a['foo']['bar']可以写做a.foo.bar 或a['foo'].bar。可读/写属性,可递归访问属性,继承dict的各种方法
- marisa-trie https://github.com/kmike/marisa-trie 超级节约内存的字典
- DAWG http://dawg.readthedocs.org/en/latest/ 另一个超级节约内存的字典
- orderedmultidict https://github.com/gruns/orderedmultidict 多值有序字典
- jsonpickle http://jsonpickle.github.io/ JSON持久化。支持更复杂数据的存储
- jq http://stedolan.github.io/jq/tutorial/ 命令行上的json处理和查询
- pjson https://github.com/igorgue/pjson 在命令行上彩色打印json
- jsonlint https://github.com/zaach/jsonlint 格式化json
- jsawk https://github.com/micha/jsawk json的awk,一个快速的命令上的查询工具
- json-diff https://www.npmjs.org/package/json-diff 比较两个json
以上都是良心推荐,经多年工程实战考验的趁手工具。掌握了这些即使学不好知识图谱,也可以成为不错的数据科学家 :D
还有一些高级的话题,json pointer, json schema, xml2json, csv2json,暂时不提。我们只需要知道,json的工具链极为丰富。很多时候我们处理数据,就是卡在这些“小”工具上。你要是用了RDF,就会在无数小地方上因为缺少这些小工具而痛苦。
最后要隆重推荐一下YAML:JSON的超集,有更简洁的语法 http://yaml.org/
警告 Yaml可能有严重的世界观副作用,过敏者请谨慎使用。
YAML在我看来比JSON的可读性更好,更加Pythonic(因为其语法接近Python)。当然有人可能会不喜欢缩进,不过Python社区的智力一般比较高,不会有这种偏见。YAML里可以有节点之间的链接,因此可以表示图。此外yaml里可以写!注!释!我认为YAML是天然的最好的知识图谱表示语法。
PyYAML是Python里的Yaml处理库 http://pyyaml.org/wiki/PyYAML
不过Yaml解析的速度比json慢得多,大概只有1/10。但是我们要牢记,知识表示最重要的是对人的友好,不是对机器的友好。速度不是大的问题,大部分的知识库都不是特别大。
最后多说一句无关的话,很多语言都有可读性更好的类Python语法。下面是我收集的一个列表
yaml -- readable json
coffeescript -- readable javascript
RapydScript -- readable javascript
groovy -- readable java
markdown -- readable html
RapydML -- readable html
jade -- readable html template
SASS,Stylus -- readable css
Turtle -- readable RDF
有一本经典的编程书《The Art of Readable Code》 https://book.douban.com/subject/5442971/ 。我觉得同样的在知识表示里,我们应该追求“易读知识的艺术”。工程上,这是特别重要的一件事。
虽然在大部分的应用场景下我都不会推荐大家使用RDF和OWL,但了解一下它们还是很有必要的,当是打免疫针。当然这两个语言非常的复杂,官方文档打印出来有1000页厚,展开讲的话一个学期也讲不完。好在我们是工程师,只关心如何应用,不需要全面了解。
Turtle语法 http://www.w3.org/TR/turtle/
2011年的综述,提到了RdfLib RdfAlchemy Fuxi ORDF Django-RDF Djubby Redland SuRF PySparql Sparta Oort Virtuoso pySesame pynappl HTTP4Store py4s Survey of Pythonic tools for RDF and Linked Data programming http://www.michelepasin.org/blog/2011/02/24/survey-of-pythonic-tools-for-rdf-and-linked-data-programming/
本文没包括的还有rdfQuery PySWIP pyDatalog PyLog FLiP seth sparrow pymantic pyRDFa djubby pySPARQL
W3C的官方入门导引
- RDF 1.1 Primer https://www.w3.org/TR/rdf11-primer/
- OWL 2 Primer http://www.w3.org/TR/owl2-primer/
手册
- 语义网速查表 http://ebiquity.umbc.edu/resource/html/id/94/
- OWL语法速查表 https://www.w3.org/TR/2012/REC-owl2-quick-reference-20121211/
- RDF和OWL语义 http://blog.memect.cn/?p=871 我的两个ppt,讲解了RDF和OWL的模型论语义
以下待续
(其实W3C的官方文档并不是学习的好起点)
JSON和RDF的混合 http://json-ld.org/
https://www.w3.org/TR/2014/REC-json-ld-20140116/
自己设计电子邮件的结构化表示
#KG小组北京一期成员github账号:
姓名 账号
- 胡杨 superhy
- 徐卓夫 ipush
- 侯月源 moonscar
- 田昌海 Jamestch
- 高晓燕 elisagao
- 侯立莎 yimiwawa
- 耿新鹏 xpgeng
- 梁方舟 pklfz
- 郑胤 Lan09 (TBD)
- 王鸿霄 wang101
- 李靖 L0113408
- 方东昊 Spirit-Dongdong
- 丁海星 godlikedog
- 付 鹏 pengfoo
- 张梦迪 mandyzore
- 佟海奇 tongtongqi
- 郭兴雨 buptguo
- 张志瑛 minenki
- 曹志远 smartczy
- 周祥 ucaszx
- 杨凯文 gentlekevin
- 王震 newle
- 鲍捷 baojie