拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

知识表示与专家系统:用符号 AI 教计算机“理解“世界

知识表示与专家系统:用符号 AI 教计算机“理解“世界
  • 教程
  • 人工智能
  • 机器学习
  • 深度学习

【免费下载链接】AI-For-Beginners

12 Weeks, 24 Lessons, AI for All!

项目地址:https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners
点击查看免费下载

本文以 AI-For-Beginners 课程第 2 课(lessons/2-Symbolic/README.md)为主线,系统讲解符号 AI 的两大支柱——知识表示(Knowledge Representation)与推理(Reasoning):从 DIKW 金字塔厘清数据/信息/知识/智慧的关系,到语义网络、框架、产生式规则与逻辑四类计算机知识表示方法,再到专家系统的架构、前向/后向推理算法,最后延伸到本体论(Ontology)与语义网(Semantic Web)。配合仓库内 Animals.ipynb、FamilyOntology.ipynb、MSConceptGraph.ipynb 三个可运行 Notebook,读者可以亲手实现并驱动一套基于规则的知识系统,理解"可解释 AI"的最早形态。

背景:自顶向下的人工智能路线

早期 AI 的主流路线是自顶向下:把人类专家头脑中的知识抽取出来,转成机器可读的形式,再交给计算机自动求解问题。这一路线建立在两大核心思想上:

  • 知识表示(Knowledge Representation):如何把知识编码成计算机可处理的数据结构;
  • 推理(Reasoning):如何在这些知识之上自动得出结论。

这个思路与当前以神经网络为主导的统计学习方法形成鲜明对照,也是理解专家系统、语义网等一系列符号 AI 技术的起点。

知识表示:让知识"住进"计算机

知识与数据、信息、智慧的区别

符号 AI 里最重要的概念是知识(knowledge),它必须与信息、数据区分开。比如我们说"书里包含知识",但严格讲,书里存放的其实是数据;人类通过阅读把数据融入自己对世界的模型,才完成了从数据到知识的转化。

✅知识是我们头脑中已有的、代表对世界理解的东西,通过主动的学习过程,把接收到的信息整合进我们的世界模型。

要精确界定知识,最常用的参照是 DIKW 金字塔(Data–Information–Knowledge–Wisdom):

层级含义
数据(Data)存在于物理介质上的表示,如文字、语音,独立于人存在,可传递
信息(Information)人脑对数据的解读,例如听到"computer"这个词时我们已有的理解
知识(Knowledge)信息被整合进世界模型后形成的相互关联的概念网络
智慧(Wisdom)对知识使用的"元知识",即知道何时、如何运用知识

DIKW 金字塔示意图(图见lessons/2-Symbolic/images/DIKW_Pyramid.png,源自 Wikimedia,CC BY-SA 4.0)。

知识表示是一个"谱系"

知识表示要解决的问题是:如何在计算机内部用数据形式高效表示知识,使其能被自动使用。不同表示方法构成一个谱系:

  • 谱系最左端是计算机最容易高效使用的表示,最简单的是算法式——把知识写成一个计算机程序。但这种表示不够灵活,因为人脑中的知识常常是非算法的;
  • 谱系最右端是自然语言文本,表达能力最强,却无法用于自动推理。

知识表示谱系图(图见lessons/2-Symbolic/images/knowledge-spectrum.png,作者 Dmitry Soshnikov)。

✅ 想一想:你平时如何在大脑中组织知识、又如何把它转成笔记?有没有某个特定格式特别有助于记忆?

计算机知识表示的四类方法

可以把各种知识表示方法归纳为四类:

1. 网络表示(Network Representations)

基于"人脑中存在相互关联的概念网络"这一事实,把同样的网络以图的形式复现在计算机里,即语义网络(semantic network)。图可以用节点与边组成的列表表示,因此语义网络可以表示为对象-属性-值(OAV)三元组或属性-值对。例如用三元组描述编程语言:

对象(Object)属性(Attribute)值(Value)
PythonisUntyped-Language
Pythoninvented-byGuido van Rossum
Pythonblock-syntaxindentation
Untyped-Languagedoesn't havetype definitions

