1.问题陈述

基于产生式规则的动物识别系统——识别虎、金钱豹、斑马、长颈鹿、鸵鸟、企鹅、信天翁等七种动物的产生式系统。
运用以下规则,设计实现一个小型动物识别系统。

R1: if 动物有毛发 then 动物是哺乳动物
R2: if 动物有奶 then 动物是哺乳动物
R3: if 动物有羽毛 then 动物是鸟
R4: if 动物会飞 and 会生蛋 then  动物是鸟
R5: if 动物吃肉 then 动物是食肉动物
R6: if 动物有犀利牙齿 and 有爪 and 眼向前方 then 动物是食肉动物
R7: if 动物是哺乳动物 and 有蹄 then 动物是有蹄类动物
R8: if 动物是哺乳动物 and 反刍 then 动物是有蹄类动物
R9: if 动物是哺乳动物 and 是食肉动物 and 有黄褐色 and 有暗斑点 then 动物是豹
R10:if 动物是哺乳动物 and 是食肉动物 and 有黄褐色 and 有黑色条纹 then 动物是虎
R11:if动物是有蹄类动物 and 有长脖子 and 有长腿 and 有暗斑点 then 动物是长颈鹿
R12:if 动物是有蹄类动物 and 有黑色条纹 then 动物是斑马
R13:if 动物是鸟 and 不会飞 and 有长脖子and有长腿 and有黑白二色 then 动物是鸵鸟
R14:if 动物是鸟 and 不会飞 and 会游泳 and 有黑白二色 then 动物是企鹅
R15:if 动物是鸟 and善飞 then 动物是信天翁

2.概要设计

2.1 规则库建立

根据规则,建立一知识库文件RD.txt,内容如下

有毛发 哺乳动物
有奶 哺乳动物
有羽毛 鸟
会飞 下蛋 鸟
吃肉 食肉动物
有犬齿 有爪 眼盯前方 食肉动物
哺乳动物 有蹄 有蹄类动物
哺乳动物 嚼反刍动物 有蹄类动物
哺乳动物 食肉动物 黄褐色 暗斑点 金钱豹
哺乳动物 食肉动物 黄褐色 黑色条纹 虎
有蹄类动物 长脖子 长腿 暗斑点 长颈鹿
有蹄类动物 黑色条纹 斑马
鸟 长脖子 长腿 黑白二色 不飞 鸵鸟
鸟 会游泳 不飞 黑白二色 企鹅
鸟 善飞 信天翁

2.2 实验原理

一个基于产生式规则专家系统的完整结构如图1。其中,知识库、推理机和工作存储器是构成专家系统的核心。系统的主要部分是知识库和推理机制,知识库由谓词演算事实和有关讨论主题的规则构成,推理机制由所有操纵知识库来演绎用户要求的信息的过程构成。


图1 一个基于产生式规则的专家系统的完整结构

2.3 绘制一图形化界面

本实验将使用Python中的PyQt5设计动物识别专家系统的界面,因本次系统设计重在产生式规则算法步骤的实现,所以不提及Qt界面的搭建。

图2 动物识别专家系统初始界面

图3 动物识别专家系统推理界面

3.关键算法

3.1 知识的获取


图4 由规则集形成的推理网络

3.2 算法步骤

