特别是我试图确定解决以下类型问题的最佳方法:
我感兴趣的示例是 Mitchell 的机器学习书中的 find-s 算法,它被应用于 4 个训练示例。
基本思想是对于每个训练示例 x 和假设 h,确定 h' 是否包含 x,使其更通用。对于训练集中的每个 x,我需要将 h 映射到 h'。我遇到的问题是如何用逻辑编程语言最好地解决这个问题。我正在使用 minikanren,它大致是嵌入在方案中的序言。
在计算每个 h' 之后,我需要设置!它到一个全局变量 h,然后继续下一个训练示例 x。下面的代码是程序的主要部分。
(define h '(0 0 0 0 0 0))
(define seto
(lambda (x)
(project (x)
(lambda (s) (set! h x) (succeed s)))))
(run* (q)
(fresh (x h0 h1)
(trainingo x)
(== h h0)
(find-so h0 x h1)
(seto h1)
(== h1 q)))
h 是全局变量,seto 使用 find-s 算法 (find-so) 从 h0 和 x 训练示例中计算的下一个假设 h1 对 h 进行变异。
在序言中,它(我认为)相当于assert('hypothesis'(H))在每个训练示例 X 之后(覆盖前一个)并在所有训练示例之后调用retract('hypothesis'(H))应用。
我的问题是,这是否是解决此类问题的最佳方法(通过副作用)?
编辑:我接受了@mat 的回答和他的评论。总之,我需要将训练示例视为一个列表,并在该列表上使用前向递归,直到我到达空列表。如果我陷入困境,就是将训练示例作为回溯的一部分,同时寻找下一个假设,而不是将它们放在我可以重复到空的列表中。