✅ 想想三元组还能表示哪些类型的知识。

2. 层次表示(Hierarchical Representations)

强调人脑常按层次组织对象:例如"金丝雀是鸟,鸟有翅膀"。这一类下有两种经典机制:

  • 框架表示(Frame representation):把每个对象或对象类表示成一个框架(frame),内含若干槽(slot)。槽可以带默认值、取值约束,或存储用于取值的可调用过程。所有框架构成类似面向对象语言对象层次的层级结构。以 "Python" 为例:
槽(Slot)值(Value)默认值(Default)区间(Interval)
NamePython
Is-AUntyped-Language
Variable CaseCamelCase
Program Length5-5000 lines
Block SyntaxIndent
  • 情景(Scenarios):一种特殊的框架,用来表示随时间展开的复杂情境。
3. 过程表示(Procedural Representations)

把知识表示为在特定条件满足时可执行的动作列表:

  • 产生式规则(Production rules):即 if-then 语句,允许我们推出结论。例如医生可以有一条规则:如果病人高烧或血液中 C 反应蛋白偏高,那么他存在炎症。一旦任一条件成立即可推出炎症,并用于后续推理;
  • 算法(Algorithms):也可视为一种过程表示,但在基于知识的系统中几乎从不直接使用。
4. 逻辑(Logic)

逻辑最早由亚里士多德提出,作为表示普适人类知识的方式:

  • 谓词逻辑(Predicate Logic):作为数学理论表达能力过强、不可计算,通常使用其子集,如 Prolog 中的Horn 子句(Horn clauses);
  • 描述逻辑(Description Logic):一族用于表示与推理对象层次结构、以及语义网这类分布式知识表示的逻辑系统。

专家系统:符号 AI 的第一个里程碑

专家系统(Expert Systems)是符号 AI 早期最成功的成果之一:在有限问题领域内扮演专家角色的计算机系统。它建立在从一位或多位人类专家那里抽取的知识库(knowledge base)之上,并内含执行推理的推理引擎(inference engine)。

知识系统架构示意(与人类神经系统简化结构的对比见lessons/2-Symbolic/images/arch-human.png)。

专家系统的构造模仿人类推理系统(含短期记忆与长期记忆),对应到知识型系统,可区分以下组件:

组件作用
问题记忆(Problem memory)存放当前正在求解的问题知识,如病人的体温、血压、是否有炎症等。又称静态知识,因为它是当前问题状态的快照(problem state)
知识库(Knowledge base)表示问题领域的长期知识,由人类专家手工抽取,咨询过程中不改变;因为它驱动问题状态迁移,又称动态知识
推理引擎(Inference engine)统筹问题状态空间的搜索,必要时向用户提问,并为每个状态找到可应用的合适规则

产生式规则与 AND-OR 树

以"根据物理特征判定动物"的专家系统为例。下图被称为AND-OR 树,是产生式规则集合的图形化表示:

AND-OR 树示意图(图见lessons/2-Symbolic/images/AND-OR-Tree.png,作者 Dmitry Soshnikov)。

从专家处抽取知识的早期阶段,画树非常有用;而要把知识放进计算机,用规则更便捷:

IF the animal eats meat OR (animal has sharp teeth AND animal has claws AND animal has forward-looking eyes ) THEN the animal is a carnivore

注意:规则左侧的每个条件与右侧动作,本质上都是 OAV 三元组。工作记忆(working memory)保存与当前问题对应的 OAV 三元组集合;规则引擎寻找条件满足的规则并应用之,从而向工作记忆添加新的三元组。

✅ 挑一个你感兴趣的主题,画出自己的 AND-OR 树。

前向推理 vs. 后向推理

