|
||||||||||||||||||||||||||||||||||||
Spis treści
1. Opis problemuCelem projektu było stworzenie bota, który rozwiązuje proste zadania z matematyki (pola figur - prostokąt, kwadrat, trójkąt, trapez) oraz dodatkowo potrafi prowadzić konwersację w zakresie tematu (potrafi podać definicje, przykłady itp.) Bot składa się z dwóch części: bazy wiedzy oraz silinika przetwarzającego tą wiedzę. Baza wiedzy została utworzona w języku AIML, który został opracowany na potrzeby projektu ALICE. Skorzystałam z gotowego interpretera o nazwie ChatterBean. Efektem końcowym projektu jest bot o imieniu Matty. [spis treści]2. Przyjęte założeniaCo bot potrafi?
Jakie podstawowe słowa/dane rozpoznaje? Nazwy figur: prostokąt, kwadrat, trójkąt, trapez. Słowa związane z właściwościami figur: obwód, pole, bok, długość, szerokość, wysokość, podstawa, górna podstawa, dolna podstawa. Oczywiście język polski jest problematyczny i każde słowo ma jeszcze odmiany, które również należy uwzględnić. Jest to dosyć kłopotliwe. Należy więc zwrócić uwagę, w jakich przypadkach najczęściej używane są poszczególne słowa w treściach zadań i na tych przypadkach się skupić. [spis treści]3. RozwiązanieBaza wiedzy została zdefiniowana w języku AIML (Artificial Intelligence Markup Language), który jest dialektem języka XML. Podstawową jednostką wiedzy w AIML jest kategoria, składająca się z pytania zwanego wzorcem (pattern) i odpowiedzi nazywanej szablonem (template) oraz opcjonalnego kontekstu(<topic>, <that>) jak i synonimów.3.1. AIML - struktura plikuKażdy plik, który będzie zawierał fragment bazy wiedzy ma następującą strukturę: <?xml version="1.0" encoding="UTF-8" ?> <aiml version="1.0"> Wszelkie wypowiedzi bota będą następnie umieszczane w obrębie głównego znacznika <aiml> 3.2. AIML - schemat budowania wypowiedziWszystkie wypowiedzi bota definiujemy w następujący sposób: <category> <pattern>CZESC</pattern> <template>Witaj</template> </category> W tym prostym przykładzie wzorcem jest słowo "Czesc". Jeżeli je wpiszemy, to w odpowiedzi otrzymamy słowo "Witaj", które tutaj jest szablonem. Przy pomocy tej prostej struktury oraz dodatkowych mechanizmów, o których będzie mowa za chwilę, można zbudować bazę wiedzy bota. 3.3. AIML - wykorzystane mechanizmyKontekst - znaczniki <that>, <topic> Ważnym elementem języka AIML jest tzw. kontekst, pozwala on rozróżnić pomiędzy kategoriami w przypadku jednakowego wzorca. Istnieją dwie możliwości zdefiniowania kontekstu. Pierwsza z nich to zastosowanie znacznika <that>: <category> <pattern> * </pattern> <that>JAK MASZ NA IMIE</that> <template> Witaj <star />! </template> </category> Powyższy wzorzec dopasuje się tylko wtedy, gdy wcześniejszą wypowiedzią bota było "Jak masz na imie". Druga możliwość zdefiniowania kontekstu polega na ustawieniu tematu. Jeżeli jakieś kategorie zdefiniujemy w obrębie tagów <topic name="PROSTOKAT"> </topic> to wzorzec zostanie dopasowany tylko wtedy, gdy zmienna topic będzie miała wartość "PROSTOKAT". A jak ustawić zmienną topic? Należy użyć <set name="topic"> PROSTOKAT </set> Synonimy - znacznik <srai> Synonimy w języku AIML pozwalają w niektórych przypadkach zaoszczędzić pisania. Oczywiste jest, że chcielibyśmy, żeby bot reagował na zdania sformułowane w różny sposób, ale mające to samo znaczenie. Dzięki synonimom wystarczy raz zdefiniować szablon odpowiedzi. <category> <pattern>CZESC</pattern> <template>Witaj</template> </category> <category> <pattern>WITAM</pattern> <template> <srai>CZESC</srai> </template> </category> Powyższy zapis oznacza, że wzorzec "WITAM" jest synonimem wzorca "CZESC". W przypadku wpisania slowa "WITAM", bot przeszuka bazę wiedzy w poszukiwaniu słowa "CZESC". Losowe odpowiedzi - znacznik <random> Warto wykorzystać ten mechanizm. Dzięki niemu zróżnicujemy odpowiedzi i na to samo pytanie bot będzie udzielał różnych odpowiedzi (wybranych losowo ze zdefiniowanej listy). <category> <pattern>CZESC</pattern> <template> <random> <li>Witaj</li> <li>Czesc, co slychac?</li> <li>Jak sie masz?</li> <li>Dzien dobry </li> </random> </template> </category> Zmienne - znaczniki <get> i <set> W AIML istnieje także możliwość zapisywania i odczytywania zmiennych. <category> <pattern>MAM NA IMIE *</pattern> <template> <set name="UserName"> <star /> </set> </template> </category> <category> <pattern>CZY PAMIETASZ JAK MAM NA IMIE</pattern> <template> Oczywiscie! Masz na imie <get name="UserName"> </template> </category> Najpierw ustawiamy wartość zmiennej o nazwie UserName. Do tak zdefiniowanej zmiennej można się później odwoływać. Wyrażenia warunkowe - znacznik <condition> Można też uzależnić odpowiedź bota od wartości pewnej zmiennej. Przykładowo<category> <pattern>*</pattern> <that>CZY JUZ ROZUMIESZ</that> <template> <think> <set name="odp"> <star index="1"/> </set> </think> <condition name="odp"> <li value="tak">Bardzo sie ciesze!</li> <li value="nie">Ohhh.. Nie wiem jak jeszcze mam ci to tlumaczyc.</li> <li value="prawie">Mhm..</li> <li value="tak sobie">No dobrze, przejdzmy zatem dalej.</li> <li>Hmm..</li> </condition> </template> </category> W kolejnych elementach listy porównywana jest wartość zmiennej odp i na przykład jeżeli użytkownik powiedział "tak", to bot odpowie "Bardzo sie ciesze!" itd. 3.4. Interpreter języka AIMLPostanowiłam skorzystać z gotowego interpretera języka AIML, aby móc skupić się jedynie na definiowaniu wzorców. Wydawało mi się, że skoro jest ustalony standard AIML, to nie będzie z tym problemu. Okazuje się jednak, że wybór interpretera języka AIML wcale nie jest prosty. Dostępnych jest wiele interpreterów, które są napisane w różnych językach i w różnych formach. Można się z nimi zapoznać tutaj. Na początku postanowiłam skorzystać z silnika o nazwie Program# napisanego w języku C#, jednak okazało się, że nie do końca poprawnie parsuje on zdania. Problem pojawia się wtedy, gdy we wzorcu znajduje się więcej gwiazdek (gwiazdka * oznacza dopasowanie dowolnego ciągu liter). W języku AIML można odwoływać się do gwiazdek w następujący sposób: <star index="" />. Atrybut index oznacza oczywiście numer gwiazdki. Program# numeruje gwiazdki od końca, co jest niezgodne ze standardem. Kolejnym wybranym przeze mnie interpreterem był ProgramQ napisany w C++. Wybór ten również nie był dobry, gdyż szybko okazało się, że interpreter ma problem z uwzględnianiem kontekstu (znacznik <that>). Ostatecznie skorzystałam z interpretera o nazwie ChatterBean napisanego w Javie. Okazało się, że najlepiej pasuje do wykonania tego zadania (chociaż też nie jest idealny, ale o tym później). Jednym z jego plusów jest to, że potrafi wykonywać proste działania na liczbach (znacznik <system>). [spis treści]3.5. Baza wiedzy botaPodstawowa wiedza bota zdefiniowana jest w następujących plikach: ogolne.aiml, prostokat.aiml, trojkat.aiml, trapez.aiml, kwadrat.aiml. Każdy plik dotyczący figury składa się z trzech części:
Wzorce dla zadań zostały zdefiniowane w oparciu o zadania ze zbioru "Mogę zostać Pitagorasem" oraz podręcznika "Matematyka 5". [spis treści]4. Przykłady rozmówRozmowa 1. (udana)
> Czesc Rozmowa 2. (nieudana)
> czesc Rozmowa 3. (udana)
> witaj Rozmowa 4. (nieudana)
> hej 5. Testy, wynikiTestowanie odbyło się w dwóch fazach. W trakcie tworzenia bazy wiedzy przeprowadzane były testy robocze (na podstawie zbioru "Mogę zostać Pitagorasem" oraz podręcznika "Matematyka 5"). Wykorzystane zadania znajdują się w pliku o nazwie "zadania-1.txt". Po utworzeniu bazy wiedzy nastąpiła druga faza testów. Druga faza testów polegała na wprowadzeniu dużej ilości zadań. Zadania zostały zaczerpnięte ze zbioru "Matematyka dla Ciebie" oraz z internetu. Ponadto poprosiłam kilka osób, żeby same wymyśliły po kilkanaście zadań. Zależało mi na tym, aby zadania wykorzystane do testów końcowych były zróżnicowane - dwie osoby mogą napisać treść do takiego samego zadania na dwa różne sposoby (np. inne słowa, inna kolejność podawania danych). Zadania wykorzystane do testów końcowych zostały zgromadzone w pliku o nazwie "zadania-2.txt". Wyniki testów
Brak rozwiązania oznacza, że bot nie znalazł w bazie wiedzy żadnego wzorca, który pasowałby do podanej treści zadania. Ta sytuacja występowała najczęściej w zadaniach na pola trapezu. Ze złym dopasowaniem wzorca mamy do czynienia wtedy, gdy bot dopasował jakiś wzorzec i rozwiązał zadanie, jednak to rozwiązanie nie do końca było poprawne (np. w treści zadania było pytanie o obwód i bok kwadratu, a bot podał tylko obwód itp.) albo jako odpowiedź zwrócił null (oznacza to, że wzorzec został dopasowany, ale w miejscu, gdzie miała wystąpić liczba pojawiła się np. liczba+wyraz i to wywołało błąd). Złe rozwiązanie zadania zdarza się wtedy, kiedy bot dobrze dopasuje wzorzec, ale wynik liczbowy jest zły. Okazuje się, że taka sytuacja może mieć miejsce. Dzieje się tak przykładowo wtedy, gdy wszystkie dane liczbowe są całkowite, a wynik jest liczbą niecałkowitą - wynik jest wtedy niedokładny, gdyż nie zawiera informacji o części ułamkowej. Jest to jednak specyfika wybranego interpretera, a nie złej bądź niewystarczającej definicji wzorców. Niemniej jednak podanie niedokładnego wyniku traktowane jest jako błąd. [spis treści]6. WnioskiO czym świadczą otrzymane wyniki? Bot dosyć dobrze poradził sobie z rozwiązaniem ponad 200 zadań i osiągnął 75% skuteczności. Najczęściej oczywiście nie mógł dopasować wzorca, jednak zdarzały się też sytuacje, w których dopasował zły wzorzec. Okazuje się, że najłatwiejsze były dla niego zadania dotyczące kwadratu, co jest logiczne, gdyż w tych zadaniach potrzebnych jest najmniej danych (przeważnie jedna liczba). Treści zadań są więc do siebie zbliżone. Najtrudniejszymi zadaniami były te dotyczące trapezu, gdyż tam jest najwięcej danych (przeważnie trzy liczby). Jest dużo różnych sformułowanie tego samego zadania, dlatego częściej zdarzało się, że bot nie potrafił dopasować wzorca. Zadania możemy uszeregować według poziomu trudności w następujący sposób:
Skuteczność działania bota pokrywa się z powyższą listą. Co można, a czego nie można zrobić za pomocą języka AIML, czyli napotkane problemy Definicja wzorca jest bardzo prosta. Można wykorzystać znaki * lub _ , które oznaczają dowolny ciąg znaków (ChatterBean uznaje za dowolny ciąg znaków także ciąg pusty, w przypadku innych interpreterów może być inaczej). Jest to kłopotliwe, gdyż nie można zaznaczyć, że w danym miejscu będzie liczba. Dlatego też podanie danych liczbowych w treści zadania wymaga poinformowania o tym bota. W ten sposób unika się sytuacji, w których następuje próba wykonania operacji dodawania na ciągu liter, ponieważ został on potraktowany jako liczba. Możliwość wykorzystania wyrażeń regularnych do definicji wzorca znacznie uprościłaby to zadanie. Pojawia się też problem z liczbami rzeczywistymi. Większość interpreterów potraktuje liczbę 5.6 (lub 5,6) jako 5, gdyż kropka (przecinek) będzie oznaczać nowe zdanie. Interpreter ChatterBean akurat poprawnie interpretuje takie sytuacje, ale jeżeli otrzyma dwie liczby całkowite, a wynikiem będzie liczba rzeczywista, to poda on niedokładny wynik. W tym przypadku wina leży akurat po stronie interpretera, a nie samego języka AIML. Czy wybór metody rozwiązania problemu był dobry? Zadanie okazało się trudniejsze, niż wydawało mi się na początku. Już w trakcie pracy nad projektem pojawiły się drobne problemy (o których pisałam w raporcie), które miały duży wpływ na całość realizacji. Jednak wydaje mi się, że wybór metody był dobry, ale... gdybym miała ponownie rozwiązać taki problem używając języka AIML, to zaczęłabym od napisania własnego interpretera, który zostałby dostosowany do tego konkretnego zadania. Przede wszystkim umożliwiałby on poprawne wykonywanie działań (mniej i bardzie skomplikowanych, także z nawiasami). Ponadto dodałabym możliwość używania wyrażeń regularnych w definicjach wzorców. Znacznie ułatwiłoby to realizację projektu, ale niestety nie byłby to już język AIML zgodny z opracowanym standardem. [spis treści]7. Wykorzystane materiały i narzędzia
Ponadto ważną rolę odegrał zbiór zadań dla klasy 5 "Mogę zostać Pitagorasem" (W.Łęska, S.Łęski), podręcznik "Matematyka 5" (M.Dobrowolska) oraz zbiór zadań "Matematyka dla Ciebie" (K.Gałązka). [spis treści] |
||||||||||||||||||||||||||||||||||||
|