Raport z projektu

Chatterbot - Monic

3.VI.2006 rok, ARR, Politechnika Wrocławska






Wykonali: Rafał Guźniczak, Jacek Jagodziński
Przedmiot: Metody i algorytmy sztucznej inteligencji
Prowadzący: Witold Paluszyński



Cel projektu
Opis projektu
Szkielet plików AIML bota
Bot
Zastosowane strategie tworzenia bota
Proste odpowiedzi w AIML
Synonimy <srai> 
Kontekst: <that>
Predykaty
Kontekst: <topic>
Wyrażenie warunkowe
Przykład rozmowy
Podsumowanie
Materiały


Cel projektu

Celem projektu było stworzenie bota, rozmawiającego w języku naturalnym, głównym tematem rozmów naszego chatbota jest polityka obecnej RP. W wyniku naszego projektu powstał bot o imieniu Monic, który podtrzymuje rozmowę z użytkownikiem próbując zastąpić człowieka.

Nasz bot dostępny jest na stronie: Monic


Opis projektu

Każdy chatterbot składa się z dwóch podstawowych elementów: bazy wiedzy i silnika przetwarzającego te wiedze. Zastosowaliśmy w naszym programie języka opisu wiedzy AIML (Artificial Intelligence Markup Language), opracowanego na potrzeby projektu sztucznej inteligencji ALICE i będącego podstawa działania wszystkich botów bazujących na osiągnięciach tego otwartego projektu. Skorzystaliśmy z gotowego silnika przetwarzania wiedzy PyAIML, napisanego w Pytonie, naszą bazę wiedzy stworzoną w AIML-u można później wykorzystać w każdym bocie zgodnym ze standardem ALICE (lista darmowych implementacji ALICE dla rożnych jeżyków jest dostępna pod adresem http://www.alicebot.org/downloads

Bazę wiedzy naszego bota stanowi następuje pliki:
bot.aiml
hunanpl.aiml
monic.aiml
nauczonegadki.aiml
politics.aiml
polityka.aiml
redukcja_symboliczna.aiml
synonimy.aiml
giertych.aiml
update.aiml


Szkielet plików AIML bota

Wszystkie pliki z bazami danych naszego bota tworzymy według wzoru:

<?xml version="1.0" encoding="ISO-8859-1"?>
<aiml version="1.0.1">

</aiml>

W dalszej kolejności będziemy wypełniać go treścią, umieszczaną w obrębie głównego znacznika aiml.


Bot

  1. Uruchomienie interpretera AIML:
    import aiml
    k = aiml.Kernel()
  2. Wczytanie pliku wzorców:
    k.learn("synonimy.aiml")
  3. otwarcie/utworzenie plikow logow
    conv_log = file("conversation.log","a",1)
    unknown_log = file("unknown.log","a",1)
    conv_log.write("-----------\n")
  4. Pobranie wypowiedzi użytkownika:
    while True:
    user_input = raw_input("> ")
    if user_input == "quit":
    break
  5. Określenie odpowiedzi:
    answer = k.respond(user_input)
    if answer == "":
    unknown_log.write(user_input+"\n")
  6. Zapisanie pytania i odpowiedzi do głównego logu:
    conv_log.write(user_input+" || "+answer+"\n")
  7. Wypisanie odpowiedzi na ekranie:
    print answer
  8. Zamkniecie plików logów:
    conv_log.close()
    unknown_log.close()

Zastosowane strategie tworzenia bota

Oprócz najprostszych odpowiedzi, na pytania, wykorzystujemy: synonimy, konteksty (znacznik <that>), predykaty, konteksty (znacznik <topic>), wyrażenia warunkowe.


Proste odpowiedzi w AIML

<category>
<pattern>Czesc</pattern>
<template>Witaj</template>
</category>

W ten prosty sposób można definiować bezpośrednie reakcje werbalne bota na wprowadzenie ściśle określonej frazy, bot potrafi zareagować odpowiedzią Witaj na ciąg wejściowy Czesc. Jak widać na tym przykładzie standard AIML nie obsługuje polskich znaków diakrytycznych, także podczas rozmowy nie należy ich stosować.


Synonimy <srai>

Język AIML posiada bardziej wyrafinowane mechanizmy definiowania bazy wiedzy botów. Np. naturalnym oczekiwaniem jest, aby bot potrafił odpowiedzieć przywitaniem na inne frazy wejściowe. Wprawdzie AIML nie pozwala na osadzanie więcej niż jednego wzorca w ramach jednej kategorii, ale możemy to osiągnąć przy użyciu mechanizmu synonimów:

<category>
<pattern>Dzien dobry</pattern>
<template><srai>Czesc</srai></template>
</category>

Gdy wprowadzimy frazę Dzien dobry bot przeszuka bazę wiedzy próbując dopasować do jakiegoś znacznika <pattern> zamiast Dzien dobry frazę Czesc. 


Kontekst: <that>

Ważnym elementem języka AIML jest tzw. kontekst, pozwala on rozróżnić pomiędzy kategoriami w przypadku jednakowego wzorca. Znajduje to zastosowanie szczególnie w przypadku częstych, jednakowych zdań użytkownika posiadających różne znaczenie (z uwagi na różny kontekst). Np. odpowiedzi tak/nie udzielane przez użytkownika na różne pytania powinny skutkować różnymi reakcjami bota, uzależnionymi od pytania, na które padła dana odpowiedź. Oto przykład wykorzystania:


<category>
<pattern>Nie</pattern>
<that>Lubisz Giertycha ?</that>
<template>Dlaczego go nie lubisz ?</template>
</category>
<category>
<pattern>Tak</pattern>
<that>Lubisz Giertycha ?</that>
<template>A ja za nim nie przepadam .</template>
</category>

Przykład ten obrazuje zastosowanie znacznika <that>. Jeśli pojawia się ze strony użytkownika stwierdzenie Nie to odpowiedź zależy od tego czy bezpośrednio poprzedzającym stwierdzeniem użytkownika było zdanie lubisz Giertycha? czy jakieś inne. Bot, odpowiednio reaguje albo pytając o uzasadnienie, albo stwierdzeniem A ja za nim nie przepadam.


Predykaty

AIML pozwala na wykorzystanie predykatów w sekcji <template> kategorii, dzięki czemu łatwiej sterować przebiegiem konwersacji. W celu wykorzystania predykatu definiujemy go w pliku dodając linijkę:

<predicate name="to" default="something" set-return="name"/>

Następnie możemy wykorzystać predykat o nazwie to w poniższym przykładzie:


<category>
<pattern>*</pattern>
<that>Dlaczego go nie lubisz</that>
<template>
Nie sadze, zeby <set name="to"><star/></set> bylo wystarczajacym wyjasnieniem. Czy naprawde uwazasz, ze '<get name="to"/>' wystarczy by przekonac tak inteligentna osobe jak ja ?
</template>
</category>

Załóżmy, że w powyższym przykładzie użytkownik udzielił odpowiedzi na pytanie Dlaczego go nie lubisz. Użytkownik odpowiedział np.: 'bo tak' słowa te zostają dopasowane poprzez wzorzec * ponieważ następuje bezpośrednio po pytaniu bota Dlaczego go nie lubisz (znacznik <that>). Znacznik <set> przypisuje predykatowi to wartość będącą uzasadnieniem i zwraca jednocześnie w miejscu przypisania swoją nazwę, co wynika z określenia predykatu set-return="name". W drugim zdaniu odpowiedzi znacznik <get> pobiera wartość predykatu i umieszcza w miejscu, w którym sam się znajduje. Efektem jest uzyskanie odpowiedzi Nie sadze, żeby bo tak było wystarczającym wyjaśnieniem. Czy naprawde uwazasz, ze 'bo tak' wystarczy by przekonac tak inteligentna osobe jak ja?


Kontekst: <topic>

Innym przykładem wykorzystania kontekstu jest znacznik <topic>. Obejmuje kilka kategorii. Temat dalszej konwersacji z botem zostaje ustalony w wyniku dopasowania odpowiedniego wzorca. Od tego momentu dopasowania w sekcji <topic> uzyskują pierwszeństwo. Zostało to zobrazowane na poniższym przykładzie:

<topic name="GIERTYCH">
<category>
<pattern>*</pattern>
<template>
<random>
<li>Chcesz poznac biografie Giertycha?</li>
<li>Co myslisz o pomysle Giertycha wprowadzenia do szkol wychowania patriotycznego?</li>
<li>Czy Roman Giertych ma odpowiednie kwalifikacje do pelnienia funkcji ministra edukacji narodowej?</li>
<li>Co sadzisz o pomysle, by uczniowie mieli mozliwosc wyboru religii jako jednego z przedmiotow zdawanych na maturze?</li>
<li>Lubisz Giertycha?</li>
<li>Znasz jakis dowcip o Giertychu?</li>
</random>
</template>
</category>
<category>
<pattern>Nie mam ochoty na ten temat rozmawiac</pattern>
<template><think><set name="topic">POLITYKA</set></think>W porzadku, nie rozmawiajmy juz o nim.</template>
</category>
</topic>
<category>
<pattern>* GIERTYCHU</pattern>
<template><think><set name="topic">GIERTYCH</set></think>Dobra, mozemy o nim porozmawiac.</template>
</category>

Część kategorii należy do tematu o nazwie GIERTYCH. Początkowo dopasowywane są wzorce spoza tego tematu, i tak na stwierdzenie użytkownika aktywujące wzorzec * GIERTYCHU (np. Porozmawiajmy o Giertychu) otrzymamy odpowiedź Dobra, możemy o nim porozmawiać, bot aktywuje równocześnie temat ZWIERZAKI, którego kategorie od tej pory, jako obowiązującego tematu rozmowy, będą miały pierwszeństwo przy dopasowaniach. Jeżeli użytkownik nie wywoła żadnego znanego wzorca, bot wylosuje jedno z pytań z wnętrza sekcji <topic> np. Lubisz Giertycha?. Sposobem wyjścia z tematu GIERTYCH, jest napisanie frazy Nie mam ochoty na ten temat rozmawiać, która zmieni aktualny temat na POLITYKA, bot odpowie równocześnie W porzadku, nie rozmawiajmy juz o nim.


Wyrażenie warunkowe na przykładzie obrażonej Monic

Ostatni przykład prezentuje wykorzystanie wyrażenia warunkowego w kombinacji z tematem:

<topic name="OBRAZONA">
<category>
<pattern>*</pattern>
<template>
<think><set name="var"><star /></set></think>
<condition>
<li name="var" value="przepraszam">
Niech bedzie, ze Ci wybaczam, ale to ma sie nie powtorzyć
<think><set name="topic">POLITYKA</set></think>
</li>
<li name="var" value="nie">
Nie rozmawiam z Toba dopoki mnie nie przeprosisz.
<think><set name="topic">OBRAZONA</set></think>
</li>
<li>Przepros mnie. </li>
</condition>
</template>
</category>
</topic>

Gdy wejdziemy do tematu OBRAZONA dowolna fraza użytkownika spotyka się z prośba bota Przepros mnie oraz ustawieniem tematu OBRAZONA. W tym temacie znajduje się jedna kategoria zawierająca w sekcji <template> wyrażenie warunkowe <condition> z listą wariantów <li>. Słowa bota Przepros mnie. będzie powtarzane dopóki użytkownik nie udzieli jednej z wyszczególnionych odpowiedzi. Po udzieleniu odpowiedzi Nie bot odpowie Nie rozmawiam z Toba dopoki mnie nie przeprosisz. Wyjście z pętli jest możliwe tylko po udzieleniu odpowiedzi Przepraszam wtedy bot zmieni temat na POLITYKA.


Podsumowanie

Okres czasu przewidziany na ten projekt jest za krótki. Większość projektów tego typu powstaje latami, a baza wiedzy jest rozwijana powoli, ale systematycznie. Ponieważ my mieliśmy tylko kilka tygodni mózg naszego bota jest stosunkowo mało rozbudowany. Aby przeprowadzić jakąś sensowna rozmowę użytkownik musi trafić w frazę, na którą bot ma przygotowaną odpowiedź. Dłuższa rozmowa nie jest możliwa, gdyż tematy zostaną wyczerpane i bot zacznie powtarzać te same zwroty.


Przykład rozmowy

Gdy z botem rozmawia osoba, która nie wie jakie frazy są w bazie wiedzy to ciężko jest uzyskać sensowna odpowiedz. Gdy natomiast rozmawia twórca bazy widać to od razu po dialogu, bot się nie powtarza i jego wypowiedzi zależą od tego co wprowadził użytkownik.

Mało sensowna
Sensowna
Human: witam
Monic: Tak?

Human: no dzien dobry
Monic: Oh, jestes poeta.

Human: chyba jestes gupia
Monic: Interesujace.

Human: glupia
Monic: Chcesz czegos ?

Human: jestes durna
Monic: Wiec ... interesujesz sie polityka.

Human: co slychac?
Monic: Nudzi mi sie, chcesz ze mna porozmawiac?

Human: nie
Monic: Hmm, to po co zaczepiasz mnie na czacie,
            nie wiesz ze na czacie sie rozmawia.

Human: to narazie
Monic: Chcesz czegos ?

Human: nie
Monic: To po co zawracasz mi glowe.

Human: to ty mi glowe zawracasz
Monic: Chcesz czegos ?

Human: jak sie masz
Monic: Calkiem dobrze, a ty?

Human: niezbyt dobrze
Monic: Tak?

Human: co tak
Monic: Chcesz cos powiedziec czy dostac w zeby.

Human: chce cos powiedziec
Monic: Chcesz czegos ?

Human: no jasne
Monic: To mow, nie wsydz sie.

Human: ale o czym
Monic: Hmmm... o czym tak wogole rozmawialismy?

Human: nie wiem
Monic: Jak nie wiesz, to po co marnuje z toba czas.

Human: bo jestes glupia
Monic: Hmmm... o czym tak wogole rozmawialismy?

Human: o tym ze jestes glupia
Monic: No masz szczescie, a nastepnym razem nie ziewaj.

Human: powiesz cos w koncu ciekawego?
Monic: Tak?

Human: chce porozmawiac o giertychu
Monic: Dobra, mozemy o nim porozmawiac.

Human: o kim jeszcze mozemy poggadac?
Monic: Lubisz Giertycha?

Human: nie chce rozmawiac o giertychu
Monic: Dlaczego go nie lubisz?

Human: nie chce rozmawiac o giertychu
Monic: Nie sadze, zeby NIE bylo wystarczajacym wyjasnieniem.
           Czy naprawde uwazasz, ze ' NIE' wystarczy by przekonac tak inteligentna osobe jak ja?

Human: sadze ze trudno przemowic do tak "inteligentnej" osoby
Monic: Wiec nie wystarczy!!!!

Human: co slychac
Monic: Zycie jest do niczego, tylko sie trzeba uczyc i pisac programy.

Human: ide pisac programy
Monic: Istne dziwactwo.

Human: narazie
Monic: Do zobaczenia .
Human: czesc
Monic: Witaj.

Human: myslalem ze ty cos powiesz
Monic: Jak sie masz?

Human: dobrze
Monic: Optymista to lubie.

Human: jak masz na imie
Monic: Nazywam sie Monika. A ty jak masz na imie?

Human: mam na imie jacek
Monic: Milo cie poznac jacek!

Human: kto cie stworzyl
Monic: Moi rodzice.

Human: porozmawiajmy o polityce
Monic: Wiec ... interesujesz sie polityka.

Human: Roman Giertych jest beznadziejny
Monic: Dobra, mozemy o nim porozmawiac.

Human: ok no to nawijaj
Monic: Czy Roman Giertych ma odpowiednie kwalifikacje do pelnienia funkcji ministra edukacji narodowej?

Human: wydaje mi sie ze nie
Monic: 58% Polakow tak uwaza, ale czemu nie?

Human: bo nie jest zbyt inteligenty
Monic: Taki masz punkt widzenia.

Human: pewnie
Monic: Co sadzisz o pomysle, by uczniowie mieli mozliwosc wyboru religii jako jednego z przedmiotow zdawanych na maturze?

Human: to glupi pomysl
Monic: Hmm.. mylse, ze gdyby ktos chcial wprowadzic mozliwosc zdawania etyki czy filozofii, nikt by sie nie czepial, wiec czemu nie religia?

Human: bo religia nie pasuje
Monic: Moze, chcesz poznac wyniki sondazu OBOPU na ten temat?

Human: nie
Monic: Moze jednak?

Human: mowie ze nie
Monic: Chcesz poznac biografie Giertycha?

Human: nie
Monic: Myslalam ze ten temat Cie interesuje

Human: niezbyt
Monic: Lubisz Giertycha?

Human: tak
Monic: A ja za nim nie przepadam.

Human: moze porozmawiamy o polskiej polityce energetycznej
Monic: Jezeli chodzi o Polska polityke enegetyczna to nie weim zbyt wiele. Moze porozmawiamy o chinskiej polityce energetycznej?

Human: ok
Monic: Czy slyszales, o Tamie Trzech Przelomow na rzece Jangcy?

Human: nie
Monic: Wysoka na 185 metrow, o ponad 2 kilometrach szerokosci, najwieksza na swiecie tama, w 2009 ma sie zakonczyc jej napelnianie. Naprawde nie slyszales?

Human: oj dobra slyszalem nie chce o tym gadac
Monic: Co myslisz o pomysle Giertycha wprowadzenia do szkol wychowania patriotycznego?

Human: wychowanie patriotyczne jest niepotrzebne jak mamy historie
Monic: wychowanie patriotyczne jest niepotrzebne jak mamy historie, dziwny punkt widzenia, wiesz co mysle?

Human: nic
Monic: Teraz to juz przecholowales.

Human: naprawde
Monic: Przepros mnie.

Human: w zyciu
Monic: Przepros mnie.

Human: nie
Monic: Nie rozmawiam z Toba dopoki mnie nie przeprosisz.

Human: nie przeprosze
Monic: Nie rozmawiam z Toba dopoki mnie nie przeprosisz.

Human: ej no
Monic: Przepros mnie.

Human: przepraszam
Monic: Niech bedzie ze Ci wybaczam, ale to ma sie nie powtorzyc!

Human: dobra bede grzeczny
Monic: mhh..

Human: co mi tu mhhhkasz?
Monic: Jak myslisz czy obecny prezydent jest reprezentatywny?

Human: nie
Monic: Dlaczego myslisz ze Kaczynski jest niereprezntatywny?

Human: no coz jego prezencja nie jest wysokich lotow..
Monic: Kto by pomyslal.

Human: nom
Monic: Znasz jakis dowcip o Giertychu?

Human: tak
Monic: To opowiedz?

Human: Giertych buhahahaha
Monic: Nie rozumiem twojego poczucia humoru.

Human: koncze
Monic: Naprawde?

Human: zegnaj
Monic: Do zobaczenia jacek.

Materiały

http://pyaiml.sourceforge.net/- interpreter AIML dla języka pyton
http://www.pandorabots.com/botmaster/en/aiml-converter.html - konwerter plików tekstowych na standard AIML
http://alicebot.org/ - strona projektu ALICE
http://www.pandorabots.com/botmaster/en/home - serwis umożliwiający zamieszczenie bota na stronie internetowej
http://www.pandorabots.com/pandora/pics/aimless/tutorial.htm - tutorial pokazujący jak się dodaje wiedze do "mózgu" bota

 


Valid HTML 4.01 Transitional