上述"由数据推出结论"的过程称为前向推理(forward inference)。它以工作记忆中的初始数据为起点,执行如下推理循环:

  1. 若目标属性已出现在工作记忆中——停止并给出结果;
  2. 查找所有条件当前被满足的规则,得到规则的冲突集(conflict set);
  3. 进行冲突消解(conflict resolution),选出本步要执行的一条规则。常见策略有:
    • 选取知识库中第一条可应用的规则;
    • 随机选取一条规则;
    • 选取更特化(more specific)的规则,即左侧(LHS)条件命中最多的那条;
  4. 应用所选规则,向问题状态插入新知识;
  5. 回到第 1 步重复。

但有些场景我们想从"对问题一无所知"开始,靠提问逐步逼近结论。比如医学诊断:通常不会先做完所有检验再开始诊断,而是在需要做决策时才去做相应检查。这种过程可用后向推理(backward inference)建模,它由目标(goal)——我们想求的属性值——驱动:

  1. 选出所有能给出目标值的规则(即目标出现在右侧 RHS 的规则),构成冲突集;
  2. 若该属性没有规则、或某条规则指示应向用户询问取值,则直接询问用户;否则继续;
  3. 用冲突消解策略选出一条规则作为假设(hypothesis),尝试证明它;
  4. 对该规则 LHS 上的每个属性递归重复上述过程,把它们当作子目标去证明;
  5. 若过程中任一点失败,回到第 3 步改用其他规则。

✅ 什么场景下前向推理更合适?后向推理呢?

专家系统的实现途径

实现专家系统主要有两种途径:

  • 直接用高级编程语言编写:这不是最佳选择。基于知识的系统最大优势在于知识与推理相分离——领域专家理论上应能只写规则、而不必理解推理过程的细节;
  • 使用专家系统外壳(expert systems shell):一种专门为装载知识而设计的系统,通过某种知识表示语言填充知识。

✍️ 动手实验一:动物识别专家系统(Animals.ipynb)

仓库中的 Animals.ipynb 给出了前向与后向推理专家系统的完整实现,是理解上述理论的最佳入口。该 Notebook 自建了一个极简"专家系统外壳",再切换到 Experta 库做前向推理。

自建外壳:用 Python 类定义规则语言

Notebook 先用 Python 类定义了知识表示的小语言,只有 3 种核心类:

class Ask(): def __init__(self,choices=['y','n']): self.choices = choices def ask(self): if max([len(x) for x in self.choices])>1: for i,x in enumerate(self.choices): print("{0}. {1}".format(i,x),flush=True) x = int(input()) return self.choices[x] else: print("/".join(self.choices),flush=True) return input() class Content(): def __init__(self,x): self.x=x class If(Content): pass class AND(Content): pass class OR(Content): pass
  • Ask表示需要向用户提出的问题,携带候选答案集合;
  • If表示一条规则,本质上是存储规则内容的语法糖;
  • AND/OR表示树的 AND/OR 分支,只存储参数列表;为简化代码,全部功能定义在父类Content中。

在该系统中,工作记忆是一组属性-值对形式的事实;知识库定义为一个把"动作(应插入工作记忆的新事实)"映射到"由 AND-OR 表达式表示的条件"的大字典,部分事实可直接Ask询问。动物知识库如下:

rules = { 'default': Ask(['y','n']), 'color' : Ask(['red-brown','black and white','other']), 'pattern' : Ask(['dark stripes','dark spots']), 'mammal': If(OR(['hair','gives milk'])), 'carnivor': If(OR([AND(['sharp teeth','claws','forward-looking eyes']),'eats meat'])), 'ungulate': If(['mammal',OR(['has hooves','chews cud'])]), 'bird': If(OR(['feathers',AND(['flies','lies eggs'])])), 'animal:monkey' : If(['mammal','carnivor','color:red-brown','pattern:dark spots']), 'animal:tiger' : If(['mammal','carnivor','color:red-brown','pattern:dark stripes']), 'animal:giraffe' : If(['ungulate','long neck','long legs','pattern:dark spots']), 'animal:zebra' : If(['ungulate','pattern:dark stripes']), 'animal:ostrich' : If(['bird','long nech','color:black and white','cannot fly']), 'animal:pinguin' : If(['bird','swims','color:black and white','cannot fly']), 'animal:albatross' : If(['bird','flies well']) }

