推理引擎根据内部规则计算匹配集

Posted

技术标签:

【中文标题】推理引擎根据内部规则计算匹配集【英文标题】:Inference engine to calculate matching set according to internal rules 【发布时间】:2011-02-23 06:12:56 【问题描述】:

我有一组具有属性的对象和一堆规则,当应用于这组对象时,这些规则提供了这些对象的一个​​子集。为了更容易理解,我将提供一个具体的例子。

我的对象是人,每个人都有三个属性:原籍国、性别和年龄组(所有属性都是离散的)。我有一堆规则,比如“所有来自美国的男性”,它们对应于这个更大对象集的子集。

我正在寻找一个现有的 Java“推理引擎”或类似的东西,它能够从规则映射到一个人的子集,或者关于如何创建我自己的建议。我已经阅读了规则引擎,但该术语似乎专门用于将业务规则外部化的专家系统,并且通常不包括任何高级形式的推理。以下是我必须处理的更复杂场景的一些示例:

    我需要规则的结合。因此,当同时出现“包括所有男性”和“排除 10 至 20 岁年龄段的所有美国人”时,我只对美国以外的男性以及美国境内 10 至 20 岁以下的男性感兴趣。 20 岁年龄段。

    规则可能有不同的优先级(明确定义)。因此,“排除所有男性”的规则将覆盖“包括所有美国男性”的规则。

    规则可能有冲突。所以我可以同时设置“包括所有男性”和“排除所有男性”,在这种情况下,必须优先解决问题。

    规则是对称的。所以“包括所有男性”相当于“排除所有女性”。

    规则(或更确切地说是子集)可能具有与之关联的元规则(明确定义)。在应用原始规则或通过推理达到子集的任何情况下,都必须应用这些元规则。因此,如果“排除美国”的元规则附加到“包括所有男性”规则,并且我为引擎提供“排除所有女性”规则,它应该能够推断出“排除所有女性”子集相当于“包括所有男性”子集,因此另外应用“排除美国”规则。

我很可能没有第 5 项,但我确实需要提到的所有其他属性。我的规则和对象都存储在数据库中,并且可以在任何阶段更新,因此我需要在需要时实例化“推理引擎”并在之后销毁它。

【问题讨论】:

数据是否在 RDBMS 中?为什么不在数据级别尝试呢?听起来你更像是我需要一个报告工具。 数据在 RDBMS 中,是的,但我不确定报告工具是否足够。我的经验很少,但似乎复杂性加上实时使用而不是报告会使它不可行? 我认为您可以在业务分析方面做更多的工作。从您的描述中,我看到将业务需求翻译成技术术语的效果不佳 - 例如:“因此,“排除所有男性”的规则将覆盖“包括所有美国男性”的规则。 - 这可以解释为单一规则“排除美国以外的所有男性”,并且在任何运行规则引擎的权力范围内。我建议你阅读一些关于 NLP 和形式逻辑的内容。最后一件事 - 避免优先事项,就像瘟疫一样,这是最简单的最终导致无法维护的混乱的方式。订购也很糟糕,但没有那么糟糕。 显然,在 *** 上以易于理解的方式传递业务需求是很困难的,但我相信我们对需求有很好的理解。当然,任何规则引擎都可以处理“排除美国以外的所有男性”的规则,但是哪些规则引擎可以结合“排除所有男性”和“包括所有美国男性”? NLP 不相关,因为这些规则不是用自然语言捕获的,而且我对形式逻辑有很好的理解,这绝对可以解决这个问题,但我不知道有任何 java 实现足以表达这些规则的推断. 是我还是你正在寻找类似 PROLOG 的推理引擎的 java 实现? 【参考方案1】:

Java 有很多嵌入式的类似 Prolog 的 SLD 求解器;我最喜欢的方法是使用mini-Kanren for Scala,因为它很干净,并且允许您使用 Scala 懒惰地处理查询结果,但我没有深入使用它。有关其他选项以及罗斯的回答,请参阅 Embedded Prolog Interpreter/Compiler for Java。

SLD 求解器可以处理您的所有条件,前提是它们具有 Prolog 所具有的一些额外功能:

    规则结合:基本 SLD 目标处理; 规则可能有不同的优先级:Prolog 的剪切规则允许表示否定,前提是查询是可判定的; 规则可能有冲突:同样,如果满足较高优先级的目标,您可以使用 cut 确保不应用较低优先级的子句。有几种方法可以做到这一点。 规则是对称的:使用 cut,可轻松确保可判定谓词的这一点。 规则(或更确切地说是子集)可能具有与之关联的元规则(明确定义):您的示例似乎表明这相当于 4,所以我不确定我是否得到您想要的。

SLD 求解器相对于基于描述逻辑的工具的优缺点如下:

    编程能力、灵活性:您通常可以找到针对建模困难的编程解决方案,其中描述逻辑可能需要您重新考虑您的模型。但当然,没有胶带意味着描述逻辑解决方案会迫使您保持清洁,这可能是一个很好的纪律。 稳健性:SLD 求解器是一种非常容易理解的技术,而描述逻辑工具通常距离博士论文的诞生并不多。 缺乏语义工具:描述逻辑与一阶逻辑和模型逻辑有很好的联系,并为您提供了一套非常丰富的技术来推理它们。 Prolog 的灵活性通常使这变得非常困难。

