**基于产生式规则的动物识别系统正反向混合推理(Python)**
产生式系统 把一组领域相关的产生式(或称规则)放在一起,让它们互相配合、协同动作,一个产生式生成的结论一般可供另一个(或一些)产生式作为前提或前提的一部分来使用,以这种方式求得问题之解决,这样的一组产生式被称为产生式系统
产生式系统的构成
一组规则
每条规则分为左部(或称前提、前件)和右部(或称结论、动作、后件)。通常左部表示条件,核查左部条件是否得到满足一般采用匹配方第 3 页法,即查看数据基DB(Data Base)中是否存在左部所指明的情况,若存在则认为匹配成功,否则认为匹配失败。一般说来,匹配成功则执行右部所规定的动作,例如:添加、修改和删除等。
数据基
DB 中存放的数据既是产生式作用的对象,又是构成产生式(或称规则)的基本元素。
一个推理程序(Engine)
它负责整个产生式系统的运行,包括:规则左部与 DB 匹配;从匹配成功的规则中,选出一条将在下一步执行的规则 R*,执行 R*右部规定的动作;掌握时间结束产生式系统的运行。
知识库 【**基于产生式规则的动物识别系统正反向混合推理(Python)**】R1: 如果 某动物有毛发(F1)则 该动物是哺乳动物(M1)
R2: 如果 某动物有奶(F2)则 该动物是哺乳动物(M1)
R3: 如果 某动物有羽毛(F3)则 该动物是鸟(M4)
R4: 如果 某动物会飞(F4),且下蛋(F5)则 该动物是鸟(M4)
R5: 如果 某动物吃肉(F6)则 该动物是食肉动物(M2)
R6: 如果 某动物有锋利的牙齿(F7),且有爪(F8),且眼睛盯着前方(F9)则 该动物是食肉动物(M2)第 10 页
R7: 如果 某动物是哺乳动物(M1),且有蹄(F10)则 该动物是有蹄类哺乳动物(M3)
R8: 如果 某动物是哺乳动物(M1),且反刍(F11)则 该动物是有蹄类哺乳动物(M3),且偶蹄类
R9: 如果 某动物是哺乳动物(M1),且是食肉动物(M2) ,且黄褐色(F12),且有暗班(F13)则 该动物是豹(H1)
R10:如果 某动物是哺乳动物(M1),且是食肉动物(M2),且黄褐色(F12),且有黑色条纹(F14)则 该动物是虎(H2)
R11:如果 某动物是有蹄类哺乳动物(M3),且有长脖(F15),且有长腿(F16),且有暗斑(F13)则 该动物是长颈鹿(H3)
R12:如果 某动物是有蹄类哺乳动物(M3),且有黑条纹(F14)
则 该动物是斑马(H4)
R13:如果 某动物是鸟(M4), 且不会飞(F17),且有长脖子(F15),且有长腿(F16),且是黑白色(F18)则 该动物是鸵鸟(H5)
R14:如果 某动物是鸟(M4),且不会飞(F17),且会游泳(F19), 且是黑白色(F18)则 该动物是企鹅(H6)
R15:如果 某动物是鸟(M4),且善飞(F20)则 该动物是信天翁(H7)
文章图片
正向推理: 在产生式系统运行过程中,要不断地用 GDB 中的数据和产生式进行匹配。正向推理一定能推理出问题的结果,但是正向推理过程在推理过程中比较盲目,可能会执行向很多无用的方向探索,类似于宽度优先搜索,当搜索结构比较深时,还可能产生指数爆炸。
反向推理: 向后(反向,逆向,反向链, 目标驱动)推理时,要把子目标和GDB 中的数据或产生式右部匹配。与数据匹配成功者生成叶节点;与
产生式右部匹配成功者,则使该产生式左部成为新的子目标。反向推理也一定能找到目标,并且在寻找目标时候目的性很强,类似于深度优先搜索。但是这个过程依赖于初始目标的选择,算法的优劣性取决于初始目标选择的好坏。
混合推理: 算法描述:
算法初始给定每个层次一个深度,最底层为1,依次向上递增,首先选出深度最小的一些属性,通过改进的正向搜索(不考虑与或关系,只要能向底层搜索就一直搜索,直到目标),每次搜索到目标,就给该目标的反向搜索优先级加一。然后根据目标优先级执行反向搜索直到推理出结果。
混合推理算法步骤:
S为初始GDB,H记录了每个属性的深度,R为规则集,G为目标集
1:从S中搜索出最小深度h
2:对于S中最先深度的属性通过改进的正向推理,计算出目标集反向推理的优先级
3:根据计算的优先级依次进行反向推理,直到推理出结果
import pandas as pd
import numpy as np
# encoding=utf8
#code by miao 2020.3.21
class Animal():
def __init__(self):
self.dict_before = {'1': '有毛发', '2': '产奶', '3': '有羽毛', '4': '会飞', '5': '会下蛋', '6': '吃肉', '7': '有犬齿',
'8': '有爪', '9': '眼盯前方', '10': '有蹄', '11': '反刍', '12': '黄褐色', '13': '有斑点', '14': '有黑色条纹',
'15': '长脖', '16': '长腿', '17': '不会飞', '18': '会游泳', '19': '黑白二色', '20': '善飞', '21': '哺乳类',
'22': '鸟类', '23': '食肉类', '24': '蹄类', '25': '金钱豹', '26': '虎', '27': '长颈鹿', '28': '斑马',
'29': '鸵鸟', '30': '企鹅', '31': '信天翁'}
print('''输入对应条件前面的数字:
*******************************************************
*1:有毛发2:产奶3:有羽毛4:会飞5:会下蛋*
*6:吃肉7:有犬齿8:有爪9:眼盯前方10:有蹄*
*11:反刍12:黄褐色13:有斑点14:有黑色条纹15:长脖 *
*16:长腿17:不会飞18:会游泳19:黑白二色20:善飞*
*21:哺乳类22:鸟类23:食肉类24:蹄类*
*******************************************************
*******************当输入数字0时!程序结束***************
''')
# 各个特征的深度
self.dict_depth = {'1': 3, '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, '10': 3, '11': 3, '12': 2,
'13': 2, '14': 2, '15': 2, '16': 2,
'17': 2, '18': 2, '19': 2, '20': 2, '21': 2, '22': 2, '23': 2, '24': 2, '25': 1, '26': 1, '27': 1,
'28': 1, '29': 1, '30': 1, '31': 1}
# 规则集
self.rules = [[[1], 21], [[2], 21], [[3], 22], [[6], 23], [[4, 5], 22], [[7, 8, 9], 23], [[10, 21], 24], [[11, 21], 24],
[[12, 23, 14, 21], 26],
[[13, 15, 16, 24], 27], [[12, 13, 21, 23], 25], [[14, 24], 28], [[15, 17, 19, 22], 29],
[[17, 18, 19, 22], 30], [[20, 22], 31]]
# 动物逆向推理优先级
self.count = {'25': 0, '26': 0, '27': 0,'28':0,'29': 0 ,'30': 0 ,'31':0 }
# 综合数据库
self.list_real = []
self.list=[]
while (1):
# 循环输入前提条件所对应的字典中的键
num_real = input("请输入:")
if (num_real == '0'):
break
self.list_real.append(num_real)
self.list.append(num_real)
#print("\n")
print("前提条件为:")
# 输出前提条件
for i in range(0, len(self.list_real)):
print(self.dict_before[self.list_real[i]], end=" ")
print("\n")
print("推理结果如下:")
# 求深度最小的进行改进的正向推演
def min_depth(self):
h = 100
for i in range(len(self.list_real)):
if (h > int(self.dict_depth[self.list_real[i]])):
h = int(self.dict_depth[self.list_real[i]])
return h
# 判断是否与数据基的数重复
def judge_repeat(self, value):
for i in range(0, len(self.list_real)):
if (self.list_real[i] == str(value)):
return 1
else:
m=len(self.list_real)
if (i != len(self.list_real) - 1):
continue
else:
return 0
# 进行改进的正向推理
def forward(self, h):
for j in range(len(self.list_real)):
if(int(self.dict_depth[self.list_real[j]]) == 2):
for i in range(len(self.rules)):
if (int(self.list_real[j]) in self.rules[i][0]):
if (self.rules[i][1] in range(25, 32)):
self.count[str(self.rules[i][1])] = self.count[str(self.rules[i][1])] + 1
if (self.judge_repeat(self.rules[i][1]) == 0):
self.list_real.append(str(self.rules[i][1]))
# 在正向推理的基础上进行逆向推理
def backward(self, a):
change = False
for i in range(len(self.rules)):
if (a == self.rules[i][1]):
for j in range(len(self.rules[i][0])):
change = False
m=self.rules[i][0][j]
if (str(self.rules[i][0][j]) in self.list):
change = True
if(j==len(self.rules[i][0])-1):
return change
else:
change=self.backward(int(self.rules[i][0][j]))
if(not change):
break;
return change
#算法框架
def run(self):
self.forward(self.min_depth())
self.count = sorted(self.count.items(), key=lambda d: d[1], reverse=True)
for i in range(len(self.count)):
if (self.backward(int(self.count[i][0]))):
print("推理此动物为:", self.dict_before[str(self.count[i][0])])
return
print("无法推理此动物")
return
#主函数
if __name__ == '__main__':
anmial = Animal()
anmial.run()
运行结果 1)无法推理出动物种类
文章图片
2)能推理出此动物种类
文章图片
::
文章图片
第一次写博客,这是学校课程的一次课后作业,也不知道写的对不对,编码能力太菜,想慢慢锻炼,写的不太行请见谅!
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- mybatisplus|mybatisplus where QueryWrapper加括号嵌套查询方式
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 视频转换器哪种好用()
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- 与狗狗的相处公式
- 康德式公平倾向
- 基于爱,才会有“愿望”当“要求”。2017.8.12
- 种树郭橐驼传(文言句式+古今异义+词类活用+通假字)