Monday, December 24, 2007

Multiple Keywords in AIML

Have you ever wanted to convert an FAQ question to AIML, only to be confounded by the overly specific wording of the FAQ question?

For example,

Q: How do I unsubscribe from the email?
A: Unsubscribe and change preferences at http://list.pandorabots.com/mailman/listinfo/pandorabots-general

Most of us are familiar with the four AIML category approach to recognizing single keywords in the input:

<category><pattern>UNSUBSCRIBE</pattern>
<template>Unsubscribe and change preferences at
http://list.pandorabots.com/mailman/listinfo/pandorabots-general
</template>
</category>
<category><pattern>_ UNSUBSCRIBE</pattern>
<template><srai>UNSUBSCRIBE</srai></template>
</category>
<category><pattern>_ UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE</srai></template>
</category>
<category><pattern>UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE</srai></template>
</category>

But in many cases, the single keyword approach is too general. There may be a comepting FAQ question that uses the same keyword, such as "How do I unsubscribe a bot?" To make the input match more specific, we would often like to use a pair of keywords.

To make the bot respond to a wide set of variations of the input, we would like it to give the same answer to any input that contains the keywords. In this example, the two keywords might be "UNSUBSCRIBE" and "EMAIL". We would like the bot to give the same answer to any input that contains this pair of keywords, inlcuding for example "I want to unsubscribe from email," "Unsubscribe me from email," and "Email unsubscribe."

To accomplish this in AIML, we use a base category and a set of symbolic reductions, just as in the case of the single keyword match. The base category uses a simple pattern containing just the keywords:

<category>
<pattern>UNSUBSCRIBE EMAIL</pattern>
http://list.pandorabots.com/mailman/listinfo/pandorabots-general
</template>
</category>

Generally speaking, when dealing with a long, very specific FAQ question, it is better to try to summarize the input pattern in one to three keywords. This makes writing symbolic reductions easier and less error prone.

In our example, the symbolic reductions include combinations of the keyword and wildcards. For each pair of keywords ordered ("UNSUBSCRIBE", "EMAIL") and ("EMAIL", "UNSUBSCRIBE") There are 7 combinations of keywords with at least one wildcard. There is one extra category to reduce the atomic pattern "EMAIL UNSUBSCRIBE" to "UNSUBSCRIBE EMAIL":

<aiml>
<category><pattern>_ UNSUBSCRIBE * EMAIL *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE * EMAIL </pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE EMAIL *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE EMAIL </pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern> UNSUBSCRIBE * EMAIL *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern> UNSUBSCRIBE * EMAIL </pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern> UNSUBSCRIBE EMAIL *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern>_ EMAIL * UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern>_ EMAIL * UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern>_ EMAIL UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern>_ EMAIL UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern> EMAIL * UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern> EMAIL * UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern> EMAIL UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
<category><pattern> EMAIL UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE EMAIL</srai></template></category>
</aiml>

You can do the same thing with three keywords. For example suppose the FAQ question is "I am still getting Pandorabots email and a I want to unsubscribe." The keywords in this case might be "UNSUBSCRIBE PANDORABOTS EMAIL". This time there are 95 combinations of keyword order and wildcards. Here are the first and last few:

<aiml>
<category><pattern>_ UNSUBSCRIBE * PANDORABOTS * EMAIL *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE * PANDORABOTS * EMAIL </pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE * PANDORABOTS EMAIL *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE * PANDORABOTS EMAIL </pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE PANDORABOTS * EMAIL *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE PANDORABOTS * EMAIL </pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE PANDORABOTS EMAIL *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern>_ UNSUBSCRIBE PANDORABOTS EMAIL </pattern>

...

<category><pattern> EMAIL * PANDORABOTS * UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern> EMAIL * PANDORABOTS * UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern> EMAIL * PANDORABOTS UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern> EMAIL * PANDORABOTS UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern> EMAIL PANDORABOTS * UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern> EMAIL PANDORABOTS * UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern> EMAIL PANDORABOTS UNSUBSCRIBE *</pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
<category><pattern> EMAIL PANDORABOTS UNSUBSCRIBE </pattern>
<template><srai>UNSUBSCRIBE PANDORABOTS EMAIL</srai></template></category>
</aiml>

Using this set of symbolic reductions, the bot will answer the same thing to a variety of inputs such as:
"How can I unsubscribe to Pandorabots email?"
"I am getting email from Pandorabots and I want to unsubscribe."
"Unsubscribe me from Pandorabots email."

For three keywords X, Y and Z, the 95 combinations come from 6 different possible orderings of the keywords (X Y Z, X Z Y, Y X Z, Y Z X, Z X Y, Z Y X ) times 16 different possible insertions of wildcards (from X Y Z to _ X * Y * Z), minus one because we use X Y Z itself as the pattern for the base category.

4 comments:

  1. (from pandorabots-general)

    Converting RSS and FAQ entries into AIML both present the same problem.
    Generally, the title (or question) is too specific, and the answer is too long. You can convert a specific FAQ question directly into an AIML pattern, but the pattern might be so long and wordy that it is unlikely anyone will ever ask a bot that exact question.

    If the responses are too long, the bot will lose its apparent intelligence and become a talking encylopedia. We have done some work in the past
    trying to come up with a "narration" tag in AIML, so that the bot can reply with part of the answer, and then continue if the client says something like "Go on" or "Tell me more."

    More progress is being made on the pattern side. I wrote recently in the Alicebot blog about how to use multiple keywords in patterns, in order to translate overly specific FAQ questions into in AIML.

    ReplyDelete
  2. I tried the multiple keyword approach as suggested here and the response I get is "Too Much Recursion in AIML" when I try it out. What am I doing wrong? (My bot is hosted by pandorabots, btw)

    ReplyDelete
  3. Hi Adeena, here is the problem I think. Some of your AIML patterns
    have no space before the wildcard *:


    <category><pattern>_ ABOUT MIGNOGNA GENEALOGY*</pattern>
    <template><srai>ABOUT MIGNOGNA GENEALOGY</srai></template></category>
    <template><srai>ABOUT MIGNOGNA GENEALOGY</srai></template></category>
    <category><pattern> ABOUT MIGNOGNA GENEALOGY*</pattern>


    You should use

    <pattern> ABOUT MIGNOGNA GENEALOGY *</pattern>


    Pandorabots is trying to normalize the words in the patterns, so
    "GENEALOGY*" looks the same as "GENEALOGY".

    Thanks for your interest in AIML!

    ReplyDelete
  4. Hello Dr. Wallace,

    I'm creating something very similar to this in a Pandorabots chatbot and was wondering if you had any full examples of the 95 categories to match 3 keywords. I'm creating a simple script to automatically generate the categories for input keywords and got a little hung up trying to get the 95 categories to reduce down to 3 keywords. Here is an example of my current script.

    http://www.wadsworthlibrary.com/

    aimltools/keywordpatterngenerator.cfm

    Thanks for your great work with AIML and thanks for any help you can provide.

    ReplyDelete

 

blogger templates | Make Money Online