3.2.1 首先将规则库里面的规则进行相应的排序和数据处理,以便之后的推理信息的匹配,此处将规则信息进行相应的拓扑排序,代码如下:
inn = []
for i in P:sum = 0for x in i:if Q.count(x) > 0:  # 能找到,那么sum += Q.count(x)inn.append(sum)
while (1):x = 0if inn.count(-1) == inn.__len__():breakfor i in inn:if i == 0:str = ' '.join(P[x])ans = ans + str + " " + Q[x] + "\n"  # 写入结果inn[x] = -1# 更新入度y = 0for j in P:if j.count(Q[x]) == 1:inn[y] -= 1y += 1x += 1
3.2.2 整理好规则库之后,我们开始进行推理功能的编写,在这里我们根据相应的规则匹配模式,对用户输入的需要推理的信息进行相应的判断,然后一步步的询问用户相关的规则信息,进行进一步的推理,直到完全匹配出推理信息。代码如下:
def go(self, flag=True):self.Q = []self.P = []fo = open('RD.txt', 'r', encoding='utf-8')for line in fo:line = line.strip('\n')if line == '':continueline = line.split(' ')self.Q.append(line[line.__len__() - 1])del (line[line.__len__() - 1])self.P.append(line)fo.close()print("go按钮按下")self.lines = self.textEdit.toPlainText()self.lines = self.lines.split('\n')  # 分割成组self.DB = set(self.lines)print(self.DB)self.str = ""print(self.str)flag = Truetemp = ""for x in self.P:  # 对于每条产生式规则if ListInSet(x, self.DB):  # 如果所有前提条件都在规则库中self.DB.add(self.Q[self.P.index(x)])temp = self.Q[self.P.index(x)]flag = False  # 至少能推出一个结论# print("%s --> %s" %(x, self.Q[self.P.index(x)]))self.str += "%s --> %s\n" % (x, self.Q[self.P.index(x)])if flag:  # 一个结论都推不出print("一个结论都推不出")for x in self.P:  # 对于每条产生式if ListOneInSet(x, self.DB):  # 事实是否满足部分前提flag1 = False       # 默认提问时否认前提for i in x:  # 对于前提中所有元素if i not in self.DB:  # 对于不满足的那部分btn = s.quest("是否" + i)if btn == QtWidgets.QMessageBox.Ok:self.textEdit.setText(self.textEdit.toPlainText() + "\n" + i)  # 确定则增加到textEditself.DB.add(i)  # 确定则增加到规则库中flag1 = True    # 肯定前提# self.go(self)if flag1:  # 如果肯定前提,则重新推导self.go()returnself.textEdit_2.setPlainText(self.str)print("----------------------")print(self.str)if flag:btn = s.alert("啥也推不出来!!!")# if btn == QtWidgets.QMessageBox.Ok:  # 点击确定#     self.textEdit.setText(self.textEdit.toPlainText() + "\n确定")else:self.lineEdit.setText(temp)
3.2.3 询问用户补充的推理信息进行进一步推理,代码如下:
def quest(self, info):QtWidgets.QMessageBox.move(self, 200, 200)button = QtWidgets.QMessageBox.question(self, "Question",self.tr(info),QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)return button