后向推理引擎:KnowledgeBase 类

为执行后向推理,Notebook 定义了KnowledgeBase类,包含:

  • 工作记忆memory——把属性映射到值的字典;
  • 知识库rules——上述格式的规则集。

两个核心方法是:

  • get(name):取得属性值,必要时触发推理。例如get('color')会得到 color 槽的值(必要时询问用户并存入工作记忆供后续复用);若调用get('color:blue'),则会先询问颜色,再按颜色是否等于 blue 返回y/n;
  • eval(expr):执行真正的推理,即遍历 AND/OR 树、求值子目标。
class KnowledgeBase(): def __init__(self,rules): self.rules = rules self.memory = {} def get(self,name): if ':' in name: k,v = name.split(':') vv = self.get(k) return 'y' if v==vv else 'n' if name in self.memory.keys(): return self.memory[name] for fld in self.rules.keys(): if fld==name or fld.startswith(name+":"): value = 'y' if fld==name else fld.split(':')[1] res = self.eval(self.rules[fld],field=name) if res!='y' and res!='n' and value=='y': self.memory[name] = res return res if res=='y': self.memory[name] = value return value # field is not found, using default res = self.eval(self.rules['default'],field=name) self.memory[name]=res return res def eval(self,expr,field=None): if isinstance(expr,Ask): print(field) return expr.ask() elif isinstance(expr,If): return self.eval(expr.x) elif isinstance(expr,AND) or isinstance(expr,list): expr = expr.x if isinstance(expr,AND) else expr for x in expr: if self.eval(x)=='n': return 'n' return 'y' elif isinstance(expr,OR): for x in expr.x: if self.eval(x)=='y': return 'y' return 'n' elif isinstance(expr,str): return self.get(expr) else: print("Unknown expr: {}".format(expr))

定义好知识库后即可开始"会诊"(kb.get('animal'))。注意:这次调用会向你提问——是非题输入y/n,多选长答案则输入选项编号(0..N)。Notebook 中的一次运行轨迹显示,系统依次追问hair、sharp teeth、claws、forward-looking eyes、color、has hooves、long neck、long legs、pattern,最终根据答案组合得出结论'giraffe'。

前向推理:借助 Experta

Notebook 的第二部分用 Experta 实现前向推理。Experta是 Python 中用于构建前向推理系统的库,设计上模仿经典老牌系统 CLIPS。当然我们也可以自己实现前向链(forward chaining),但朴素实现通常效率不高;更高效地规则匹配需要使用专门的Rete 算法。

安装与使用方式:

import sys !{sys.executable} -m pip install git+https://github.com/nilp0inter/experta from experta import *

将系统定义为一个继承KnowledgeEngine的类,每条规则用带@Rule注解的函数声明,注解里指明规则的触发条件;规则体内用declare函数新增事实,新增事实会继续触发更多规则——这正是前向推理引擎的工作方式:

class Animals(KnowledgeEngine): @Rule(OR( AND(Fact('sharp teeth'),Fact('claws'),Fact('forward looking eyes')), Fact('eats meat'))) def cornivor(self): self.declare(Fact('carnivor')) @Rule(OR(Fact('hair'),Fact('gives milk'))) def mammal(self): self.declare(Fact('mammal')) @Rule(Fact('mammal'), OR(Fact('has hooves'),Fact('chews cud'))) def hooves(self): self.declare('ungulate') @Rule(Fact('mammal'),Fact('carnivor'), Fact(color='red-brown'), Fact(pattern='dark spots')) def monkey(self): self.declare(Fact(animal='monkey')) @Rule(Fact(animal=MATCH.a)) def print_result(self,a): print('Animal is {}'.format(a))

规则定义好后,向工作记忆填充初始事实,再调用run()执行推理。结果会显示新的派生事实不断加入工作记忆,包括最终动物结论:

ex1 = Animals() ex1.reset() ex1.factz([ Fact(color='red-brown'), Fact(pattern='dark stripes'), Fact('sharp teeth'), Fact('claws'), Fact('forward looking eyes'), Fact('gives milk')]) ex1.run() ex1.facts

