特别是我正在尝试确定解决以下类型问题的最佳方法:
我感兴趣的例子是Mitchell机器学习书中的find-s算法,它适用于4个训练样例。
基本思想是针对每个训练样例,x和假设h,通过使其更通用来确定它是否包含x。我需要为训练集中的每个x将h映射到h'。我遇到的问题是如何在逻辑编程语言中最好地解决这个问题。我正在使用minikanren,它大致是在计划中嵌入的prolog。
计算每个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用h1变异h,这是h0和x训练示例中使用find-s算法(find-so)的下一个计算假设。
在prolog中,它(我认为)等同于断言('假设'(H))在每个训练示例X(覆盖前一个)并调用撤回(')之后在应用了所有训练样例后,假设'(H))。
我的问题是,这是否是解决这类问题的最佳方法(通过副作用)?
编辑: 我和他的comment一起接受了@mat答案。总之,我需要将训练示例视为列表,并在该列表中使用前向递归,直到我进入空列表。如果我陷入困境,那就是将训练样例作为回溯的一部分,同时找到下一个假设,而不是将它们列入我可以重复使用的列表中直到空。
答案 0 :(得分:3)
您的建议似乎诱人:使用assertz/0
和retract/1
模拟全局更新。
但是,如果你这样做,有主要缺点:
模拟这些状态变化的声明性解决方案是根据状态之间的关系来思考。
例如,当您使用H0
计算下一个假设H1
时,您可以将其表达为H0
和{{1}之间的关系可能还有其他参数。想想谓词如下:
H1
hypothesis_next(H0, H1)
algorithm_hypothesis_next(A, H0, H1)
请注意,此类谓词可以在所有方向读取和 - 理想 - 运行!
总的来说,整个解决方案将在您的案例中建模为假设序列:
parameters_hypothesis_next(Ps, H0, H1)
→H0
→H1
→...→H2
有关更多信息和指示,请参阅密切相关的问题:
How to avoid using assert and retractall in Prolog to implement global (or state) variables