美文网首页lisp语言我是程序员;您好程先生;叫我序员就好了
AI编程范式 第5章 ELIZA:和机器对话(四)

AI编程范式 第5章 ELIZA:和机器对话(四)

作者: geoeee | 来源:发表于2015-01-06 17:13 被阅读119次
    5.4 ELIZA程序:一个基于规则的翻译器

    现在我们已经有了一个能用的模式匹配器了,我们还需要一些模式来进行匹配。进一步来说,我们需要模式来与回答进行关联。可以通过引入一个叫做rule的数据结构来做到这件事情,rule由一个模式和一个或者多个关联的回答组成。这些规则的意思就是“如果你看到了A就用B或者C来恢复,随机选择。”我们来实现一个最简单的规则,用列表实现,第一个元素就是模式,剩下的就是一个回复的列表。
    (defun rule-pattern (rule) (first rule))
    (defun rule-responses (rule) (rest rule))
    下面是一个规则的例子:
    (((?* ?x) I want (?* ?y))
    (What would it mean if you got ?y)
    (Why do you want ?y)
    (Suppose you got ?y soon))
    接下来我们输入(I want to test this program),这个规则(当在ELIZA程序内被解释的时候)就会随机选择一个回复,用回复替代变量?y的值,回复(Why do you want to test this program)。
    现在我们已经知道了单独的股则是怎么工作的,我们还需要明白如何来处理规则的集合。如果ELIZA是兴趣广泛的,那么就会有很多种不同的回答。所以一些规则可能会用来处理同一个输入。其中一种可能性就是从匹配输入的众多规则中随机选择一个规则。
    另一外一种可能就是选择匹配的第一个规则,这表示了规则的集合是一个有序的列表,而不是无序的。聪明的ELIZA规则创建者会利用这种有序,安排一些特定的规则在前面,把某些含糊的规则放在队列的后面。
    原始的ELIZA程序有一个优先级系统,每一个规则都有一个确定的优先级数字绑定在上面。优先级最高的匹配规则总是会最先被选择的。请注意,把规则的集合进行有序的排列效果上来说和设置优先级是一样的。第一条规则就是隐式的最高优先级规则,第二条就是次高优先的,以此类推。
    这里是一个规则的比较短的列表,从Weizenbaum的论文中节选出来的,但是这里有了规则组织形成的形式了。
    (defparameter *eliza-rules*
    ‘((((?* ?x) hello (?* ?y))
    (How do you do. Please state your problem.))
    (((?* ?x) I want (?* ?y))
    (What would it mean if you got ?y)
    (Why do you want ?y) (Suppose you got ?y soon))
    (((?* ?x) if (?* ?y))
    (Do you really think its likely that ?y) (Do you wish that ?y)
    (What do you think about ?y) (Really—if ?y))
    (((?* ?x) no (?* ?y))
    (Why not?) (You are being a bit negative)
    (Are you saying “NO” just to be negative?))
    (((?* ?x) I was (?* ?y))
    (Were you really?) (Perhaps I already knew you were ?y)
    (Why do you tell me you were ?y now?))
    (((?* ?x) I feel (?* ?y))
    (Do you often feel ?y ?))
    (((?* ?x) I felt (?* ?y))
    (What other feelings do you have?))))

    最后我们准备开始定义ELIZA本身。正如我们之前所说,主程序应该是一个不断读取输入的循环,转化输入,输出打印结果。转化过程主要通过找到一些匹配输入的模式规则来完成,之后就会用规则中的回复替换变量。程序在下面的表格中总结。
    还有一些小复杂的地方,我们打印一个提示符来告诉用户输入些东西。我们使用函数flatten来确保输出不会在变量替换后嵌入列表。一个重要的技巧就是更改输入,从你到我的转变等等,这些属于也都是相对于说话者,下面是完整的程序:

    (defun eliza ()
    “Respond to user input using pattern matching rules.”
    (loop
       (print ‘eliza>)
       (write (flatten (use-eliza-rules (read))) :pretty t)))

    (defun use-eliza-rules (input)
    “Find some rule with which to transform the input.”
    (some #’(lambda (rule)
         (let ((result (pat-match (rule-pattern rule) input)))
           (if (not (eq result fail))
             (sublis (switch-viewpoint result)
               (random-elt (rule-responses rule))))))
       *eliza-rules*))

    (defun switch-viewpoint (words)
    “Change I to you and vice versa, and so on.”
    (sublis ‘((I . you) (you . I) (me . you) (am . are))
       words))

    函数名 功能含义
    顶层函数
    Eliza 使用模式匹配规则回复用户的输入
    特殊变量
    Eliza-rules 转换规则的列表
    数据类型
    Rule 一个模式和一系列的回复的组合
    函数
    Eliza 使用模式匹配规则回复用户的输入
    Use-eliza-rules 找出可以转化输入的一些规则
    Switch-viewpoint 将I更改成you,或者反之,等等
    Flatten 将列表中的元素追加到一起
    用到的Common Lisp函数
    Sublis 将元素替换到一颗树中
    之前定义的函数
    Random-elt 从列表中随机选择一个元素
    Pat-match 针对输入匹配一个模式
    Mappend 将mapcar的结果追加到一起

    请注意在write函数中使用的关键字pretty的值是真。这会在某些情况下给出更好的格式化输出。程序利用之气那顶一个random-elt和flatten,他们是使用mappend和mklist来定义的,这个函数在InterLisp方言中定义了,但是没有在Common Lisp中定义。

    (defun flatten (the-list)
    “Append together elements (or lists) in the list.”
    (mappend #’mklist the-list))

    (defun mklist (x)
    “Retrun x if it is a list, otherwise (x).”
    (if (listp x)
       x
       (list x)))

    (defun mappend (fn the-list)
    “Apply fn to each element of list and append the results.”
    (apply #’append (mapcar fn the-list)))

    (defun random-elt (choices)
    “Choose an element from a list at random.”
    (elt choices (random (length choices))))

    真实的ELIZA程序要比这里的版本更加复杂一些。首先有一个别名方法来关联一些单词到一些模式上,比如父亲和母亲都会关联到家人这个模式中。也有一个同义词机制来确保,不和否,每人和每个人是一样的意思。由于输入有时候会使用逗号来分割短语,每一个短语都是单独处理的,回复也是使用的最高优先级。另外,原始的ELIZA有一个记忆机制。当没有模式匹配当前输入的时候,但会打印告诉我更多关于X的信息,X就是之前给定的某些输入。最后来说,我们的把呢吧的过则更少,不管我们的版本的短处,他已经可以完成一个对话了,如下:
    > (eliza)
    ELIZA> (hello there)
    (HOW DO YOU DO. PLEASE STATE YOUR PROBLEM.)
    ELIZA> (i want to test this program)
    (WHAT WOULD IT MEAN IF YOU GOT TO TEST THIS PROGRAM)
    ELIZA> (i could see if it works)
    (DO YOU REALLY THINK ITS LIKELY THAT IT WORKS)
    ELIZA> (no not really)
    (ARE YOU SAYING "NO" JUST TO BE NEGATIVE?)
    ELIZA> (no)
    (ARE YOU SAYING "NO" JUST TO BE NEGATIVE?)
    ELIZA> (forget it-- i was wondering how general the program is)
    (WHY DO YOU TELL ME YOU WERE WONDERING HOW GENERAL THE PROGRAM IS NOW?)
    ELIZA> (i felt like it)
    (WHAT OTHER FEELINGS DO YOU HAVE?)
    ELIZA> (i feel this is enough)
    (DO YOU OFTEN FEEL THIS IS ENOUGH ?)
    ELIZA> [Abort]
    ¬>

    最后要说的是,重要的是计数而不是程序,ELIZA已经被解剖地可以请下神坛了。模式匹配仍然是重要的即使,我们会在后面的章节中再见到的。基于规则的翻译器的概念也是很重要的。能够理解英语,或者其他语言的问题领域,仍然是AI中重要的一部分。很明显,理解英语这个问题并没有被ELIZA解决。在第五部分,我们会使用一些更加附加的技术再次讨论这个问题。

    5.5 历史和参考

    如上面所说,描述ELIZA的原始论文是Weizenbaum在1966年写的。另一个使用相似模式匹配技术的对话系统是Kenneth Colby的PARRY。PARRY这个程序模拟的是一个类似具有妄想偏执倾向的人格的人,而且已经像到了可以骗过一些专业心理学家的地步了。虽然模式匹配技术是简单的,但系统维护的意识模型要比ELIZA复杂得多。Colby已经表明了对话程序,如ELIZA,增加了一些意识模型的程序如PARRY,都可以成为在人类精神领域的有用工具。如Colby所说,这些程序可以成为免费而高效的工具,让病人和一个特殊设计程序交互,可以应对一些简单的情况,也可以让魏医生筛选需要更多帮助的病人。其他的有意思的早期对话系统,意识模型是有Allan Collins和Jamie Carbonell提出的。

    相关文章

      网友评论

        本文标题:AI编程范式 第5章 ELIZA:和机器对话(四)

        本文链接:https://www.haomeiwen.com/subject/wtvtxttx.html