如何从experta库的规则引擎中提取规则。

huangapple go评论117阅读模式
英文:

how to extract the rules from rules engine of experta library

问题

我正在尝试从我使用experta库构建的规则引擎中提取规则。以下是代码:

from experta import *
import pydot

class Iris(Fact):
    """IRIS"""
    sepal_length = Field(float)
    sepal_width = Field(float)
    petal_length = Field(float)
    petal_width = Field(float)

class Species(Fact):
    """Species characteristics"""
    pass

class IrisExpert(KnowledgeEngine):

    def __init__(self):
        super().__init__()
        self.status = None

    @Rule(Iris(sepal_length=P(lambda x: x > 5), sepal_width=P(lambda x: x < 3)))
    def rule1(self):
        self.status = 'Iris Setosa'
        return self.declare(Species(flower='Iris Setosa'))

    @Rule(AND(
        Iris(sepal_length=P(lambda x: x > 5.5)),
        Iris(sepal_width=P(lambda x: x > 2.5))
    ))
    def rule2(self):
        self.status = 'Iris Versicolor'
        return self.declare(Species(flower='Iris Versicolor'))

    @Rule(AND(
        Iris(petal_length=P(lambda x: x > 4.8)),
        Iris(petal_width=P(lambda x: x > 1.8))
    ))
    def rule3(self):
        self.status = 'Iris Virginica'
        return self.declare(Species(flower='Iris Virginica'))

def execute_fuc(key):
    if key == 'rule1':
        print('executing rule-1')
        engine.rule1()
    elif key == 'rule2':
        print('executing rule-2')
        engine.rule2()
    else:
        print('executing rule-3')
        engine.rule3()

# Create a new knowledge engine instance
engine = IrisExpert()
engine.reset()
# Create a Pydot graph
graph = pydot.Dot(graph_type='digraph', comment='IRIS Expert Rules')
# Add nodes for each rule
for rule_instance in engine.get_rules():
    quality = rule_instance()
    qual_node = pydot.Node(repr(quality))
    graph.add_node(qual_node)
    for rule in rule_instance:
        print('rule_format: ', repr(rule))

我得到的输出格式如下:

rule_format: Iris(petal_width=P(<function IrisExpert.<lambda> at 0x7fe3fd4788c8>,))

但我正在寻找类似于以下格式的内容(用于"rule1"函数):

Iris(petal_width=P(lambda x: x > 5))

希望这对你有所帮助。

英文:

I am trying to extract the rules from the rules engine that I build using experta library.

Below is the code

