基于Python的动物识别专家系统--20180515人工智能作业
参考链接:https://www.cnblogs.com/lepeCoder/p/8094136.html
实验目的:
设计一个可以识别7种动物的专家系统,可以根据前提推导出结论,如果只有部分前提,询问提示
实验内容:
1. 利用pyqt5来设计专家系统的界面。
如下图一:
图一 起始界面
相应的运行过程的界面,如图二:
图二 相应的运行过程界面
2. 设置规则文本 guizhe.txt
有毛发 哺乳动物
有奶 哺乳动物
有羽毛 鸟
会飞 下蛋 鸟
吃肉 食肉动物
有犬齿 有爪 眼盯前方 食肉动物
哺乳动物 有蹄 有蹄类动物
哺乳动物 嚼反刍动物 有蹄类动物
哺乳动物 食肉动物 黄褐色 暗斑点 金钱豹
哺乳动物 食肉动物 黄褐色 黑色条纹 虎
有蹄类动物 长脖子 长腿 暗斑点 长颈鹿
有蹄类动物 黑色条纹 斑马
鸟 长脖子 长腿 黑白二色 不飞 鸵鸟
鸟 会游泳 不飞 黑白二色 企鹅
鸟 善飞 信天翁
3. 编写思路
1)首先将规则库里面的规则进行相应的排序和数据处理,以便之后的推理信息的匹配,在这里我们将规则信息进行相应的拓扑排序,代码如下:
inn = []
for i in P:
sum = 0
for x in i:
if Q.count(x) > 0: # 能找到,那么
sum += Q.count(x)
inn.append(sum)
while (1):
x = 0
if inn.count(-1) == inn.__len__():
break
for i in inn:
if i == 0:
str = ' '.join(P[x])
# print("%s %s" %(str, Q[x]))
ans = ans + str + " " + Q[x] + "\n" # 写入结果
# print("%s -- %s" %(P[x],Q[x]))
inn[x] = -1
# 更新入度
y = 0
for j in P:
if j.count(Q[x]) == 1:
inn[y] -= 1
y += 1
x += 1
2)整理好规则库之后,我们开始进行推理功能的编写,在这里我们根据相应的规则匹配模式,对用户输入的需要推理的信息进行相应的判断,然后一步步的询问用户相关的规则信息,进行进一步的推理,直到完全匹配出推理信息。代码如下:
def go(self, flag=True):
self.Q = []
self.P = []
fo = open('guizhe.txt', 'r', encoding='utf-8')
for line in fo:
line = line.strip('\n')
if line == '':
continue
line = 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 = True
temp = ""
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) # 确定则增加到textEdit
self.DB.add(i) # 确定则增加到规则库中
flag1 = True # 肯定前提
# self.go(self)
if flag1: # 如果肯定前提,则重新推导
self.go()
return
self.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)询问用户补充的推理信息进行进一步推理,代码如下:
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. 代码的优化处理
在编写的过程中,我们参考了相关的文献资料,思考是否可以通过更新规则库来扩展系统可识别的动物的数量,从而使得系统更加完善。于是在原基础上,通过参考大牛的代码,增添了“修改规则库”和“整理规则库”两个功能。代码如下:
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)
实验过程中遇到的问题如何解决的?
1. 遇到的问题
在本次实验中最大的问题就是第一步对于规则库的信息的整理和之后如何在匹配这些规则,开始使用了元组和集合,但是都难以进行多次匹配,于是想到了Python本身的字典的“键值对”属性,并且参考了相关文献,对信息做了拓扑排序。
2. 如何解决
首先,对规则信息通过字典的格式存入相应的“guizhe.txt”文件中,然后对当中的信息进行相应的拓扑排序。
本次实验的体会(结论)
1. 结论
本次实验项目,通过pyqt5与Eric6自动生成用户交互页面,体现了Python在前台的优势,同时整体的代码量比起用C/C++而言,大大减少,体现了Python在编写专家系统的优势。
2. 体会与项目优化
在后期查看相应查看大量有关专家系统的文件中,个人认为可以结合知识图谱来构建一个大型的动物专家系统的识别,我们可以通过复旦大学的知识工厂的相应的知识库构建相应的知识图谱,结合MongoDB数据库以及知识图谱的数据库,来构建一个更智能更全面的的动物识别的专家系统。当然所花的时间和精力也是非常巨大的!