运行输出Animal is tiger,且工作记忆的FactList中可以看到由初始事实逐步推出的Fact('mammal')、Fact('carnivor')、最终Fact(animal='tiger')的完整推理链。

注意:这个示例相当简单,只用来展示专家系统的样子。真正开始构建时,通常要积累到200+ 条规则才会观察到明显的"智能"行为。此时规则已复杂到无法全部记在脑中,你可能会开始疑惑系统为何做某个决定——但知识型系统最重要的特性是:你总能精确解释任何决策是如何做出的。

本体论与语义网

20 世纪末出现了一项倡议:用知识表示去标注互联网资源,使用户能检索到匹配非常具体查询的资源。这一方向被称为语义网(Semantic Web),依赖以下概念:

  • 一种基于**描述逻辑(DL)**的特殊知识表示。它类似框架式知识表示——同样构建带属性的对象层次——但具备形式化的逻辑语义与推理。DL 是一整个家族,在表达力与推理的算法复杂度之间取得平衡;
  • 分布式知识表示:所有概念都用全局 URI 标识符表示,从而可以创建横跨互联网的知识层次;
  • 一组基于 XML 的知识描述语言:RDF(资源描述框架)、RDFS(RDF Schema)、OWL(本体语言)。

语义网的核心概念是本体论(Ontology):使用某种形式化知识表示对问题领域的显式规格说明。最简单的本体可以只是问题领域中对象的层次,更复杂的本体则会包含可用于推理的规则。

在语义网中,所有表示都基于三元组,每个对象与关系都由 URI 唯一标识。例如要陈述"AI 课程由 Dmitry Soshnikov 于 2022 年 1 月 1 日创作":

三元组示意(图见lessons/2-Symbolic/images/triplet.png,作者 Dmitry Soshnikov)

http://github.com/microsoft/ai-for-beginners http://www.example.com/terms/creation-date “Jan 1, 2022” http://github.com/microsoft/ai-for-beginners http://purl.org/dc/elements/1.1/creator http://soshnikov.com

✅ 这里http://www.example.com/terms/creation-date与http://purl.org/dc/elements/1.1/creator是表达"创作者""创建日期"概念的公认通用 URI。

更复杂的情形——比如要定义一个创作者列表——可用 RDF 中定义的数据结构表达:

复杂三元组结构示意(图见lessons/2-Symbolic/images/triplet-complex.png,作者 Dmitry Soshnikov)

语义网建设的进展部分被搜索引擎与自然语言处理技术的成功所减缓——这些技术已能从文本中抽取结构化数据。但在某些领域仍有大量维护本体与知识库的工作值得关注:

  • WikiData:与 Wikipedia 关联的机器可读知识库集合,大部分数据来自 Wikipedia 的信息框(InfoBox)。可用SPARQL(语义网的专用查询语言)查询,例如下面的查询展示人类中最常见的眼睛颜色:
#defaultView:BubbleChart SELECT ?eyeColorLabel (COUNT(?human) AS ?count) WHERE { ?human wdt:P31 wd:Q5. # human instance-of homo sapiens ?human wdt:P1340 ?eyeColor. # human eye-color ?eyeColor SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } } GROUP BY ?eyeColorLabel
  • DBpedia:另一项与 WikiData 类似的努力。

✅ 想亲手创建或打开现有本体?有一个很棒的图形化本体编辑器Protégé,可下载或在线使用。Protégé 编辑器界面(图见lessons/2-Symbolic/images/protege.png,Dmitry Soshnikov 的截图,图中为打开的 Romanov 家族本体)。

✍️ 动手实验二:家族本体(FamilyOntology.ipynb)

FamilyOntology.ipynb 演示了如何用语义网技术对家族关系进行推理:输入以通用GEDCOM格式表示的家族谱系,结合一个家族关系本体,为给定个体集合构建全部家族关系的图。