from experta import *
import pydot
class Iris(Fact):
&quot;&quot;&quot;IRIS&quot;&quot;&quot;
sepal_length = Field(float)
sepal_width = Field(float)
petal_length = Field(float)
petal_width = Field(float)
class Species(Fact):
&quot;&quot;&quot;Species characteristics&quot;&quot;&quot;
pass
class IrisExpert(KnowledgeEngine):
def __init__(self):
super().__init__()
self.status = None
@Rule(Iris(sepal_length=P(lambda x: x &gt; 5), sepal_width=P(lambda x: x &lt; 3)))
def rule1(self):
self.status = &#39;Iris Setosa&#39;
return self.declare(Species(flower=&#39;Iris Setosa&#39;))
@Rule(AND(
Iris(sepal_length=P(lambda x: x &gt; 5.5)),
Iris(sepal_width=P(lambda x: x &gt; 2.5))
))
def rule2(self):
self.status = &#39;Iris Versicolor&#39;
return self.declare(Species(flower=&#39;Iris Versicolor&#39;))
@Rule(AND(
Iris(petal_length=P(lambda x: x &gt; 4.8)),
Iris(petal_width=P(lambda x: x &gt; 1.8))
))
def rule3(self):
self.status = &#39;Iris Virginica&#39;
return self.declare(Species(flower=&#39;Iris Virginica&#39;))
def execute_fuc(key):
if key == &#39;rule1&#39;:
print(&#39;executing rule-1&#39;)
engine.rule1()
elif key == &#39;rule2&#39;:
print(&#39;executing rule-2&#39;)
engine.rule2()
else:
print(&#39;executing rule-3&#39;)
engine.rule3()
# Create a new knowledge engine instance
engine = IrisExpert()
engine.reset()
# Create a Pydot graph
graph = pydot.Dot(graph_type=&#39;digraph&#39;, comment=&#39;IRIS Expert Rules&#39;)
# Add nodes for each rule
for rule_instance in engine.get_rules():
quality = rule_instance()
qual_node = pydot.Node(repr(quality))
graph.add_node(qual_node)
for rule in rule_instance:
print(&#39;rule_format: &#39;,repr(rule))

I am getting in the below format

rule_format: Iris(petal_width=P(&lt;function IrisExpert.&lt;lambda&gt; at 0x7fe3fd4788c8&gt;,))

But I am looking for something like

Iris(petal_width=P(&lt;function IrisExpert. x &gt; 5)) (for function &quot;rule1&quot;)

答案1

得分: 1

以下是代码部分的翻译:

你显然试图重新编写你的 lambda 函数的 `repr` 方法 [这个答案](https://stackoverflow.com/a/10875517/13525512) 展示了如何做到这一点应用到你的情况包括 &lt; 和 &gt; 的表示),你可以这样做

from experta import *
import pydot
import functools

class reprwrapper(object):
def init(self, repr, func):
self._repr = repr
self._func = func
functools.update_wrapper(self, func)
def call(self, *args, **kw):
return self._func(*args, **kw)
def repr(self):
return self._repr(self._func)

def withrepr(reprfun):
def _wrap(func):
return reprwrapper(reprfun, func)
return _wrap

def x_gt(a):
@withrepr(lambda x: f"function IrisExpert. x > {a}")
def gt_a(x):
return x > a
return gt_a

def x_lt(a):
@withrepr(lambda x: f"function IrisExpert. x < {a}")
def lt_a(x):
return x < a
return lt_a

class Iris(Fact):
"""IRIS"""
sepal_length = Field(float)
sepal_width = Field(float)
petal_length = Field(float)
petal_width = Field(float)

class Species(Fact):
"""Species characteristics"""
pass

class IrisExpert(KnowledgeEngine):

def __init__(self):
super().__init__()
self.status = None
@Rule(Iris(sepal_length=P(x_gt(5)), sepal_width=P(x_lt(3))))
def rule1(self):
self.status = 'Iris Setosa'
return self.declare(Species(flower='Iris Setosa'))
@Rule(AND(
Iris(sepal_length=P(x_gt(5.5))),
Iris(sepal_width=P(x_gt(2.5))
))
def rule2(self):
self.status = 'Iris Versicolor'
return self.declare(Species(flower='Iris Versicolor'))
@Rule(AND(
Iris(petal_length=P(x_gt(4.8))),
Iris(petal_width=P(x_gt(1.8))
))
def rule3(self):
self.status = 'Iris Virginica'
return self.declare(Species(flower='Iris Virginica'))

def execute_fuc(key):
if key == 'rule1':
print('executing rule-1')
engine.rule1()
elif key == 'rule2':
print('executing rule-2')
engine.rule2()
else:
print('executing rule-3')
engine.rule3()

创建一个新的知识引擎实例

engine = IrisExpert()
engine.reset()

创建一个 Pydot 图

graph = pydot.Dot(graph_type='digraph', comment='IRIS Expert Rules')

为每个规则添加节点

for rule_instance in engine.get_rules():
quality = rule_instance()
qual_node = pydot.Node(repr(quality))
graph.add_node(qual_node)
for rule in rule_instance:
print('rule_format: ', repr(rule))


输出:
```python
rule_format:  Iris(sepal_length=P(function IrisExpert. x > 5,), sepal_width=P(function IrisExpert. x < 3,))
rule_format:  AND(Iris(sepal_length=P(function IrisExpert. x > 5.5,)), Iris(sepal_width=P(function IrisExpert. x > 2.5,))
rule_format:  AND(Iris(petal_length=P(function IrisExpert. x > 4.8,)), Iris(petal_width=P(function IrisExpert. x > 1.8,))

<details>
<summary>英文:</summary>
You are apparently trying to rewrite the `repr` method of your lambda functions. [This answer](https://stackoverflow.com/a/10875517/13525512) shows how to do it. Applied to your case (both &lt; and &gt; representations), you could do the following:

from experta import *
import pydot
import functools

class reprwrapper(object):
def init(self, repr, func):
self._repr = repr
self._func = func
functools.update_wrapper(self, func)
def call(self, *args, **kw):
return self._func(*args, **kw)
def repr(self):
return self._repr(self._func)

def withrepr(reprfun):
def _wrap(func):
return reprwrapper(reprfun, func)
return _wrap

def x_gt(a):
@withrepr(lambda x: f"function IrisExpert. x > {a}")
def gt_a(x):
return x > a
return gt_a

def x_lt(a):
@withrepr(lambda x: f"function IrisExpert. x < {a}")
def lt_a(x):
return x < a
return lt_a

class Iris(Fact):
"""IRIS"""
sepal_length = Field(float)
sepal_width = Field(float)
petal_length = Field(float)
petal_width = Field(float)

class Species(Fact):
"""Species characteristics"""
pass

class IrisExpert(KnowledgeEngine):

def __init__(self):
super().__init__()
self.status = None
@Rule(Iris(sepal_length=P(x_gt(5)), sepal_width=P(x_lt(3))))
def rule1(self):
self.status = &#39;Iris Setosa&#39;
return self.declare(Species(flower=&#39;Iris Setosa&#39;))
@Rule(AND(
Iris(sepal_length=P(x_gt(5.5))),
Iris(sepal_width=P(x_gt(2.5)))
))
def rule2(self):
self.status = &#39;Iris Versicolor&#39;
return self.declare(Species(flower=&#39;Iris Versicolor&#39;))
@Rule(AND(
Iris(petal_length=P(x_gt(4.8))),
Iris(petal_width=P(x_gt(1.8)))
))
def rule3(self):
self.status = &#39;Iris Virginica&#39;
return self.declare(Species(flower=&#39;Iris Virginica&#39;))

def execute_fuc(key):
if key == 'rule1':
print('executing rule-1')
engine.rule1()
elif key == 'rule2':
print('executing rule-2')
engine.rule2()
else:
print('executing rule-3')
engine.rule3()

Create a new knowledge engine instance

engine = IrisExpert()
engine.reset()

Create a Pydot graph

graph = pydot.Dot(graph_type='digraph', comment='IRIS Expert Rules')

Add nodes for each rule

for rule_instance in engine.get_rules():
quality = rule_instance()
qual_node = pydot.Node(repr(quality))
graph.add_node(qual_node)
for rule in rule_instance:
print('rule_format: ',repr(rule))

Output:

rule_format: Iris(sepal_length=P(function IrisExpert. x > 5,), sepal_width=P(function IrisExpert. x < 3,))
rule_format: AND(Iris(sepal_length=P(function IrisExpert. x > 5.5,)), Iris(sepal_width=P(function IrisExpert. x > 2.5,)))
rule_format: AND(Iris(petal_length=P(function IrisExpert. x > 4.8,)), Iris(petal_width=P(function IrisExpert. x > 1.8,)))


</details>

huangapple
  • 本文由 发表于 2023年3月12日 18:58:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712638.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定