如何在CLIPS中计算具有相同参数的断言?

我是CLIPS的新手。我想计算具有两个相同参数的断言的平均值。例如,如果我有以下模板:

(deftemplate quiz  (slot id (type INTEGER))  (slot course(type STRING))  (slot quizname (type STRING))  (slot userid (type INTEGER))  (slot firstname (type STRING))  (slot average (type FLOAT))  )

以及这些断言:

(deffacts users   (quiz (id 1) (course "Math") (quizname "Equations") (userid 1) (firstname "Mike") (average 70.00))   (quiz (id 2) (course "Math") (quizname "Exercise") (userid 1) (firstname "Mike") (average 20.00))   (quiz (id 3) (course "Math") (quizname "Sum") (userid 2) (firstname "Ronald") (average 90.00))   (quiz (id 4) (course "Math") (quizname "Equations") (userid 2) (firstname "Ronald") (average 60.00))   (quiz (id 9) (course "English") (quizname "Listening") (userid 5) (firstname "Lionel") (average 60.00))   )

我想构建一个规则来计算具有相同’userid’和’course’的断言的平均值,并将结果写入文件。我希望得到的答案是:

迈克在数学中的平均分为45.00;罗纳德在数学中的平均分为75.00;莱昂内尔在英语中的平均分为60.00

我尝试了这个规则。我知道它完全是错误的:

(defrule averageStudent=>(bind ?sum 0)(do-for-all-facts ((?f quiz)) TRUE(bind ?sum (+ ?sum ?f:average)))(bind ?sum (/ ?sum (length$ (find-all-facts ((?nFacts quiz)) (eq ?nFacts:userid) (eq ?nFacts:namequiz math)))))(printout t ?firstname " in math has " ?sum crlf))

回答:

你需要构建一些东西来保存你想要计算平均值的所有名字/课程组合。在规则的动作中,你需要遍历quiz事实并生成一个包含(“迈克” “罗纳德” “莱昂内尔”)的多字段变量和另一个包含(“数学” “数学” “英语”)的多字段变量。然后,你需要使用从1到列表长度的索引来迭代这些列表,然后使用nth$函数从每个列表中提取名字和课程。然后,你可以使用事实查询函数来提取每个名字/课程的平均值并计算总平均值。

与其做所有这些,你可以编写一个规则来确定需要计算平均值的所有名字/课程组合,并将这些作为事实断言:

(deftemplate compute   (slot course (type STRING))   (slot firstname (type STRING)))   (defrule determine-course-name   (logical (compute-averages))   (quiz (course ?course) (firstname ?name))   (not (compute (course ?course) (firstname ?name)))   =>     (assert (compute (course ?course) (firstname ?name))))

然后你可以编写一个规则,仅计算一个名字/课程的平均值:

(defrule compute-average   (compute (course ?course) (firstname ?name))   =>   (bind ?sum 0)   (bind ?count 0)   (do-for-all-facts ((?f quiz))                     (and (eq ?f:course ?course)                          (eq ?f:firstname ?name))      (bind ?sum (+ ?sum ?f:average))      (bind ?count (+ ?count 1)))   (format t "%s in %s has %0.2f%n" ?name ?course (/ ?sum ?count)))