如果您没有描述逻辑方面的专业知识,我建议您使用 SLD 求解器。

【讨论】:

【参考方案2】:

对于您所描述的情况,我认为您将希望使用后向链接,而不是前向链接(像 Drools 这样的 RETE 系统在其默认行为中是前向链接)。

查看tuProlog。易于与 Java 绑定,100% 纯 Java,绝对可以做你想要的推理。您需要对 Prolog 有足够的了解才能描述您的规则集。

Prova 还可以进行推理和处理复杂的规则系统。

【讨论】:

+1,嵌入式 SLD 求解器。 tu-Prolog 似乎是***.com/questions/1817010/… 上公认的答案 谢谢,我去看看。我目前不在接受培训,但我会在有足够时间对其进行适当评估时尽快回复。【参考方案3】:

对我来说,这听起来很像描述逻辑和知识库。你有概念、角色和个体。

如果您想将问题推广为基于描述逻辑的推理,您应该对问题进行精细建模并对其执行推理器。

有一些免费的推理器可用,可以在here找到一个列表。

但是请注意,这是一种相当复杂但功能强大的方法。

在使用 Java 时,您可能希望特别了解 KAON2 和 DIG。

【讨论】:

我查看了描述逻辑和推理器,但有些疑虑。首先是解决方案的复杂性。其次是需要一个相当有表现力的描述逻辑,这将影响推理时间,甚至可能使推理变得不可能。最后,我所知道的任何描述逻辑都不能立即满足优先级要求,这需要我开发自己的描述逻辑变体。想发表评论吗? 描述性逻辑似乎在“模糊”方面做得不好。您的要求表明可能存在冲突的规则。基于 OWL 之类的方法应该是“开放世界”,这意味着它可以代表冲突。问题是,推理者(Pellet 等)如何处理冲突?我认为您可以在模型中添加其他可以消除歧义的语句。也许做过的人知道确切的答案。 @Ross - 我的问题中的第 2 项提到了优先级,这将被手动分配并用于确定如何处理冲突。【参考方案4】:

我相信您可以使用 ID3 algorithm 从对象的初始状态中提取一组规则。我不知道任何具体的 Java 实现,虽然 Wikipedia 指出了从 Ruby 到 C 的不同实现(我不能发布多个超链接 :-)),但这并不是一个难学的算法。

一旦构建了可以以规则格式表示的决策树,您就可以使用它来查看您的对象属于哪个类别:来自美国的所有男性,所有 10 到 20 岁之间的女性,...以及当有人更新您在数据库中的对象时,您可以重建决策树。

【讨论】:

我注意到的问题。这只会有助于分类,而不是相反(给定一组规则,找到匹配的总体)。这是基于机器学习的,因此不是 100% 准确的。这些规则具有这样的性质,可以做出 100% 准确的推断。没有初始人口,我必须手动创建并分类它们以用作训练数据。【参考方案5】:

好的,这可能是一个愚蠢的答案。但无论如何我都会尝试...... 你可以使用 BeanShell 来做这样的事情:

创建一个简单的选择器命令(类似于 select(initialSet, paramName, paramValue) ),它返回 inicialSet 中的集合元素并与您的参数匹配。

创建一些可以帮助您编写漂亮的 BeanShell 脚本的常量。

通过这种方式,您可以将规则编写为简单的脚本和嵌套规则。

所以,这个

我需要规则的结合。因此,当同时出现“包括所有男性”和“排除 10 至 20 岁年龄段的所有美国人”时,我只对美国以外的男性以及美国境内 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;

当然,这很糟糕。我现在成功了。但是您可以编写非常好的命令并找到一种方法来使其更具可读性。

不是那么快,但易于维护和阅读(我认为)。而且您不必担心订购

就是这样。我试过了。 :)

【讨论】:

【参考方案6】:

最强大的基于 Java 的生产规则引擎(推理引擎)之一是 JBoss DROOLS。

http://jboss.org/drools

老实说,除非您的应用程序变得更加复杂,否则使用规则引擎实在是太过分了。另一方面,如果您的应用程序变得太大并且有太多冲突的规则,那么它将无法提供结果。

如果您可以更好地控制您的客户或问题领域,最好完全避免使用推理引擎。

【讨论】:

以上是关于推理引擎根据内部规则计算匹配集的主要内容,如果未能解决你的问题,请参考以下文章

Drools 推理引擎可以根据输入动态地生成一些rules吗?

业余草开源规则流引擎实践

清华深度学习框架 Jittor 开源,创新元算子和统一计算图,推理速度可提升 10%-50%

规则引擎Drools示例:个人所得税计算器信用卡申请保险产品准入规则

学习深度解析中文分词器算法(最大正向/逆向匹配)

模拟内存计算如何解决边缘人工智能推理的功耗挑战