推理引擎根据内部规则计算匹配集
-
04-10-2019 - |
题
我有一组具有属性和一堆规则的对象,当应用于对象集时,它们提供了这些对象的子集。为了使这更容易理解,我将提供一个具体的示例。
我的对象是人,每个人都有三个属性:原籍国,性别和年龄段(所有属性都是离散的)。我有一堆规则,例如“来自美国的所有男性”,与此较大对象集的子集相对应。
我正在寻找现有的Java“推理引擎”或类似的东西,这些引擎将能够从规则映射到一部分人,也可以就如何创建自己的建议。我已经阅读了规则引擎,但是该术语似乎仅用于外部化业务规则的专家系统,通常不包含任何高级推断形式。以下是我必须处理的更复杂情况的一些示例:
我需要规则的结合。因此,当两者都呈现“包括所有男性”和“排除10-20岁年龄段的美国所有人”时,我只对美国以外的男性以及美国境外的男性感兴趣。 20岁年龄段。
规则可能具有不同的优先级(明确定义)。因此,一条说“排除所有男性”的规则将覆盖一条规则,说“包括所有美国男性”。
规则可能是矛盾的。因此,我可以既有“包括所有男性”,又可以将所有男性排除在外,在这种情况下,优先事项将不得不解决这个问题。
规则是对称的。因此,“包括所有男性”等同于“排除所有女性”。
规则(或更确切地说的子集)可能具有与之关联的元规则(明确定义)。在任何情况下应用原始规则,或者通过推断达到子集,都必须应用这些元规则。因此,如果将“排除美国”的元规则附在规则上“包括所有男性”,而我为引擎提供规则“排除所有女性”,则应该能够推断“排除所有女性”子集等同于“包含所有男性”子集,因此另外应用了“排除美国”规则。
我可以在没有项目5的情况下活下来,但是我确实需要提到的所有其他属性。我的规则和对象都存储在数据库中,并且可以在任何阶段进行更新,因此我需要在需要时实例化“推理引擎”,然后将其销毁。
解决方案
Java有一堆嵌入式序言式的SLD求解器;我最喜欢的方法是使用 Scala的迷你kanren, ,因为这很干净,并且允许您使用Scala懒惰地处理查询结果,但我没有深入使用它。看 Java的嵌入式Prolog口译/编译器 对于其他选项,以及罗斯的答案。
SLD求解器处理您的所有标准,只要它们具有Prolog具有的一些额外功能:
- 规则的结合:基本SLD目标处理;
- 规则可能具有不同的优先级:Prolog的削减规则可以代表否定,只要查询是可决定的;
- 规则可能是矛盾的:同样,如果满足更高的优先级目标,则可以确保不应用较低的优先级子句。有几种方法可以做到这一点。
- 规则是对称的:剪切,这很容易确保可确定的谓词。
- 规则(或更确切地说的子集)可能具有与之关联的元规则(明确定义):您的示例似乎表明这相当于4,因此我不确定我在这里得到了您的想法。
SLD求解器的优势和缺点以说明基于逻辑的工具是:
- 程序化功率,灵活性:您通常可以找到建模困难的编程解决方案,其中描述逻辑可能需要您重新考虑模型。但是当然,没有管道录像带意味着描述逻辑解决方案迫使您保持清洁,这可能是一门很好的纪律。
- 鲁棒性:SLD求解器是一项非常了解的技术,而描述逻辑工具通常比博士学位论文出生的步骤不多。
- 缺乏语义工具:描述逻辑与一阶逻辑和模型逻辑具有良好的链接,并为您提供了非常丰富的技术来推理它们。序言的灵活性通常会非常困难。
如果您没有描述逻辑方面的特殊专业知识,我建议使用SLD求解器。
其他提示
我相信你可以使用 ID3算法 从对象的初始状态中提取一组规则。我不知道任何具体的Java实现,尽管Wikipedia指出了从Ruby到C的不同实现(我不能发布超过一个超链接:-)),但这并不是很难学习的算法。
一旦构建了决策树,可以以规则格式表达,您可以使用它来查看您的对象所属的类别:从美国的所有男性,到10到20的所有女性,以及某人更新时您的对象在数据库中,您可以重建决策树。
好的,这可能是一个愚蠢的答案。但是我无论如何都会尝试....您可以使用beanshell做这样的事情:
创建一个简单的Selector命令(类似Select(inicialSet,paramname,paramvalue)),该命令返回inicialSet中的设置元素并匹配您的参数。
创建一些可以帮助您编写漂亮Beanshell脚本的常数。
这样,您可以将规则写成简单的脚本和巢规则。
所以这
我需要规则的结合。因此,当两者都呈现“包括所有男性”和“排除10-20岁年龄段的美国所有人”时,我只对美国以外的男性以及美国境外的男性感兴趣。 20岁年龄段。
将成为这样的脚本:
originalSet = getOriginalSet(); //Get all from DB
//elements in originalSet that have gender=male
males = select(originalSet, PARAM.GENDER, GENDER.MALE);
//elements in males that have age in [10,20]
youngMaleGuys = select(males, PARAM.AGE, AGE.10_20);
//Exclude from
males.removeAll(youngMaleGuys);
notYoungUSMaleGuys = select(males, PARAM.COUNTRY, COUNTRY.US);
males.removeAll(notYoungUSMaleGuys);
return resp;
当然,这很糟糕。我现在做到了。但是您可以编写非常好的命令,并找到一种使其更可读的方法。
不是那么快,但是很容易曼丹和阅读(我认为)。而且您不必担心订购
就是这样。我试过。 :)
JBOSS DROORS是最强大的基于Java的生产规则引擎(推理引擎)。
老实说,除非您的应用程序变得更加复杂,否则使用规则引擎是过度的。另一方面,如果您的应用程序太大并且规则太多,那么它将无法提供结果。
如果您可以更好地控制客户或问题域,最好完全避免推理引擎。