Skip to content

Latest commit

 

History

History
188 lines (107 loc) · 8.04 KB

report.md

File metadata and controls

188 lines (107 loc) · 8.04 KB

人工智能课程项目-"Pokemon Know"-报告

15307130185 王鹏

[TOC]

项目介绍

我的项目idea来源自微软小冰两年前推出的应用——读心术,这是一款基于人物知识库进行问答并猜出相应人物的专家系统。

2018-01-08 23-08-38屏幕截图.png

我在本项目中设计开发的是一款类似于微软小冰读心术的专家系统——Pokemon Know,只是把范围限制在了第一世代的Pokemon(或称:神奇宝贝,精灵宝可梦)中。

目前知识库涵盖了第一世代的59只宝可梦,具体名单见这里

如果用户了解足够的事实,符合条件的宝可梦一般能在8个问题内找出来。

项目特点

  • 基于框架(frame)的专家系统
    • 支持框架的继承
    • 规则的隐式表达
  • 基于确信因子的不确定性管理
  • 基于决策树的ID3算法
  • 友好的用户界面
  • 友好的知识库扩展机制

运行方法与环境

需要本机装有Python3,界面依赖第三方Python-GUI库PyQt5。

如果不想知道专家系统运行时的内部部分信息,在source目录下运行命令:

python Play.py

如果想知道专家系统运行时的内部部分信息,在source目录下运行命令:

python Main.py

(注意:程序在最后的流程中会调用网络上的图片资源,因此要求该专家系统在有网络的条件下使用。)

###组成与逻辑

1.用户界面作为用户与系统的交互媒介,向用户展示问题,并获得事实。

2.基于框架的知识数据库储存已有的Pokemon知识,以皮卡丘为例,其知识库内容(目前)为:

{
"名字": {"皮卡丘": "defi"},
 "整体颜色": {"黄色": "prob"},
 "继承": {"四足兽": "prob", "鼠宝可梦": "prob"},
 "眼睛颜色": {"黑色": "prob", "褐色": "prob"},
 "耳朵颜色": {"黄色": "prob", "黑色": "prob"},
 "肢数": {"4": "prob"},
 "翅膀数": {"0": "prob"},
 "地区": {"关都":"prob", "城都":"prob", "丰缘":"prob", "神奥":"prob", "卡洛斯":"prob", "阿罗拉": "prob"},
 "特点": {"前爪有五个\"手指\"": "defi", "有像锯齿状闪电的尾巴": "defi"}
}

3.候选的Pokemon类维护着自身的信息(例如确信程度等等)。

4.我们假定使用该专家系统的用户知道Pokemon的基本外貌信息。

5.推理引擎根据候选的Pokemon和用户提供的事实,对已有的Pokemon的确信因子进行更新,并根据相应的规则,筛出部分不合格的Pokemon,然后根据相关算法(见下文)设计出合适的问题以做出进一步的筛选,或者给出它目前认为的答案。

6.数据库编辑器(知识库编辑脚本)给专家提供了更新知识的工具。

实现细节

面向对象

基于框架的专家系统适合用面向对象的方法来处理,Python支持面向对象的编程。

我定义了一个Pokemon class来作为它们的基本框架,并为它们的数据载入、初始化、确信因子的变化以及出局等操作提供了相关的方法。

Pokemon class支持继承,这可以用来分类和丰富Pokemon的特性。

不确定性管理

教材第3章提供了一种对基于规则的专家系统的不确定性管理方案:确信因子。我在这里把它用在了基于框架的专家系统中。

  • 用确信因子表达知识

    以皮卡丘知识为例,当我们在知识库中加入:

    "整体颜色" : {"黄色": "prob"}

    表示当用户给出了"整体颜色为黄色"这个事实后,皮卡丘的候选程度会与确信因子"prob"结合,得到一个新的候选程度,至于"prob"是多少由专家决定,我这里使用的是0.6。

  • 用确信因子表达用户对事实的相信程度

    在与用户的交流中,我给每个问题提供了三个选项:"是的","有一点","不是",确信因子分别为1.0, 0.6和-1.0,这样做的好处可以容忍用户对事实的一定程度上的不确定,提高专家系统的鲁棒性。

  • 确信因子的结合

    我采用教材第三章提供的公式来计算结合后的确信因子:

    CodeCogsEqn.gif

如何选择合适的问题

Pokemon的判断与筛选非常适合决策树这个模型。

这里我采用决策树的ID3算法来对问题进行选择。ID3算法的核心在于最大化信息增益,即最小的期望信息熵。

随机变量$S$的信息熵$E(S)=\sum -p_i\log p_i$

我们要做的是最小化$\sum_{v}^{}\frac{|S_v|}{|S|}E(S_v)$

这里有一个问题:如何估计$p_i$,即每个还在候选池里的Pokemon是答案的概率?

我采用的方法是设计一个函数,这个函数能完成确信因子到概率的转换,最终设计的函数长这样:

base是人为设定的一个参数,我给它设置成了100。

完成转换后,我们就能计算出相应的信息熵,从而对问题进行选择。

如何获取知识

关于Pokemon知识的来源可以见宝可梦百科

知识库的语法

由于该知识库规模较小,故用json作为数据存储就能满足专家系统对知识库操作的基本需求,并且比一般数据库操作更方便。

对于每个Pokemon,我们用一个字符型文件来描述。文件内容的最外层为一对"{"、"}",表示对象的定义。

对象的每个属性用"<属性名>" : { "<值1>" : "<确信因子1>", "值2" : "<确信因子2>" }...来表示。

  • 属性可以为空。例如: "尾巴颜色" : {} 意味着这个对象没有尾巴。
  • 属性的值可以冲突。以身体颜色为例,可能存在某个Pokemon,它的身体颜色介于红色和黄色之间,那么我们可以这样来描述: "整体颜色": {"红色": "mayb", "黄色": "mayb" },其中mayb代表着正面的但是程度较低的确信因子。
  • 属性可以继承。语法为: "继承": { "<被继承对象1>": "<归属度1>", "<被继承对象2>": "<归属度2>"...}。在载入知识库的时候,专家系统会自动处理继承属性,并与原属性结合。
  • "?" 语法。当属性值中存在"?"时,这意味着就算回答了与对象该属性相悖的答案,也不会降低这个Pokemon的确信程度,多用于难以判断/模糊的知识,这样做可以增强专家系统的鲁棒性。

知识库的操作

  • 用户可以直接修改data/*.json文件。

  • 用户可以调用DB_proc.py脚本,对知识库进行修改。

    命令行格式为:python DB_proc.py <name> <attr> <val> <CertaintyFactor>

    该操作会将name对象的attr属性添加一个CartaintyFactor的val值,如果已有val值则在原基础上修改。

关于对Pokemon的筛选

我给Pokemon类提供了is_out()函数,用来判定这个Pokemon是否出局,目前的判定方法是如果它的确信因子小于0.5超过两轮则认为出局。

这个条件并不是一成不变的,可以根据后续的需要来进行修改。

效果展示

界面展示

2018-01-08 23-47-21屏幕截图.png

交互展示

见DEMO-*.mp4文件,DEMO中测试了四只宝可梦:皮卡丘、妙蛙种子、阿柏怪和喵喵,均在8个问题内给出答案。

未来工作

  • 尝试加入更多的Pokemon的知识与框架。
  • 尝试利用NLP(自然语言处理)的方法来从Pokemon百科上提取结构化的知识,减少人工专家录入知识库的负担。
  • 尝试搭建该系统的web服务,免去python依赖。

附录

此项目的代码仓库:Github

宝可梦百科:Wiki