4.程序代码

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.setGeometry(100, 200, 623, 300)self.groupBox = QtWidgets.QGroupBox(Form)self.groupBox.setGeometry(QtCore.QRect(10, -20, 600, 311))self.groupBox.setTitle("")self.groupBox.setObjectName("groupBox")self.label = QtWidgets.QLabel(self.groupBox)self.label.setGeometry(QtCore.QRect(30, 40, 61, 18))self.label.setAlignment(QtCore.Qt.AlignCenter)self.label.setObjectName("label")self.label_2 = QtWidgets.QLabel(self.groupBox)self.label_2.setGeometry(QtCore.QRect(470, 40, 101, 18))self.label_2.setAlignment(QtCore.Qt.AlignCenter)self.label_2.setObjectName("label_2")self.pushButton = QtWidgets.QPushButton(self.groupBox)self.pushButton.setGeometry(QtCore.QRect(230, 35, 88, 27))self.pushButton.setObjectName("pushButton")self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)self.pushButton_2.setGeometry(QtCore.QRect(475, 190, 88, 27))self.pushButton_2.setObjectName("pushButton_2")self.pushButton_2.clicked.connect(self.btn2_click)self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)self.pushButton_3.setGeometry(QtCore.QRect(475, 240, 88, 27))self.pushButton_3.setObjectName("pushButton_3")self.pushButton_3.clicked.connect(QtCore.QCoreApplication.instance().quit)self.pushButton_4 = QtWidgets.QPushButton(self.groupBox)self.pushButton_4.setGeometry(475, 140, 88, 27)self.pushButton_4.setObjectName("pushButton_4")self.pushButton_4.clicked.connect(self.topological)self.textEdit = QtWidgets.QTextEdit(self.groupBox)self.textEdit.setGeometry(QtCore.QRect(20, 80, 80, 211))self.textEdit.setObjectName("textEdit")self.textEdit_2 = QtWidgets.QTextEdit(self.groupBox)self.textEdit_2.setGeometry(QtCore.QRect(110, 80, 331, 211))self.textEdit_2.setObjectName("textEdit_2")self.textEdit_2.setReadOnly(True)self.lineEdit = QtWidgets.QLineEdit(self.groupBox)self.lineEdit.move(460, 90)self.lineEdit.setReadOnly(True)self.pushButton.clicked.connect(self.go)self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def btn2_click(self):if self.pushButton_2.text() != "确定输入":self.pushButton_2.setText("确定输入")else:self.pushButton_2.setText("修改知识库")def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "动物识别专家系统by文坛"))self.label.setText(_translate("Form", "输入事实"))self.label_2.setText(_translate("Form", "显示推理结果"))self.pushButton.setText(_translate("Form", "进行推理"))self.pushButton_2.setText(_translate("Form", "修改知识库"))self.pushButton_3.setText(_translate("Form", "退出程序"))self.pushButton_4.setText(_translate("From", "整理知识库"))# 将知识库做拓扑排序def topological(self):Q = []P = []ans = ""  # 排序后的结果for line in open('RD.txt'):line = line.strip('\n')if line == '':continueline = line.split(' ')Q.append(line[line.__len__() - 1])del (line[line.__len__() - 1])P.append(line)# 计算入度inn = []for i in P:sum = 0for x in i:if Q.count(x) > 0:  # 能找到,那么sum += Q.count(x)inn.append(sum)while (1):x = 0if inn.count(-1) == inn.__len__():breakfor i in inn:if i == 0:str = ' '.join(P[x])ans = ans + str + " " + Q[x] + "\n"  # 写入结果inn[x] = -1# 更新入度y = 0for j in P:if j.count(Q[x]) == 1:inn[y] -= 1y += 1x += 1print(ans)# 将结果写入文件fw = open('RD.txt', 'w', buffering=1)fw.write(ans)fw.flush()fw.close()# 进行推理def go(self, flag=True):# 将产生式规则放入规则库中# if P then Q# 读取产生式文件self.Q = []self.P = []fo = open('RD.txt', 'r', encoding='utf-8')for line in fo:line = line.strip('\n')if line == '':continueline = line.split(' ')self.Q.append(line[line.__len__() - 1])del (line[line.__len__() - 1])self.P.append(line)fo.close()print("go按钮按下")self.lines = self.textEdit.toPlainText()self.lines = self.lines.split('\n')  # 分割成组self.DB = set(self.lines)print(self.DB)self.str = ""print(self.str)flag = Truetemp = ""for x in self.P:  # 对于每条产生式规则if ListInSet(x, self.DB):  # 如果所有前提条件都在规则库中self.DB.add(self.Q[self.P.index(x)])temp = self.Q[self.P.index(x)]flag = False  # 至少能推出一个结论self.str += "%s --> %s\n" % (x, self.Q[self.P.index(x)])if flag:  # 一个结论都推不出print("一个结论都推不出")for x in self.P:  # 对于每条产生式if ListOneInSet(x, self.DB):  # 事实是否满足部分前提flag1 = False       # 默认提问时否认前提for i in x:  # 对于前提中所有元素if i not in self.DB:  # 对于不满足的那部分btn = s.quest("是否" + i)if btn == QtWidgets.QMessageBox.Ok:self.textEdit.setText(self.textEdit.toPlainText() + "\n" + i)  # 确定则增加到textEditself.DB.add(i)  # 确定则增加到规则库中flag1 = True    # 肯定前提if flag1:  # 如果肯定前提,则重新推导self.go()returnself.textEdit_2.setPlainText(self.str)print("----------------------")print(self.str)if flag:btn = s.alert("啥也推不出来!!!")else:self.lineEdit.setText(temp)
# 判断list中至少有一个在集合set中
def ListOneInSet(li, se):for i in li:if i in se:return Truereturn False
# 判断list中所有元素是否都在集合set中
def ListInSet(li, se):for i in li:if i not in se:return Falsereturn True
class SecondWindow(QtWidgets.QWidget):def __init__(self, parent=None):super(SecondWindow, self).__init__(parent)self.setWindowTitle("修改知识库")self.setGeometry(725, 200, 300, 300)self.textEdit = QtWidgets.QTextEdit(self)self.textEdit.setGeometry(8, 2, 284, 286)# 警告没有推导结果def alert(self, info):QtWidgets.QMessageBox.move(self, 200, 200)QtWidgets.QMessageBox.information(self, "Information", self.tr(info))# 询问补充事实def quest(self, info):# 如果推理为空,需要询问用户是否要添加已知条件QtWidgets.QMessageBox.move(self, 200, 200)button = QtWidgets.QMessageBox.question(self, "Question",self.tr(info),   QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel,QtWidgets.QMessageBox.Cancel)return buttondef handle_click(self):if not self.isVisible():# 读取文件放到多行文本框中str = ""fo = open('RD.txt', 'r', encoding='utf-8')for line in fo:line = line.strip('\n')if line == '':continuestr = str + line + "\n"fo.close()self.textEdit.setText(str)self.show()else:# 输出文本框内容self.str = self.textEdit.toPlainText()print(self.str)# 将文本框内容写入文件self.fw = open('RD.txt', 'w')self.fw.write(self.str)self.fw.close()  # 关闭文件self.close()  # 关闭窗口def handle_close(self):self.close()
if __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)widget = QtWidgets.QWidget()ui = Ui_Form()ui.setupUi(widget)widget.show()s = SecondWindow()ui.pushButton_2.clicked.connect(s.handle_click)sys.exit(app.exec_())

