====== - LAB: Regułowe systemy ekspertowe ======
Celem ćwiczenia jest zapoznanie się z regułową reprezentacją wiedzy i systemami ekspertowymi, które je wykorzystują.
===== - Do przygotowania =====
* Przejrzeć [[http://clipsrules.sourceforge.net/documentation/v624/bpg.htm|instrukcję do CLIPSa (sekcje 1-5)]] -- **NIE** będzie tego na kartkówce i kolokwium, ale chcemy mieć pojęcie o zasadzie działania CLIPSa, bo będziemy z niego korzystać na zajęciach (mile widziany skrót instrukcji na wiki)
* [[https://docs.jboss.org/drools/release/5.5.0.Final/drools-expert-docs/html_single/#d0e23|Sekcja 1 z podręcznika Droolsa]]
* {{https://ai.ia.agh.edu.pl/wiki/_media/pl:dydaktyka:psi:labs:negnevitsky-chapter2-rbs.pdf|Chapter 2: Rule-based expert systems}} z podręcznika [[https://www.amazon.com/Artificial-Intelligence-Guide-Intelligent-Systems/dp/0321204662/|Artificial Intelligence: A Guide to Intelligent Systems]]
* [[https://natemat.pl/blogi/ryszardtadeusiewicz/145591,systemy-ekspertowe-swiatlo-ludzkiej-madrosci-w-archipelagu-sztucznej-inteligencji|Wpis o systemach ekspertowych na blogu prof. Tadeusiewicza]]
===== - Wstęp =====
W systemie ekspertowym można wyróżnić następujące elementy:
* baza wiedzy, czasami dzielona na: właściwą bazę wiedzy (czyli tą którą system dysponuje stale, od początku/uruchomienia) i bazę faktów, które system odkrywa, dostaje, wypracowuje,
* mechanizm wnioskujący, który przeprowadza właściwy proces wnioskowania, tj. odnajduje rozwiązanie/odpowiedź
* mechanizm wyjaśniający, dlaczego jest to odpowiedź poprawna/dopuszczalna,
* interfejs użytkownika, pozwalający na komunikację z systemem.
Rysunek 1: Struktura Systemu Ekspertowego.
{{:pl:prolog:prolog_lab:expert-systems-arch.png}}
===== - CLIPS =====
==== Rodzina ====
- Ściągnij plik {{:pl:dydaktyka:psi:labs:family1.clp.zip|}}
- Po ściągnięciu pliku należy zawartą w nich wiedzę wczytać do bazy wiedzy a następnie uruchomić wnioskowanie przy pomocy komendy:clips -f family1.clp
- Po poprawnym załadowaniu na ekranie powinna ukazać się lista zdefiniowanych faktów.
- Tutaj także warto zwrócić uwagę czy nie wystąpiły jakieś błędy.
W CLIPS-ie mamy dostępne wnioskowanie w przód, a więc na podstawie istniejących faktów sprawdzane będą warunki reguł i te reguły, których warunki są spełnione zostaną uruchomione. Cykl ten powtarza się aż do momentu kiedy żadna reguła nie zostanie uruchomiona. Informacją wejściową dla algorytmu wnioskowania w przód jest **zbiór faktów** w bazie wiedzy.
* Na podstawie otrzymanego rezultatu uruchomienia wnioskowania odpowiedz na następujące pytania:
* Jakie reguły są uruchamiane?
* Jakie fakty aktywują te reguły?
* Jak wyjaśnić otrzymany rezultat?
* Ile faktów zostało dodanych do bazy wiedzy w trakcie wnioskowania?
* Czy takiego wyniku można było się spodziewać?
Aby reguła opisująca **dziecko** mogła zostać uruchomiona należy zdefiniować regułę dodającą do bazy wiedzy fakt mówiący kto jest **rodzicem** kogo (zmiana bazy wiedzy spowoduje uruchomienie kolejnego cyklu wnioskowania):
(defrule rodzic
(or (mama ?x ?y) (tata ?x ?y))
=>
(assert (rodzic ?x ?y))
)
Uruchom wnioskowanie ponownie i odpowedz na pytania:
* Ile teraz jest faktów w bazie CLIPS-a?
* Jakie są aktywacje reguł w CLIPS-ie przed rozpoczęciem wnioskowania (rezultat wywołania funkcji ''(agenda)'')?
* Dlaczego wśród nich nie ma reguł definiujących **dziecko**?
**Zadanie 1** \\
Rozbuduj bazę reguł dodając do niej reguły definiujące relacje rodzinne takie jak
* ''syn'', ''corka''
* ''malzenstwo''
* Dwie osoby są małżeństwem jeżeli:
* są różnej płci,
* mają wspólne dziecko.
* Definiując regułę przy pomocy powyższych warunków, algorytm wnioskowania wyszuka nam tylko małżeństwa posiadające dzieci. Małżeństwa, które nie posiadają dzieci są niemożliwe do znalezienia na podstawie dostępnej wiedzy.
* ''rodzenstwo''
* Dwie osoby są rodzeństwem jeżeli
* mają wspólnego rodzica
* są dwiema różnymi osobami
* ''dziadkowie'', ''dziadek'', ''babcia''
* ''wnuk'', ''wnuczka'', ''wnuczek''
* ''kuzynostwo''
* ''ciocia'', ''wujek''
* Jak przy pomocy reguł definiujących **siostrę** oraz **rodzica** zdefiniować pojęcie **ciocia**?
* Jak przy pomocy reguł definiujących **brata** oraz **rodzica** zdefiniować pojęcie **wujek**?
==== Truth maintenance ====
Truth Maintenance System w systemach regułowych jest odpowiedzialny za utrzymanie spójności wiedzy w nich zawartych.
Niespójność może być różna: niespójność logiczna wiedzy, niespójność materialna (w odniesieniu do interpretacji wiedzy w przyjętym świecie).
* Czym różnią się te rodzaje niespójności :?:
* Które z nich mogą wystąpić w systemach produkcyjnych :?:
- Ściągnij plik {{:pl:dydaktyka:psi:labs:family2.clp.zip|}}
- Otwórz i zapoznaj się z jego zawartością. Zwróć uwagę na:
* Definicję faktów ''wiek'' określających wiek danej osoby.
* Definicję modułów ''defmodule'' - jaką rolę odgrywają moduły :?:
* Dwie reguły zdefiniowane w pliku:
* ''przyznaj-bilet::bilet-uczen'' która dla każdej niepełnoletniej osoby w dodaje fakt mówiący, że należy się jej bilet dziecięcy. Następnie reguła ta wyświetla kompletną listę faktów znajdujących się w bazie wiedzy.
* ''zwieksz-wiek::zwieksz'' która zwiększa wiek dla danej osoby.
- Uruchom ściągnięty plik. Aby łatwiej było przeglądać rezultaty wyświetlane podczas uruchomienia, można użyć następującej komendyclips -f family2.clp | less
Zaobserwuj jak zwiększany jest wiek poszczególnych osób oraz zidentyfikuj moment kiedy dodawany jest fakt typu ''bilet''. Jakiego typu i dla kogo ten bilet jest dodawany :?:
**Zadanie 1** \\
Zdefiniuj regułę ''przyznaj-bilet::bilet-dorosly'' w analogiczny sposób jak zdefiniowana została reguła ''przyznaj-bilet::bilet-uczen''.
Uruchom otrzymany model i zaobserwuj jakie bilety istnieją w bazie wiedzy na końcu procesu wnioskowania.
* Jak wyjaśnić taki rezultat :?:
* Czy baza wiedzy w takim wypadku jest spójna :?:
**Zadanie 2** \\
Popraw otrzymany model poprzez zastosowanie mechanizmu //Truth Maintenance System//
* Jaka konstrukcje języka CLIPS umożliwia jego wykorzystanie :?:
* Po poprawnym zastosowaniu mechanizmu na końcu wnioskowania powinien być dokładnie jeden fakt opisujący bilet dla każdej osoby.
* Wśród wyświetlanych wiadomości wskaż miejsca, gdzie usuwane są //niepotrzebne// bilety.
===== - Drools (dla zainteresowanych) =====
==== Model systemu PLOC ====
Celem systemu jest określenie wysokości składki ubezpieczenia na podstawie danych wejściowych. Danymi wejściowymi dla systemu są dane na temat kierowcy: wiek, okres posiadania prawo jazdy, liczba wypadków w ostatnim roku, dotychczasowa klasa ubezpie- czeniowa. Kolejnym elementem istotnym przy wyliczaniu składki ubezpieczenia są dane na temat pojazdu: pojemność silnika, wiek samochodu, liczba miejsc, badanie techniczne. Ostatnim elementem są zniżki oraz zwyżki za: liczbę rat, inne ubezpieczenia, ciągłość ubezpieczenia, liczbę samochodów ubezpieczonych. Wyliczenie składki ubezpieczenia przebiega w trzech etapach. Pierwszym etapem jest ustalenie stawki podstawowej na podstawie pojemności samochodu. Dane o wysoko- ści składki podstawowej są podane dla rejestracji w Szczecinie. Drugim etapem jest tzw. tabela bonus malus. Zawarte w niej są zniżki i zwyżki wynikające z bezszkodowego prze- biegu ubezpieczenia. Towarzystwa ubezpieczeniowe udzielają maksymalnie 60 % zniżki z tego tytułu. Za każdy bezszkodowy 12 miesięczny okres ubezpieczenia, klient przesuwa się o jedną klasę w dół tabeli. Trzecim etapem jest uwzględnienie pozostałych zniżek i zwyżek m.in. za wiek, dodatkowe ubezpieczenia itp.
Kompletna lista reguł:
{{:pl:dydaktyka:psi:labs:pl-oc.pdf|}}
==== Uruchomienie modelu ====
- Ściągnij plik {{:pl:dydaktyka:psi:labs:ploc-drools.drl.zip|}}
- W celu uruchomienia bazy wiedzy zapisanej w ściągniętym pliku, uruchamiamy narzędzie Eclipse i tworzymy nowy projekt:
- Tworzymy nowy projekt ''File'' ⇒ ''New'' ⇒ ''Project...''.
- Na liście odnajdujemy pozycję ''Drools'' i ją rozwijamy.
- Wybieramy ''Drools Project''
- Klikamy ''Next >''
- W kolejnym korku kreatora podajemy nazwę projektu np. ''DroolsTest''.
- Klikamy ''Next >''
- W kolejnym kroku pozostawiamy zaznaczone tylko dwie pierwsze opcje.
- Klikamy ''Next >''
- W kroku ''Drools Runtime'' z listy ''Generate code compatible with:'' wybieramy ''Drools 5.1 or above''.
- Klikamy ''Finish''
- W worksspace pojawia się nam nowy projekt do którego dodajemy klasy pozwalające na uruchomienie projektu:
- Rozwijamy drzewo projektu ''DroolsTest'' ⇒ ''src'' ⇒ ''main'' ⇒ ''java'' ⇒ ''com'' ⇒ ''sample''.
- Klikamy na plik ''*.java''. W tym pliku:
* Usuwamy definicję klasy ''Message''
* Usuwamy w funkcji ''main'' wszystkie linie, które korzystają z instancji tej klasy.
* Zmieniamy nazwę pliku z regułami z ''Sample.drl'' na ''ploc-drools.drl''.
* Do głównej klasy dodajemy definicję typu enumerowanego:
public enum PaymentType {
single, instalments
}
- Rozwijamy drzewo projektu ''DroolsTest'' ⇒ ''src'' ⇒ ''main'' ⇒ ''rules''.
- Usuwamy plik ''Sample.drl''.
- W miejsce usuniętego pliku dodajemy wcześniej ściągnięty plik ''ploc-drools.drl'':
- Klikamy prawym przyciskiem na pobrany plik i wybieramy ''Kopiuj''.
- Klikamy prawym przyciskiem na katalog ''rules'' i menu kontekstowego wybieramy opcję ''Wklej''.
- Wybieramy polecenie ''Run as'' ⇒ ''Java application''.
- Jeżeli wszystko przebiegło pomyślnie to w konsoli środowiska Eclipse powinny pojawić się komunikaty generowane przez reguły.
==== Zadania ====
**Zadanie 1** \\
Wśród uruchamianych reguł można zauważyć, że atrybut ''DriverClass'' klasy ''Driver'' jest zwiększany wielokrotnie:
* Czy jest to poprawne zachowanie :?: Jeżeli nie, to dlaczego i jakie powinno być poprawne :?:
* Jak sprawić aby tylko jedna z tych reguł została uruchomiona :?: \\ //Wskazówka: poczytaj o możliwych atrybutach reguł i spróbuj znaleźć ten który pozwoli osiągnąć żądany efekt: [[http://docs.jboss.org/drools/release/6.0.1.Final/drools-docs/html_single/#d0e6643|atrybuty reguł]]//
**Zadanie 2** \\
Model bazy wiedzy jest niekompletny i zawiera tylko część reguł z modułu ''base-charge-modifiers'' (''agenda-group "base-charge-modifiers"'').
Na podstawie definicji innych reguł dopisz 4 ostatnie reguły podwyższające cenę ubezpieczenia zawarte w pliku {{:pl:dydaktyka:psi:labs:pl-oc.pdf|}} tzn.:
- liczba miejsc pojazdu (6-9): +20%,
- brak wałnego badania technicznego: +20%,
- opłata na 2 raty: +10%,
- brak zaświadczenia o przebiegu ubezpieczenia: +60%.
**Zadanie 3** \\
Dopisz regułę, która po przyznaniu wszystkich zniżek i zwyżek obliczy wartość końcową polisy ubezpieczenia.
* Zdefiniuj tą regułę jako element modułu ''calculation'' (agenda-group "calculation").
* W definicji reguły można wykorzystać element ''accumulate''.
* Reguła ta ma zapisywać wartość polisy w polu ''Value'' obiektu typu ''Result''.
* Reguła powinna wyświetlać finalną wartość do zapłaty.
* Poprawna wartość, jaka powinna zostać obliczona to: ''865.95''.
**Zadanie 4*** \\
Spróbuj zdefiniować powyższą regułę bez użycia ''accumulate''.