determine-course-name规则最初不会被激活:

         CLIPS (6.4 2/9/21)CLIPS> (deftemplate quiz  (slot id (type INTEGER))  (slot course (type STRING))  (slot quizname (type STRING))  (slot userid (type INTEGER))  (slot firstname (type STRING))  (slot average (type FLOAT)))CLIPS> (deffacts users   (quiz (id 1) (course "Math") (quizname "Equations") (userid 1) (firstname "Mike") (average 70.00))   (quiz (id 2) (course "Math") (quizname "Exercise") (userid 1) (firstname "Mike") (average 20.00))   (quiz (id 3) (course "Math") (quizname "Sum") (userid 2) (firstname "Ronald") (average 90.00))   (quiz (id 4) (course "Math") (quizname "Equations") (userid 2) (firstname "Ronald") (average 60.00))   (quiz (id 9) (course "English") (quizname "Listening") (userid 5) (firstname "Lionel") (average 60.00)))CLIPS>    (deftemplate compute   (slot course (type STRING))   (slot firstname (type STRING)))CLIPS>    (defrule determine-course-name   (logical (compute-averages))   (quiz (course ?course) (firstname ?name))   (not (compute (course ?course) (firstname ?name)))   =>     (assert (compute (course ?course) (firstname ?name))))CLIPS>    (defrule compute-average   (compute (course ?course) (firstname ?name))   =>   (bind ?sum 0)   (bind ?count 0)   (do-for-all-facts ((?f quiz))                     (and (eq ?f:course ?course)                          (eq ?f:firstname ?name))      (bind ?sum (+ ?sum ?f:average))      (bind ?count (+ ?count 1)))       (format t "%s in %s has %0.2f%n" ?name ?course (/ ?sum ?count)))CLIPS> (reset)CLIPS> (facts)f-1     (quiz (id 1) (course "Math") (quizname "Equations") (userid 1) (firstname "Mike") (average 70.0))f-2     (quiz (id 2) (course "Math") (quizname "Exercise") (userid 1) (firstname "Mike") (average 20.0))f-3     (quiz (id 3) (course "Math") (quizname "Sum") (userid 2) (firstname "Ronald") (average 90.0))f-4     (quiz (id 4) (course "Math") (quizname "Equations") (userid 2) (firstname "Ronald") (average 60.0))f-5     (quiz (id 9) (course "English") (quizname "Listening") (userid 5) (firstname "Lionel") (average 60.0))For a total of 5 facts.CLIPS> (agenda)CLIPS> 

一旦你断言(compute-averages),规则就可以计算平均值:

CLIPS> (assert (compute-averages))<Fact-6>CLIPS> (agenda)0      determine-course-name: f-6,f-5,*0      determine-course-name: f-6,f-4,*0      determine-course-name: f-6,f-3,*0      determine-course-name: f-6,f-2,*0      determine-course-name: f-6,f-1,*For a total of 5 activations.CLIPS> (run)Lionel in English has 60.00Ronald in Math has 75.00Mike in Math has 45.00CLIPS>

中间的compute事实仍然存在,但由于这些事实逻辑上依赖于(compute-averages)事实,如果你需要清理它们,你可以通过撤回那个事实来删除它们:

CLIPS> (facts)f-1     (quiz (id 1) (course "Math") (quizname "Equations") (userid 1) (firstname "Mike") (average 70.0))f-2     (quiz (id 2) (course "Math") (quizname "Exercise") (userid 1) (firstname "Mike") (average 20.0))f-3     (quiz (id 3) (course "Math") (quizname "Sum") (userid 2) (firstname "Ronald") (average 90.0))f-4     (quiz (id 4) (course "Math") (quizname "Equations") (userid 2) (firstname "Ronald") (average 60.0))f-5     (quiz (id 9) (course "English") (quizname "Listening") (userid 5) (firstname "Lionel") (average 60.0))f-6     (compute-averages)f-7     (compute (course "English") (firstname "Lionel"))f-8     (compute (course "Math") (firstname "Ronald"))f-9     (compute (course "Math") (firstname "Mike"))For a total of 9 facts.CLIPS> (retract 6)CLIPS> (facts)f-1     (quiz (id 1) (course "Math") (quizname "Equations") (userid 1) (firstname "Mike") (average 70.0))f-2     (quiz (id 2) (course "Math") (quizname "Exercise") (userid 1) (firstname "Mike") (average 20.0))f-3     (quiz (id 3) (course "Math") (quizname "Sum") (userid 2) (firstname "Ronald") (average 90.0))f-4     (quiz (id 4) (course "Math") (quizname "Equations") (userid 2) (firstname "Ronald") (average 60.0))f-5     (quiz (id 9) (course "English") (quizname "Listening") (userid 5) (firstname "Lionel") (average 60.0))For a total of 5 facts.CLIPS>

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注