5.运行结果与测试

5.1 测试数据1

输入'有奶'推出'哺乳动物',此例正确

图 5 成功测试数据 1 运行结果

5.2 测试数据2

输入'鸟', '长脖子', '长腿', '黑白二色', '不飞' =>推出‘鸵鸟’,复杂示例正确
图 6 成功测试数据 2运行结果

5.3 测试数据3

输入'不飞', '黑白二色', '长腿' ,'会游泳', '长脖子',推不出任何动物,此例错误 ![在这里插入图片描述]
图 7 失败测试数据 3运行结果

6.设计体会与总结

6.1.1 遇到的问题

在本次实验中最大的问题就是第一步对于规则库的信息的整理和之后如何在匹配这些规则,开始使用了元组和集合,但是都难以进行多次匹配,于是想到了Python本身的字典的“键值对”属性,并且参考了相关文献,对信息做了拓扑排序。

6.1.2 如何解决

首先,对规则信息通过字典的格式存入相应的“RD.txt”文件中,然后对当中的信息进行相应的拓扑排序。

6.2本次实验的体会

6.2.1 结论

本次实验项目,通过pyqt5Eric6自动生成用户交互页面,体现了Python在前台的优势,同时整体的代码量比起用C/C++而言,大大减少,体现了Python在编写专家系统的优势。

6.2.2体会与项目优化

在后期查看相应查看大量有关专家系统的文件中,个人认为可以结合知识图谱来构建一个大型的动物专家系统的识别,我们可以通过复旦大学的知识工厂的相应的知识库构建相应的知识图谱,结合MongoDB数据库以及知识图谱的数据库,来构建一个更智能更全面的的动物识别的专家系统。当然所花的时间和精力也是非常巨大的!