实验数据就存放在仓库中:

  • 罗曼诺夫沙皇家族的谱系文件 data/tsars.ged——GEDCOM 5.5 格式,例如0 @0@ INDI/1 NAME Mihail Fedorovich /Romanov//1 SEX M这样的个体记录;Notebook 用python-gedcom库解析它;
  • 家族关系本体 data/onto.ttl——Turtle 格式的 OWL 本体,约 288 行。其中既有类定义(Man、Woman、Person、Marriage、Sex、Ancestor等,并通过owl:equivalentClass、owl:intersectionOf、owl:disjointWith等构造定义语义),也有对象属性定义(hasMother、hasFather、isBrotherOf、isSisterOf、hasUncle、isGreatUncleOf、hasSpouse等,大量使用owl:inverseOf、owl:subPropertyOf、owl:propertyChainAxiom、owl:TransitiveProperty、owl:SymmetricProperty、owl:FunctionalProperty来表达关系推理规则)。

Notebook 的做法是:创建一个包含"家族本体原有规则 + GEDCOM 文件提取出的个体事实"的统一本体文件——遍历 GEDCOM 提取家庭与个体信息并转换为三元组,再追加进本体的 Turtle 文件,最后用推理工具加载(g.parse("onto.ttl", format="turtle"))并查询推理出的家族关系。

🚀挑战:在这个 Notebook 里可以继续实验其他家族关系,尝试在族谱中发现人与人之间新的连接。

✍️ 动手实验三:概念图(MSConceptGraph.ipynb)

大多数情况下本体由人工精心构建,但也存在从非结构化数据中**挖掘(mine)**本体的可能,比如从自然语言文本。

微软研究院曾做过这类尝试,产出了 Microsoft Concept Graph:一个用is-a继承关系聚拢大量实体的大型集合,能回答"Microsoft 是什么?"这类问题——答案是"以 0.87 概率是公司、以 0.75 概率是品牌"。该图以 REST API 或可下载的大型文本文件(列出全部实体对)两种形式提供。

MSConceptGraph.ipynb 展示了如何用概念图把新闻文章归类到若干类别。注意:原版 Microsoft Concept Graph 的 API 已不可用,该 Notebook 已改用ConceptNet——一个免费开放、同样具备概念间is-a关系的知识图谱。它提供免密钥的 REST API,例如:

https://api.conceptnet.io/query?start=/c/en/microsoft&rel=/r/IsA&limit=10

Notebook 的流程大致是:先对文本做词性标注与名词短语抽取,然后对每个名词短语调用概念图 API 取其上位的IsA概念,用这些更宽泛的概念(而非具体名词)给新闻标题聚类——因为具体名词通常形不成大的主题群。新闻数据来自 NewsAPI.org(需自行注册免费 API Key)。

结论:显式推理的价值

今天,AI 常被当作机器学习或神经网络的同义词。但人类还具备显式推理能力,而这正是神经网络当前无法处理的。在真实项目中,显式推理仍被用于那些需要解释、或需要以受控方式修改系统行为的任务——专家系统、语义网与知识库正是这种可解释智能的载体。

复习与自修

建议进一步研究人类历史上量化、编码知识的各种尝试:

  • 查阅Bloom 的认知目标分类学(Bloom's Taxonomy);
  • 回顾林奈(Linnaeus)的生物分类学体系;
  • 观察门捷列夫(Dmitri Mendeleev)如何为化学元素建立描述与分组方式;
  • 寻找更多类似的有趣案例。

配套练习:创建一个本体(见 assignment.md)——挑选一个主题(人、地点或物品),用本课介绍的技术与建模策略为其建模。示例:为客厅创建本体(家具、灯等),并思考它与厨房、卫生间有何不同?如何判断它是客厅而不是餐厅?使用Protégé完成构建。

  • 教程
  • 人工智能
  • 机器学习
  • 深度学习

【免费下载链接】AI-For-Beginners

12 Weeks, 24 Lessons, AI for All!

项目地址:https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners
点击查看免费下载

相关推荐

上一篇:突破性存储优化:Milvus聚类压缩技术深度解析与架构设计实战指南
下一篇:揭秘智能裁剪算法:从数学基础到色彩空间的终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表