基于Python的动物识别专家系统相关推荐

  1. python编写的动物识别专家系统_基于Python的动物识别专家系统

    1. 利用pyqt5来设计专家系统的界面. 如下图一: 图一 起始界面 相应的运行过程的界面,如图二: 图二 相应的运行过程界面 2. 设置规则文本 guizhe.txt 有毛发 哺乳动物 有奶 哺乳 ...

  2. python是哪种动物_基于Python的动物识别专家系统

    1. 利用pyqt5来设计专家系统的界面. 如下图一: 图一 起始界面 相应的运行过程的界面,如图二: 图二 相应的运行过程界面 2. 设置规则文本 guizhe.txt 有毛发 哺乳动物 有奶 哺乳 ...

  3. 动物识别专家系统PYTHON

    能搜到这个文章的,估计你就是为了想找篇现成的系统抄抄了,我也废话不多说好叭. 下面这些是我们当时的要求和加分项: 1.建立一个动物识别系统的规则库,用以识别虎.豹.斑马.长颈鹿.企鹅.鸵鸟.信天翁等7 ...

  4. 动物识别系统代码python_人工智能-动物识别专家系统算法Python + Pyqt 实现

    #-*- coding: utf-8 -*- #Form implementation generated from reading ui file '动物识别专家系统.ui'# #Created b ...

  5. python动物专家系统_动物识别专家系统 实验报告

    学 号 XXXXX 姓 名 XXXXX 实验名称 动物识别专家系统 实验目的 本实验的主要目的是熟练使用推理方法, 进行编程完成相应的功 能. 本次试验的预期功能是在系统可以像使用者提出问题, 然后系 ...

  6. 动物识别系统代码python_动物识别专家系统课程设计

    title: 动物识别专家系统课程设计 date: 2017-12-23 18:44:13 tags: categories: python 设计一个可以识别7种动物的专家系统,可以根据前提推导出结论 ...

  7. JavaScript 实现动物识别专家系统交互演示

    本文首发且更新于个人博客: https://www.xerrors.fun/Animal-Identification-Expert-System/ 前言:本篇文章主要是介绍什么是专家系统,接下来会使 ...

  8. 基于产生式规则的动物识别系统

    基于产生式规则的动物识别系统 先放效果图 控制台 推理失败截图: 推理成功截图: MFC 推理失败截图: 推理成功界面: 实验目的: 熟悉一阶谓词逻辑和产生式表示法,掌握产生式系统的运行机制,以及基于 ...

  9. 动物识别专家系统 Java 简单实现

    不再BB什么是专家系统了,自行百度,这篇博客专门帮助写作业的,人工智能导论课要求写一个动物识别专家系统,这就是一个很好的实现,编了2天,有界面,有功能,分享给需要的同学. 直接上源代码,开箱即用,包括 ...

最新文章

  1. HI3519V101调试记录
  2. python exec
  3. python对笔记本电脑的要求-如何用Python在笔记本电脑上分析100GB数据(上)
  4. 【Qt】打开现有 Qt 项目 ( 打开已存在的项目 | 运行打开的项目 )
  5. 全球多媒体视频内容保护最佳实践
  6. qt5.11 linux oracle,Qt5.11.1 + VS2017环境搭建(Qt5.11在windows上的安装)
  7. 【cGAN】conditional生成对抗网络--有代码
  8. 如何安装redmine插件
  9. vue混合开发笔记, this的指向
  10. 西瓜书+实战+吴恩达机器学习(十六)半监督学习(半监督SVM、半监督k-means、协同训练算法)
  11. [论文翻译] Visual Saliency Transformer
  12. 华为5g鸿蒙麒麟,华为5G亮王牌:鸿蒙系统+7800W+麒麟990+防水,钱包按耐不住!
  13. 「Algospot」量化QUANTIZE
  14. 网众远程修改ip、dns
  15. jsp中java代码、jsp代码、js代码执行的顺序
  16. 微信小程序简单爱心点赞动画
  17. java xlsm_在Java中使用POI框架读取xlsm文件时出错
  18. 微博SDK第三方授权登陆
  19. Effective_go_Notes
  20. 正序,负序,零序分量的产生与计算

热门文章

  1. R语言入门(21)-数据框的数据处理以及数学计算
  2. 关于Allegro 16X版本,铺铜卡死问题的一个可行解决方案
  3. 兄弟我在义乌的发财史读后
  4. 一个ping大包不通问题的解决过程
  5. 宝塔Nginx配置Mediawiki短链接
  6. python设计模式(1)前言
  7. 仿驾考宝典 驾考软件
  8. FPGA通信第三篇--TCP
  9. Android N来电拦截
  10. QT连接SQLServer并添加ODBC数据源