Metody rozumowania dla Semantic Webkopel/mgr/2016.06 mgr Woronko.pdf · Przegląd dziedziny...
Transcript of Metody rozumowania dla Semantic Webkopel/mgr/2016.06 mgr Woronko.pdf · Przegląd dziedziny...
1
Wydział Informatyki i Zarządzania
kierunek studiów: Informatyka
specjalność: Internet i technologie mobilne
Praca dyplomowa - magisterska
Metody rozumowania dla Semantic Web
Marcin Józef Worońko
słowa kluczowe:
Wnioskowanie, Reasoner, Reasoner Hybrydowy
krótkie streszczenie: Praca dotyczy metod wnioskowania dla Semantic Web a w
szczególności opracowania hybrydowej metody wnioskowania. Pierwsza część pracy
to przegląd dziedziny rozwiązań, natomiast druga skupia się na opracowaniu hybrydy.
opiekun pracy
dyplomowej
Dr Marek Kopel ....................... .......................
Tytuł/stopień naukowy/imię i nazwisko ocena podpis
Do celów archiwalnych pracę dyplomową zakwalifikowano do:*
a) kategorii A (akta wieczyste) b) kategorii BE 50 (po 50 latach podlegające ekspertyzie)
* niepotrzebne skreślić
pieczątka wydziałowa
Wrocław 2016
2
Streszczenie ............................................................................................................................................................. 3
Abstract ................................................................................................................................................................... 3
Przegląd dziedziny rozwiązań ................................................................................................................................. 4
Reprezentacja wiedzy i metadanych (RDF i RDFS) ......................................................................................................... 4
Reprezentacja ontologii czyli język OWL ......................................................................................................................... 4
Reprezentacja reguł za pomocą SWRL ............................................................................................................................. 5
Język zapytań SPARQL ...................................................................................................................................................... 6
Wnioskowanie ...................................................................................................................................................................... 8
Wnioskowanie - praktyka ................................................................................................................................................. 10
Zastosowanie metod wnioskowania ................................................................................................................................. 13
Wyszukiwanie informacji np. wyszukiwarka internetowa .................................................................................................... 14
Semantyczna encyklopedia „Semantic Wiki” ...................................................................................................................... 16
Zastosowania nietypowe, nie wpisujące się w poprzednie kategorie ................................................................................... 17
Czemu warto szukac nowych metod wnioskowania w Semantic Webie ? ........................................................... 18
Słabe i mocne punkty istniejących metod wnioskowania w kontekście semantic weba ....................................... 19
Forward chaining semantic reasoner- jak działa i co można usprawnić ................................................... 19
Backward chaining semantic reasoner- jak działa i co można usprawnić ................................................. 21
Porównanie obu podejść pod kątem złożoności obliczeniowej i narzutu pamięci ..................................... 23
Dodatkowe heurystyki potencjalnie usprawniające hybrydę znanych metod wnioskowania .................. 23
Badania czasów wnioskowania w przód i w tył istniejących reasonerów ............................................................. 24
OWLViz i badania na ontologii Wine ........................................................................................................... 26
Badania reasonerów wykorzystujących wnioskowanie w przód ................................................................ 28
Badania reasonerów wykorzystujących wnioskowanie w tył (backward chaining) ................................. 32
Zaproponowanie heurystyki i implementacja w wybranym środowisku .............................................................. 33
Implementacja reasonera do wnioskowania w przód ............................................................................................ 35
Krótkie omówienie szczegółów implementacji wnioskowania w przód ..................................................... 36
Implementacja reasonera do wnioskowania w tył ................................................................................................. 38
Krótkie omówienie szczegółów implementacji wnioskowania w tył ........................................................... 39
Implementacja reasonera hybrydowego ................................................................................................................ 40
Krótkie omówienie szczegółów implementacji wnioskowania hybrydowego ............................................ 41
Wyniki badań własnej implementacji ................................................................................................................... 41
Podsumowanie ...................................................................................................................................................... 45
Bibliografia: .......................................................................................................................................................... 46
3
Streszczenie
Praca dotyczy metod wnioskowania dla Semantic Web a w szczególności opracowania
hybrydowej metody wnioskowania. Pierwsza część pracy to przegląd dziedziny rozwiązań.
Zawiera ona parę słów na temat dzisiejszego stanu rozwiązań w zakresie reprezentacji
wiedzy, silników wnioskowania oraz badania istniejących już implementacji reasonerów.
Druga część natomiast to próba opracowania hybrydy popularnych metod udowadniania
hipotez czyli wnioskowania w przód i wstecz. Zawierają sie tam również badania stworzonej
implementacji jak również analiza porównawcza w zakresie wydajności z istniejącymi już
rozwiązaniami.Na końcu zawarte zostało podsumowanie i sugestie jak ową pracę można w
przyszłości kontynuować.
Abstract
The master thesis concerns the methods of reasoning for the Semantic Web and in particular
the development of hybrid inference methods. The first part is an overview of the field of
solutions. It contains a few words about the present state of solutions for knowledge
representation, inference engines, and research existing reasoner implementations. The
second part is an attempt to develop a hybrid method of proving hypotheses based on forward
and backward chaining. This paper also includes survey of implementation as well as a
comparative analysis of the efficiency with existing solutions. Summary and suggestions how
this work can be continued in the future is contained at the end of master thesis.
4
Przegląd dziedziny rozwiązań
Reprezentacja wiedzy i metadanych (RDF i RDFS)
RDF (Resource Description Framework) to model, który służy do opisywania zasobów
identyfikowanych przez URI. Opis zasobu jest to zbiór stwierdzeń. Każde stwierdzenie
określa właściwość zasobu. Stwierdzenie określa również wartość tej właściwości. Struktura stwierdzenia przybiera
postać krotki złożonej z 3 elementów- [podmiot, predykat, obiekt], reprezentowanej, np. Za
pomocą grafu przedstawionego na poniższym rysuku.
Graf struktury danych w RDF
RDFS pozwala tworzyć taskonomie klas, oraz taksonomie relacji. Umożliwia również
określanie ascojacji między klasami za pomocą relacji. Właściwość rdf:type daje nam
również możliwość typowania zasobów i posługiwanie się obiektami klas.
Reprezentacja ontologii czyli język OWL
Język OWL (Web Ontology Language) to standard W3C. Jego przeznaczenie to
definiowanie znaczenia dokumentów przez uściślanie wiedzy dziedzinowej. Łączy on zalety RDF i RDFS. Składnia opiera się na języku XML, chociaż posiada sporo
form zapisu. Dzięki OWL możemy tworzyć ontologie jako zbiory definicji pojęć, cech jak
również obiektów (instancji) i relacji.
OWL posiada wielopoziomową strukturę. Struktura ta składa się z następujących warstw:
5
OWL Lite:
Umożliwia tworzenie teaskonomii pojęć ontologicznych.
Umożliwia nakładanie ograniczeń na relacje
Niestety nie umożliwia formułowania konstruktorów klas
OWL DL (OWL Description Logics):
Pod kątem znaczenia jest to odpowiednik logik deskrypcyjnych
W przeciwieństwie do OWL Lite daje możliwość tworzenia konstruktorów klas, dzięki
możliwości nakładania wielu ograniczeń
Można powiedzieć, że jest to najczęściej wykorzystywania warstwa w
Sieciach Semantycznych
OWL Full:
Składa się z konstruktorów które nie mają ograniczeń. W konsekwencji przynosi to
fatalną efektywność oraz brak rozstrzygalności.
Nie możemy tutaj również mówić o formalnie zdefiniowanej semantyce.
Jak widać ontologie OWL mogą składać się z modułów oraz być tworzone na różnych
poziomach szczegółowości. OWL używa wielu rozpowszechnionych języków znaczników
(XML, XSD, RDF), które służą definiowaniu znaczenia pewnych bytów np. dokumentów.
Zastosowanie takiej notacji procentuje potem możliwością integracji naszych reprezentacji
bytów z innymi popularnymi notacjami np. omawianym w dalszej części SWRL.
Reprezentacja reguł za pomocą SWRL
Język SWRL (Semantic Web Rule Language)- języka reprezentacji reguł, zaproponowany
przez W3C. Wykorzystuje się go do zapisu reguł semantycznych. SWRL w swojej budowie
rozszerza aksjomaty języka OWL. Dodaje reguły przedstawiane w postaci klauzul Horna.
Owe klauzule mogą operować na pojęciach ontologicznych.
6
Budowa reguły przedstawia się następująco:
Ciało które, reprezentuje warunki
Głowa która, (określa konsekwencje wystąpienia warunków).
Interpretacja wyniku reguły przedstawia się następująco: zazwyczaj tożsama jest z dodaniem
nowego faktu do bazy wiedzy. Pozwala to na zastosowanie nowych reguł.
Rysunek 1. Położenie warstwy SWRL w kontekście innych pojęć związanych z
wnioskowaniem semantycznym. Źródło: [14]
Język zapytań SPARQL
Język SPARQL (SPARQL Protocol And RDF Query Language) jest językiem zapytań do
danych (trochę jak SQL). Dane jednak nie są przechowywane w relacyjnej bazie danych, ale
w formacie RDF. SPARQL pozwala na formułowanie zapytań. Zapytania te przybierają
postać grafów RDF. Grafy owe zawierają wiedzę pochodzącą z danych. Zapytania to trójki
RDF które uwzględniają słowa kluczowe języka SPARQL. Poniżej przedstawię trzy
podstawowe części zapytania SPARQL:
• Część prefiksów. Tutaj definiujemy adresy URI danych i ontologii lub innych bytów.
• Część która opisuje rodzaj zapytania- analogicznie do SQL- np. SELECT.
• Część wzorca (trójki RDF) oraz dodatki takie jak np. FILTER, ORDER BY,itp.
7
Rysunek 2. Położenie warstwy SPARQL w kontekście innych pojęć związanych z
wnioskowaniem semantycznym. Źródło: [13]
8
Wnioskowanie
Istotą moich badań będzie uzyskiwanie nowych faktów za pomocą wnioskowania. Cel ten do
realizacji wymaga algorytmów wnioskujących. Istnieje wiele reasonerów które umożliwiają
uwzględnienie w cyklu wnioskowania, wiedzy opisanej za pomocą ontologii. Podczas
udzielania odpowiedzi na zapytania owa wiedza jest również brana pod uwagę przed
zwróceniem ostatecznego wyniku. W istniejących algorytmach przyjęło się stosować
mechanizmy wnioskowania w przód, wstecz i hybrydowe.
Z istniejących silników, które umożliwiają wnioskowanie bądź konstruowanie i
wykonywanie zapytań w SPARQL warte wymienia są:
Pellet – open Sourceowe rozwiązanie. Umożliwia wnioskowanie wykorzystujące
RDFS, OWL, SWRL (https://www.w3.org/2001/sw/wiki/Pellet)
KAON2– rozwiązanie niekomercyjne. Umożliwia wnioskowanie wykorzystujące
RDFS, OWL, SWRL. Ciekawą funkcją jest możliwość integracji z relacyjną bazą
danych (http://kaon2.semanticweb.org/)
RacerPro – rozwiązanie komercyjne. Jest to pełnoprawny reasoner.Warty uwagi,
ponieważ można uzyskać licencję akademicką.
FaCT++ – rozwiązanie open Source. Wykorzystywany głównie do wnioskowania w
kontekście warstwy OWL-DL.
9
Rysunek 3. Architektura silnika Pellet, źródło [15]
10
Wnioskowanie - praktyka
Szukając informacji o wnioskowaniu w sieciach semantycznych natrafiłem na
przeprowadzone badania wykorzystujące ontologię Wine, która opisuje wina i jedzenie które
do nich pasuje. Fragmenty kodu i wyniki wnioskowania przez Pellet pochodzą z:
http://dezinformacja.org/tarpit/archiwum/wnioskowanie_owl. Ontologia ta posiada właściwości, które wpływają na jej popularność:
W3C umieściło ją w swojej rekomendacji
Posiada sporo elementów, których nie wykorzystuje żadna inna konkurentka
Jest ogromna- zawiera ok 140 klas oraz 200 instancji.
Wyżej wymienione cechy powodują, że słabsze mechanizmy wnioskowania nie radzą sobie z
nią zbyt dobrze. Autor badań postanowił sprawdzić jak z wnioskowaniem poradzi sobie
reasoner SWOOP w wersji 2.3.
“<wine:CabernetSauvignon
rdf:about="#MariettaCabernetSauvignon">
<wine:hasBody rdf:resource="#Medium"/>
<wine:hasFlavor rdf:resource="#Moderate"/>
<wine:hasMaker rdf:resource="#Marietta"/>
<wine:hasSugar rdf:resource="#Dry"/>
<wine:locatedIn rdf:resource="#SonomaRegion"/> </wine:CabernetSauvignon>”
Treść ontologii dotyczącej wina MariettaCabernetSauvignon: Podczas opisywanych badań reasoner SWOOP bez włączonego wnioskowania pokazywał te
same dane w następującej formie:
11
“OWL-Individual: MariettaCabernetSauvignon
Instance of: CabernetSauvignon
Object Assertions:
hasBody : Medium
locatedIn : SonomaRegion
hasMaker : Marietta
hasFlavor : Moderate
hasSugar : Dry”
Autor badania następnie podłączył wymienionego wcześniej reasonera Pellet. Na wyjściu uzyskał już dużo ciekawszy wynik, zawierający wyniki „myślenia” reasonera. “OWL-Individual: MariettaCabernetSauvignon Instance of: CaliforniaWine (Why?) CabernetSauvignon Object Assertions:
locatedIn : SonomaRegion locatedIn : CaliforniaRegion (Why?)
locatedIn : USRegion (Why?) hasBody
: Medium hasColor : Red (Why?)
hasMaker : Marietta
hasFlavor : Moderate
hasSugar : Dry hasWineDescriptor : Red (Why?)
hasWineDescriptor : Moderate (Why?)
12
hasWineDescriptor : Dry (Why?) hasWineDescriptor : Medium (Why?)”
Interpretować to wyjście możemy w następujący sposób- stwierdzenia wygenerowane
przez Pellet posiadają sufiks „Why?”. Pod sufiksem owym znajduje się wyjaśnienie
przedstawianego wniosku- np. skąd wiadomo, że jest wyprodukowane w Kalifornii- locatedIn
: CaliforniaRegion (Why?), lub skąd wiadomo, że ma czerwony kolor? hasColor: Red (Why?)
Poniżej fragment wyjaśnienia kryjący się pod sufiksem:
“Axioms causing the inference : 1) (MariettaCabernetSauvignon rdf:type CabernetSauvignon)
2) |_(CabernetSauvignon ⊆ (∃hasColor . {Red}))”
Krótkie wyjaśnienie:
1) MariettaCabernetSauvignon jest typu CabernetSauvignon.
2) CabernetSauvignon dla cechy hasColor posiada jedynie wartość Red
.
13
Pod uzasadnieniem wnioskowania o region produkcji (locatedIn : USRegion (Why?) autor badań uzyskał następujące uzasadnienie: “Axioms causing the inference : 1) (MariettaCabernetSauvignon locatedIn SonomaRegion) 2) |_(CaliforniaRegion locatedIn USRegion) 3) |_(SonomaRegion locatedIn CaliforniaRegion) 4) |_Transitive(locatedIn)”
Poniżej które wyjaśnienie:
1) MariettaCabernetSauvignon ma korzenie w regionie SonomaRegion,
2) Region ten jest leży w CaliforniaRegion,
3) Kalifornia znajduje się w USA. Zastosowanie metod wnioskowania
Mając już ogólny pogląd na wnioskowanie w semantic web, możemy się zastanawiać w
jakich dziedzinach biznesu/życia może nam się to przydać. Poniżej postaram się omówić
kilka praktycznych zastosowań wnioskowania w semantic webie.
14
Wyszukiwanie informacji np. wyszukiwarka internetowa
Wyszukiwarki którymi dysponujemy dzisiaj z reguły traktują zapytania bardzo dosłownie, co
przynosi niekiedy mizerne efekty. Wyszukiwarki semantyczne są dużo bardziej intuicyjne i
potrafią „zrozumieć” co użytkownik miał na myśli. Jeśli zachodzi taka potrzeba, możemy
nawet prześledzić „tok myślowy”, który doprowadził reasonera do wyświetlanych wyników.
Poniżej kilka przykładów istniejących już w biznesie rozwiązań w tym zakresie:
PowerSet – jest to wyszukiwarka semantyczna, za której wydanie odpowiedzialna jest
firma Microsoft. Jak sama nazwa wskazuje można za jej pomocą wyszukiwać
informacje za pomocą zapytań w języku naturalnym. Serce tej wyszukiwarki to
Wikipedia oraz dane z bazy
„Freebase”. Dla przykładu na pytanie „kto zatrzymał słońce a poruszył ziemię”
wyszukiwarka wyświetli nam informacje dotyczące Mikołaja Kopernika i jego
portrety. Nasze pytania mogą przyjmować nawet dużo bardziej precyzyjną formę typu
„ile to jest 2 plus 2”.
Yahoo! SearchMonkey – Najciekawszym motywem SearchMonkey jest fakt, że
udostępnia ona api za pomocą którego możemy tworzyć własne aplikacje. Podobnie
jak wyżej wymieniona „Power Set” znakomicie sprawdza się w wyszukiwaniu
informacji na podstawie fraz podanych w języku naturalnym
15
Rysunek 4. Dobra wizualizacja działania Search Monkey
Źródło : [11]
Rich Snippets– tutaj z koleii mamy reprezentanta wyszukiwarek semantycznych od
giganta z Mountain View czyli „Google’a”. Jej specjalność to precyzyjne odpowiedzi
na temat ludzi oraz produktów (jeśli tylko strona opisana jest w RDF). Owa
specjalizacja polega na tym, że Rich Snippets wyróżnia takie atrybuty produktu jak
średnia cena i opinie innych użytkowników
.
Hakia– Tutaj sprawa jest o tyle ciekawa, że przy jej rozwoju brała udział polska firma
PROKOM INVESTMENTS S.A. Udziałowi temu zawdzięczamy możliwość
formułowania zapytań w języku polskim.
16
Semantyczna encyklopedia „Semantic Wiki”
W dziedzinie Wiki semantyczne metody wyszukiwania narzucają się same. Gdy poszukujemy
informacji zwykle pytamy się kogoś w języku naturalnym. Istnieje klika rozwiązań na rynku,
które udostępniają taką możliwość. Postaram się wymienić kilka:
1. Semantic MediaWiki– jest to freewarowe rozszerzenie platformy MediaWiki. Jest o tyle ciekawe, że pozwala dodawać do Wiki semantyczne adnotacje. Takie adnotacje
powodują, że łatwiej wyszukać precyzyjne informacje o które prosi użytkownik a struktura
samego Wiki staje się bardziej przejrzysta. Zaletą Semantic Media Wiki jest również jej api,
które pozwala na eksport zawartych w niej danych do popularnych formatów używanych w
sieci np. JSON/XML.
Rysunek 5. System zawierający Semantic media wiki- przykładowy schemat
Źródło : [16]
17
2. BiomedGT– rozwiązanie typowo ukierunkowane na konkretną dziedzinę wiedzy-
biotechnologię. Umożliwia integrację wiedzy i doświadczenia ekspertów dziedzinowych z
całego świata. Stanowi mocną siłę napędową dla rozwoju nowych metod walki z rakiem oraz
innymi groźnymi chorobami.
Zastosowania nietypowe, nie wpisujące się w poprzednie kategorie
1. Faviki– załóżmy, że mamy klika zakładek „ulubione” w naszej przeglądarce internetowej.
Skoro są nasze „ulubione” to musimy mieć jakieś zastosowanie dla nich, albo po prostu
zawierają ważne informacje dla nas. Dzięki Faviki możemy opisać je semantycznie (przy
pomocy RDF albo Common Tag) i dzięki temu dostarczyć trochę wiedzy dla semantycznych
zapytań. Swój opis możemy zintegrować np. z DbPedią linkując do wiedzy zawartej w niej.
Przydatną cechą jest również możliwość definiowania własnych znaczników semantycznych.
Dla przykładu możemy zdefiniować czy Apple to owoc/firma, co pomaga potem precyzyjniej
wyszukiwać (system ma pojęcie, że fraza ta może odnosić się do dwóch lub więcej kategorii).
Dzięki Faviki powstaje jedna z większych semantycznych baz na świecie .
2. Zemanta– narzędzie skierowane do twórców serwisów internetowych oraz blogów. Z jego
pomocą sprawnie oznaczyć możemy tagi/słowa oraz zdjęcia znajdujące się w serwisie.
Dodatkową zaletą jest wbudowany system sugerowania (coś jak podpowiedzi w IDE
służących do programowania), który sugeruje jakie znaczniki najlepiej opisałyby naszą
witrynę. Nawet jeśli twórca serwisu nie zna RDF, może dostarczyć opis swojej witryny
za pomocą wymienionego wcześniej mechanizmu.
18
Czemu warto szukac nowych metod wnioskowania w Semantic Webie ?
Istniejące rozwiązania w zakresie wnioskowania semantycznego są zadowalające, ale daleko
im jeszcze do pełnego „pojmowania” zapytań w języku naturalnym. Co prawda obecnie
prowadzi się sporo inicjatyw mających na celu poprawę skalowalności systemów
semantycznych, ale warto dorzucić tutaj swoją cegiełkę w postaci opracowania nowej metody
wnioskowania. Jednym z nowszych projektów (na które warto zwrócić uwagę przy tworzeniu
autorskiej metody, z uwagi na mnogość zaimplementowanych metod wnioskowania) jest
LarKC.
Large Knowledge Collider (LarKC) ma być skalowalny nawet dla sieci wielkości
współczesnego Internetu. Na tle innych projektów wyróżnia go:
platforma umożliwiająca rozproszone i niekompletne wnioskowanie,
duża skalowalność
hybryda wnioskowania z wyszukiwaniem oraz ekstrakcją informacji
algorytmy wnioskowania, korzystające z rachunku prawdopodobieństwa
architektura, która wyróżnia specyficzne segmenty
Rysunek 6. Schemat architektoniczny LarKC i zobrazowanie procesu decyzyjnego, źródło : [12]
19
Słabe i mocne punkty istniejących metod wnioskowania w kontekście
semantic weba
Obecnie w rozwiązaniach komercyjnych (w dziedzinie reasonerów semantycznych)
wyróżniamy dwie główne metody wnioskowania:
- forward chaining, czyli „wnioskowanie metodą przyrostową” (od przesłanek do wniosków)
- backward chaining, czyli wnioskowanie od „wniosków do przesłanek”
Parafrazując Ajlan Al-Ajlan z [1].
Forward chaining semantic reasoner- jak działa i co można usprawnić
W tej metodzie na podstawie reguł wnioskowania tzw. „klauzul” wyciągamy wnioski które
następnie możemy wykorzystać do generowania nowych wniosków. Wszystkie tak
wygenerowane wnioski da się udowodnić na podstawie wejściowego zbioru faktów. Proces
wnioskowania trwa do momentu aż udowodnimy zdanie którego chcieliśmy dowieść
prawdziwości albo nie będziemy mogli już wygenerować więcej wniosków przy użyciu
dostępnych klauzul.
Rysunek 7. Graf przepływu (wnioskowanie w przód), źródło: International Journal of Machine
Learning and Computing, Vol. 5, No. 2, April 2015
20
Żeby lepiej pokazać mechanizm działania forward chainingu postaram się przedstawić
przykład rozumowania opartego o ten algorytm.
Załóżmy, że mamy zbiór faktów:
A) Marcin jest bratem Wiktora
B) Wiktor jest bratem Rafała
C) Matką Rafała jest Teresa
Oraz zbiór klauzul:
1) X jest bratem Z jeżeli X jest bratem Y i Y jest bratem Z
2) X jest matką Y jeżeli X jest Matką Z i Z jest bratem Y
Przyjmijmy, że część zdania po „jeżeli” nazywać będziemy poprzednikiem klauzuli.
Spróbujmy udowodnić zdanie Teresa jest matką Marcina.
Fakty „Marcin jest bratem Wiktora” oraz „Wiktor jest Bratem Rafała” pasują do poprzednika
klauzuli 1. Po podstawieniu ich otrzymujemy wniosek, że Marcin jest bratem Rafała, przy
założeniu że:
X = Marcin
Y = Wiktor
Z = Rafał
Nazwijmy go więc faktem „D”. Tak wygenerowany fakt, zostanie dodany do naszej
wejściowej bazy faktów oraz wykorzystany będzie w dalszych etapach wnioskowania.
Teraz przejdźmy do klauzuli 2. Do jej poprzednika możemy podstawić różne kombinacje
faktów. Zacznijmy od pierwszej części poprzednika klauzuli czyli „X jest Matką Z”. Tutaj
pasuje tylko fakt C czyli „Matką Rafała jest Teresa”, czyli X = Teresa, Z = Rafał.
Znajdźmy teraz fakt który pasuje do drugiej części poprzednika czyli „Z jest bratem X”. Za
„Z” przyjęliśmy Rafała więc szukamy faktu który powie nam coś o bracie Rafała. Z pomocą
przychodzi nam fakt B. Oraz dodany dopiero co do bazy faktów fakt D. Zacznijmy od faktu
B. Podstawiając go do drugiej części poprzednika reguły 2. Wnioskujemy, że Teresa jest
Matką Wiktora. Analogicznie dodajemy fakt do bazy. Podstawiając w to samo miejsce fakt
D uzyskujemy wniosek „Teresa jest matką Marcina”. Zakładając, że algorytm za
wygenerowaniem każdego faktu sprawdza czy uzyskany wniosek jest zdaniem które
chcieliśmy udowodnić w tym momencie prawdziwość zdania zostaje potwierdzona a
algorytm kończy działanie.
21
Zauważmy, że w tym procesie udowodniliśmy przy okazji nadmiarowe zdanie- Teresa jest
Matką Wiktora. W miarę przyrostu ilości klauzul oraz faktów w algorytmie „forward
chaining” nadmiarowych informacji generujemy coraz więcej. Nasuwa się tutaj pomysł
zredukowania tej nadmiarowości i zastosowanie heurystyki która usprawni owy proces.
Zastanawiając się nad zaletami „forward chainingu” pierwsza która od razu rzuca się w oczy
to „ogromne wzbogacenie bazy faktów” jak zauważył Tomasz Jach w [5]. Jeśli wejściowa
baza jest uboga to zastosowanie omawianego algorytmu ma mocne uzasadnienie. Dodatkowo
„przy okazji” udowadniamy inne hipotezy a co za tym idzie, możemy udowadniać kilka
hipotez równocześnie.
Backward chaining semantic reasoner- jak działa i co można usprawnić
W przeciwieństwie do „forward chainingu” algorytm ten wykorzystuje jedynie niezbędne
reguły wnioskowania do udowodnienia postawionej hipotezy. Zaczynamy od wniosków i
stopniowo kierujemy się ku przesłankom. Jeśli wejściowe zdanie do udowodnienia znajduje
się w naszym zbiorze faktów to od razu otrzymujemy wynik pozytywny. W przeciwnym
wypadku algorytm szuka reguły której następnik odpowiada zdaniu które chcemy udowodnić.
Teraz gdy wybraliśmy już regułę musimy udowodnić jej poprzednik by dowieść
prawdziwości zdania wejściowego. Prawdziwość przesłanek dowodzimy rekurencyjnie
wykonując opisaną wyżej procedurę.
22
Rysunek 8. Graf przepływu (wnioskowanie w tył), źródło: [1]
Widać tutaj wyraźną różnicę w stosunku do forward chainingu. Nie udowadniamy
wszystkiego po kolei a jedynie niezbędne hipotezy które mogą stać się podstawą dowodu.
Niestety baza faktów pozostanie uboga jeśli na wejściu nie posiada satysfakcjonującego
rozmiaru oraz dowodzenie kilku hipotez jednocześnie nie jest możliwe.
Zilustrujmy działanie opisanego algorytmu na analogicznym przykładzie. Spróbujmy
udowodnić zdanie „Teresa jest matką Marcina”. Jedyna reguła której poprzednik zawiera
szukane zdanie do udowodnienia to :
1) X jest matką Y jeżeli X jest Matką Z i Z jest bratem Y
Więc X = Teresa a Y = Marcin. Do udowodnienia mamy przesłanki reguły czyli: Teresa jest
Matką Z i Z jest bratem Marcina. Przeszukując bazę faktów algorytm natrafia na fakt C czyli
„Teresa jest matką Rafała” więc Z = Rafał. Przechodząc do drugiej części poprzednika
musimy udowodnić że „Rafał jest bratem Marcina”. Niestety w bazie faktów nie znajdujemy
potwierdzenia, więc zaczynamy szukać reguły która zawierać będzie tą konkluzję. Z pomocą
przychodzi reguła:
1) X jest bratem Z jeżeli X jest bratem Y i Y jest bratem Z
23
Więc X = Rafał Z = Marcin. Znowu musimy udowodnić dwie części poprzednika czyli
konkretnie: „Rafał jest bratem Y” i „Y jest bratem Marcina”. W bazie faktów możemy
znaleźć informację że „Rafał jest bratem Wiktora” więc zostanie nam udowodnić, że „Wiktor
jest bratem Marcina”. Owo zdanie znajduje się w bazie faktów więc proces dowodzenia
kończy się sukcesem. Widać że mocną stroną tego podejścia jest to, że żaden krok nie jest
podjęty bez przyczyny.
Porównanie obu podejść pod kątem złożoności obliczeniowej i narzutu pamięci
Pod kątem narzutu pamięci od razu rzuca się w oczy generowana masa potencjalnie
niepotrzebnych reguł przez „forward chaining”. Jeśli przyjmujemy, że „backward chaining”
nie będzie korzystał z cache to jest on zdecydowanym zwycięzcą w tej materii ponieważ
przechowuje jedynie fakty wejściowe.
Jeśli zastanowimy się nad złożonością obliczeniową to w przypadku „forward chainingu” jest
ona niska dzięki temu, że nie udowadniamy po kilka razy tych samych faktów. Zostają one
dodane do bazy i na ich podstawie po prostu uruchamiamy kolejne reguły. W przypadku
„backward chainingu” istnieje ryzyko udowadniania tych samych faktów po kilka razy w
jednym procesie wnioskowania (zakładając brak chache). Idealnym rozwiązaniem które się
nasuwa jest hybryda tych algorytmów a konkretnie „backward chaining” z uzupełnianiem
bazy faktów na bieżąco. Jeżeli dysponujemy dużą ilością pamięci to takie rozwiązanie wydaje
się być sensowne.
Dodatkowe heurystyki potencjalnie usprawniające hybrydę znanych metod
wnioskowania
Podczas szukania wiedzy na temat metod wnioskowania w semantic webie, natrafiłem na
kilka heurystyk które wydają się być sensowne. Często jest tak, że w procesie wnioskowania
wiele reguł pasuje dla danego faktu- pytanie więc którą „odpalić”. Heurystyki o których
mowa pomagają nam podjąć decyzję którą regułę aktualnie uaktywnić.
1) Reguły które niedawno pojawiły się w naszej bazie wiedzy mają pierwszeństwo (ma
to sens, ponieważ nowa wiedza często jest w stanie usprawnić proces wnioskowania i
nadać mu nowy kierunek).
2) W danej iteracji algorytmu wnioskowania, jedna reguła może być użyta tylko raz.
Heurystyka ta chroni nas przed sytuacją korzystania ciągle z tych samych reguł i daje
szanse również innym. Dzięki takiemu podejściu wiedza którą uzyskujemy jest dużo
bogatsza i bardziej różnorodna.
3) Metoda faworyzowania reguł o większej liczbie przesłanek. Tutaj zakładamy, że
bardziej wyspecyfikowana reguła najlepiej nadaje się do wykorzystania w danej
sytuacji. Jest to intuicyjne, gdyż korzystamy z wyspecjalizowanego narzędzia (w tym
24
wypadku reguły wnioskowania). Porównać można to do sytuacji gdy zastanawiamy
się czy łatwiej przykręcić śrubkę wkrętarką czy śrubokrętem.
Źródło: Strategie doboru reguł [1]
Badania czasów wnioskowania w przód i w tył istniejących reasonerów
Zastanawiając się nad nowymi sposobami wnioskowania w sieci semantycznej warto
postawić sobie pytanie jak obecne rozwiązania radzą sobie z tym zadaniem. Przedmiotem
badań będzie sławna ontologia Wine z W3C. Jest ona dosyć rozległa (około 140 klas i 200
instancji) dlatego świetnie się nada do badań wydajności. Przyjrzyjmy się zatem jej
strukturze. Poniżej zamieszczam wygenerowany graf za pomocą OVLviz. Widać tutaj
doskonale skalę całej ontologii oraz liczność zależności pomiędzy jej klasami. Podstawowymi
cegiełkami po których dziedziczy większość klas są Grape, Thing oraz PotableLiquid.
25
Rysunek 9. Wizualizacja struktury ontologii Wine, wygenerowane przez OVL Viz
26
OWLViz i badania na ontologii Wine
Widzimy, że najbardziej rozległą gałęzią jest ta wychodząca od „PotableLiquid” czyli cieczy
którą można gdzieś nalać. Dzięki wygodnemu interfejsowi który zapewnia Protege jesteśmy
w stanie przeglądać ontologie i na przykład zweryfikować czy przykłady wnioskowania
pochodzące z wymienionego wcześniej źródła (
http://dezinformacja.org/tarpit/archiwum/wnioskowanie_owl) pokrywają się ze strukturą
ontologii Wine.
Rysunek 10 . Zrzut ekranu nakładki graficznej Protege, 1.04.2016
Przeglądając właściwości klasy CabernetSauvignon zauważamy, że faktycznie posiada
właściwości wykorzystane przy wnioskowaniu w podanym wcześniej przykładzie.
Ciekawszym jest jednak jak reasoner poradzi sobie z wnioskowaniem w zakresie tej
ontologii. Protege umożliwia podłączenie wybranego reasonera jako plugin i późniejsze
wykorzystanie go przy pozyskiwaniu wiedzy. Mój wybór padł na następujące technologie
typu open- source. Większość z nich omawiałem wcześniej przy przeglądzie istniejących
reasonerów. Są to:
Pellet
Incremental pellet
Hermit 1.3.8
Wykorzystują one wnioskowanie w przód. Następnie z wygenerowanej wiedzy możemy
pozyskiwać interesujące nas wycinki za pomocą języka zapytań DL Query. Dla przykładu
sprawdźmy czy w naszej ontologii istnieją jakieś wina które są wytrawne. W zakładce DL
27
Query wpisałem zapytanie „Wine and hasSugar value Dry”. Na początku określamy klasę
obiektu który nas interesuje a następnie dodajemy jeszcze ograniczenie co do atrybutu
hasSugar. Oto wyniki tego eksperymentu:
Rysunek 11. Zrzut ekranu, Protege zakładka DL Query, 1.04.2016
Interfejs wygenerował nam wyniki w postaci listy instancji które spełniają podane
ograniczenie. Jak widać istnieje 43 wytrawnych win w ontologi Wine. Klikając na znak
zapytania koło instancji możemy zapytać się o tok rozumowania reasonera, który
doprowadził do zaklasyfikowania instancji. Sprawdźmy czemu Pellet zaklasyfikował
MountaindainReisling do win wytrawnych.
Rysunek 12. Zrzut ekranu Protege, wyjaśnienie toku rozumowania 1.04.2016
28
Widać, że w krokach 1 i 2 reasoner zrozumiał o jakie właściwości go pytaliśmy, następnie
zaklasyfikował dziedzinę właściwości hasSugar w kategorii win. Potem natrafił na aksjomat i
ostatecznie było to podstawą do zaklasyfikowania MountaindainReisling do poszukiwanej
przez nas grupy.
Badania reasonerów wykorzystujących wnioskowanie w przód
Po uruchomieniu procesu wnioskowania omawiana ontologia powinna zmienić swoją
strukturę oraz dostarczyć nowej wiedzy i przydatnych informacji.
Rysunek 13. Zrzut ekranu, konsola Protege, 1.04.2016
Widać, że proces forward chainingu w przypadku Pellet’a trwał ok 16,8 sekundy. W tym
czasie reasoner wygenerował multum nowych informacji oraz zmienił strukturę ontologii.
Dzięki dobrodziejstwom nakładki Protege możemy porównać ontologię (jej strukturę) przed
tym procesem jak i po nim. Jest ich sporo więc przyjrzymy się tylko kilku różnicom.
Protege dzieli modyfikacje ontologii na 3 rodzaje- dodanie aksjomatu, modyfikacja
istniejących struktur oraz usunięcie jakiejś zależności. W procesie wnioskowania w przód
przy użyciu Pellet’a dodane zostało sporo aksjomatów.
29
Rysunek 14. Zrzut ekranu- różnice pomiędzy ontologiami (Pellet)
Widzimy, że jednym z dodanych aksjomatów jest fakt iż kurczak jest rzeczą do jedzenia oraz
można go przerobić. Do tego został poprawnie zaklasyfikowany jako ptak który posiada jasne
mięso. Oprócz omówionego przykładu do ontologii zostało dodane około 40 podobnych
aksjomatów. Widać tutaj skalę przyrostu nowej wiedzy którą zawdzięczamy wnioskowaniu w
przód.
Spoglądając na modyfikacje dokonane przez uruchomienie reasonera Pellet dla ontologii
Wine zauważyłem również sporo zmian istniejących już bytów. Na przykład pojęcie
„Medium” czyli średnie- odnosi się ono teraz do czegoś co opisuje wino pod kątem jego
smaku. Widzimy, że dzięki procesowi wnioskowania nasza hierarchia klas została
wzbogacona.
Rysunek 15. Zrzut ekranu, Protege- różnice pomiędzy ontologiami
30
Po wglądzie w struktury ontologii poddanej działaniu reasonera warto przebadać czasy
innych aktualnie istniejących mechanizmów wnioskowania w przód. Dzięki możliwości
aplikowania własnych reasonerów które implementują odpowiednie interfejsy protege
umożliwia podłączenie ich oraz przeprowadzenie badań. Dla reasonera Hermit 1.3.8.3 czas
wyniki przedstawiają się następująco:
Rysunek 16. Zrzut ekranu, protege 16.04.2016
Oczywiście badania przeprowadzałem dla ontologii Wine tak samo jak w poprzednim
przypadku. Hermitowi zajęło to około 3 razy dłużej przy porównywalnym wzroście wielkości
ontologii. Może to być spowodowane faktem, że Hermit wykorzystuje dosyć złożoną
reprezentację wiedzy (SHOIQ+) a co za tym idzie forward chaining jest bardziej kosztowny
pod kątem narzutu pamięciowego.
Ostatnim z przebadanych reasonerów jest Pellet w wersji wnioskowania przyrostowego. W
przeciwieństwie do swojej podstawowej wersji nie ma on zaimplementowanego pełnego
śledzenia procesu wnioskowania. Nie dojdzie zatem do sytuacji gdzie reasoner zdecyduje
żeby usunąć jakieś elementy ontologii np. po usunięciu aksjomatu. Zamiast tego algorytm
wprowadza nowe moduły (struktury danych) gdzie składowane są wywnioskowane
konkluzje. Mechanizm ten redukuje złożoność obliczeniową, ale niestety kosztem większego
narzutu pamięci. Poniżej wyniki forward chainingu za pomocą przyrostowej wersji Pellet’a:
31
Rysunek 17. Zrzut ekratu, protege 14.04.2016
Wzrost wydajności plasuje się na poziomie ok 6 sekund w stosunku do wersji podstawowej
tego reasonera czyli o 37 %. W skali tak wielkiej ontologii jak Wine to spory wzrost
wydajności.
Pellet Hermit 1.3.8.3 Incremental pellet
Czas
wnioskowania [ms]
16.845 47.118 10.732
17.834 48.028 11.554
15.438 45.318 11.165
15.524 45.818 11.285
16.65 48.077 11.355
17.456 43.013 12.545
15.832 46.028 13.115
16.817 44.113 11.245
17.898 45.013 11.315
16.812 47.045 13.115
Tabela 1. Zestawienie czasów wnioskowania w przód dla popularnych dzisiaj reasonerów
(przybliżone wartości )
32
Badania reasonerów wykorzystujących wnioskowanie w tył (backward chaining)
1) Porównanie przybliżonych udowadniania zdania MariettaCabernetSauvignon jest
typu CabernetSauvignon.
Pellet Hermit 1.3.8.3 Incremental pellet
Czas
wnioskowania [ms]
11.545 21.248 10.732
12.751 23.245 11.554
11.141 24.269 11.165
13.444 26.264 11.285
11.54 27.248 11.355
12.455 24.187 12.545
13.187 21.133 13.115
11.615 20.145 11.245
12.156 22.145 11.315
13.854 23.145 13.115
Tabela 2. Zestawienie czasów wnioskowania w tył dla popularnych dzisiaj
reasonerów(przybliżone wartości )
Wykres 1. Zestawienie czasów wnioskowania w przód omawianych reasonerów
33
Wykres 2. Zestawienie czasów wnioskowania w tył omawianych reasonerów
Zaproponowanie heurystyki i implementacja w wybranym środowisku
Po analizie istniejących rozwiązań i przebadaniu ich w interesującym mnie zakresie pora
przystąpić do implementacji własnej metody wnioskowania której specyfika wynikać będzie
z wcześniej wyciągniętych wniosków. Opierać się ona będzie na kilku wymienionych już
heurystykach:
1) „Reguły które niedawno pojawiły się w naszej bazie wiedzy mają pierwszeństwo”
2) „W danej iteracji algorytmu wnioskowania, jedna reguła może być użyta tylko raz”.
3) „Metoda faworyzowania reguł o większej liczbie przesłanek”.
Rdzeniem wnioskowania będzie „backward chaining”, ale naszą bazę faktów będziemy
uzupełniali na bieżąco co zapobiegnie udowadnianiu po kilka razy tych samych faktów.
Dodatkowo przed udowadnianiem zawsze nastąpi chwilowe przełączenie na „forward
chaining” żeby wzbogacić naszą bazę faktów. Następnie wrócimy do wnioskowania w tył z
użyciem wspomnianych heurystyk. Podobną koncepcję wnioskowania mieszanego przyjmuje
Tomasz Jach w [5]. Tutaj jednak nie dostarczamy meta wiedzy o regułach jak zaproponował
Pan Tomasz, ale co iterację uruchamiamy wnioskowanie w przód na podany przez
użytkownika interwał czasowy.
34
Podsumowując projekt algorytmu wygląda następująco:
1) Wczytaj zbiór faktów i reguł
2) Wczytaj maksymalny czas działania algorytmu oraz interwał czasowy
3) Wczytaj hipotezę do udowodnienia
4) Uruchom wnioskowanie w przód na interwał czasu lub do udowodnienia hipotezy. W
przypadku udowodnienia hipotezy idź po punktu 6.
5) Próbuj udowodnić hipotezę metodą wnioskowania w tył z zastosowaniem omawianych
heurystyk, do momentu w którym hipoteza zostanie udowodniona lub upłynie wyznaczony
interwał. Gdy upłynie wyliczony interwał przejdź do punktu 4.
6) Wyświetl wynik- true jeśli udowodniono hipotezę, false- jeśli wykorzystano wszystkie
możliwości i hipotezy nie udało się udowodnić, null jeśli przekroczono limit czasu wczytany na
początku.
Językiem programowania w którym zaimplementowano algorytm jest Java. Porównywać
będziemy czas udowadniania hipotez dla zaimplementowanych algorytmów (backward
chaining, forward chaining, oraz zaproponowany hybrydowy). Baza reguł i baza faktów
będzie stopniowo rosła. Dodatkowo warto zaznaczyć że czas ten zależeć będzie od struktury
reguł a konkretnie ich poprzedników. Na przykład reguła „jeśli a to b” będzie generować
szybciej wynik niż „jeśli a i c to b”, ponieważ dostarcza nam dodatkowy fakt do
udowodnienia. Postarałem się wydzielić bazy wiedzy o rozmaitych charakterystykach by
badania miały wiarygodny wymiar.
Dla porównania przepływ wnioskowania w istniejącej już hybrydzie Apache Jena wygląda
następująco:
Rysunek 18. Źródło : [17]
Tutaj autor rozwiązania zaproponował podział na reguły dostępne dla wnioskowania w przód
i odrębne dla wnioskowania w tył. Fakty wywnioskowane przez mechanizm wnioskowania w
przód dodawane są do bazy faktów reasonera odpowiedzialnego za wnioskowanie w tył.
Takie rozwiązanie wydaje się być sensowne, z uwagi na potencjalnie mniejszą nadmiarowość
generowanych faktów przez mechanizm wnioskowania w przód. Niestety liczyć trzeba się
wtedy, że przy wnioskowaniu w tył nie będziemy mieli czasami potrzebnych reguł do
dopasowania dla następnika.
35
Implementacja reasonera do wnioskowania w przód
public abstract class Reasoner { protected KnowledgeBase knowledgeBase; protected Hypothesis hypothesis; public Reasoner(KnowledgeBase knowledgeBase, Hypothesis hypothesis) { this.knowledgeBase = knowledgeBase; this.hypothesis = hypothesis; } public abstract boolean performReasoning(); public abstract boolean isHypothesisProven(); public KnowledgeBase getKnowledgeBase() { return knowledgeBase; } }
Fragment kodu, klasa abstrakcyjna Reasoner. Definiuje interfejs dla dalszych implementacji.
36
public class ForwardChainingReasoner extends Reasoner { @Override public boolean performReasoning() { boolean generatedNewFact; do { generatedNewFact = false; for(Rule rule : knowledgeBase.getRules()) { if(rule.evaluate(knowledgeBase.getReasonedAndInputFacts()) && knowledgeBase.addNewFact(rule.getConsequent())) { generatedNewFact = true; } } } while(generatedNewFact && !isHypothesisProven()); return isHypothesisProven(); } @Override public boolean isHypothesisProven() { return knowledgeBase.getReasonedAndInputFacts().stream().anyMatch(new Predicate<Fact>() { @Override public boolean test(Fact t) { return t.getFactName().equals(hypothesis.getHypothesis()); } }); } }
Fragment kodu, klasa ForwardChainingReasoner.
Krótkie omówienie szczegółów implementacji wnioskowania w przód
Tutaj warto zwrócić uwagę na metodę performReasoning(). Do szybkiego sprawdzania
prawdziwości reguły użyłem biblioteki JEP, która usprawnia przetwarzanie wyrażeń
logicznych ze zwykłego łańcucha znaków. Cały proces wnioskowania to tutaj klasyczny
forward chaining. Owa metoda wykorzystana została przy implementacji wnioskowania
hybrydowego do poszerzania bazy faktów będących podstawą dowodu.
Dla przykładu mając bazę wiedzy:
x && (y || z || w) -> m
x && (w || o || w) -> l
y && (o && w) -> p
x && (x || z || w) -> o
w && (z || o || s) -> y
w -> z
x && (z || r || w) -> p
s -> r
x && (y || z || w) -> r
37
x && (y || w) -> s
#FACTS
x,w,z,r
Po uruchomieniu wnioskowania finalna baza faktów będzie mieć postać:
Forward chaining fact base: [p, r, s, w, x, y, z, l, m, o]
A program wypisze nam czas działania algorytmu.
Algorithm done in 174[ms], hypothesis p proven
Widać, że znacznie wzbogaciliśmy naszą bazę wiedzy w czasie 174 [ms]. Sporo faktów
jednak nie było nam zupełnie potrzebne. Odpowiedzią na tą nadmiarowość będzie
zaimplementowany niżej algorytm wnioskowania w tył.
38
Implementacja reasonera do wnioskowania w tył
public class BackwardChainingReasoner extends Reasoner { @Override public boolean performReasoning() { return performReasoning(hypothesis); } private boolean performReasoning(Hypothesis hypothesis) { hypothesisStack.push(hypothesis); List<Rule> rules = findRulesWhichContainsHypothesisInConsequence(hypothesis); boolean result = knowledgeBase.getIntputFacts().contains(new Fact(hypothesis)) || rules.stream().anyMatch(new Predicate<Rule>() { @Override public boolean test(Rule rule) { boolean res = proofRule(rule); if(res) rulesProveStack.push(rule); return res; } }); if(!result) rulesProveStack.clear(); hypothesisStack.pop(); return result; } private boolean proofRule(Rule rule) { if (rule.evaluate(knowledgeBase.getIntputFacts())) return true; else if (rule.hasAnyNullsInPredecessor(knowledgeBase.getIntputFacts())) { Set<Fact> localFactCache = new HashSet<>(); localFactCache.addAll(knowledgeBase.getIntputFacts()); for (Hypothesis hypothesis : rule.getAllUnknownHypothesis(knowledgeBase.getIntputFacts())) { if (!hypothesisStack.contains(hypothesis) && performReasoning(hypothesis)) { localFactCache.add(new Fact(hypothesis)); if(rule.evaluate(localFactCache)) return true; } } return false; } else return false; } }
Fragment kodu, klasa BackwardChainingReasoner.
39
Krótkie omówienie szczegółów implementacji wnioskowania w tył
Warto zwrócić uwagę na przepływ komunikatów między metodami
performReasoning(Hypothesis) i proofRule(Rule). Wywołują się one wzajemnie a co za tym
idzie metoda proofRule(Rule) wywołuje się rekurencyjnie. Zaczynamy od hipotezy
wyjściowej i próbujemy udowodnić jej wszystkie przesłanki tym samym sposobem którym
udowadniamy następnik głównej hipotezy. Widać, że nie dodajemy żadnych nowych faktów
do bazy wiedzy. Posiadamy zbiór- zmienna „localFactCache” gdzie jedynie lokalnie do
udowodnienia danej reguły posiadamy pamięć o udowodnionych hipotezach pośrednich.
Uruchamiając algorytm uzyskujemy wynik:
Algorithm2 done in 16[ms], hypothesis proven.
backward chaining fact base: [r, w, x, z] reasoning stack : [x && (x || z || w) -> o, w && (z || o || s) -> y, y && (o && w)
-> p]
Widać tutaj że baza faktów pozostała niezmienna, a reguły które posłużyły za podstawę
dowodu zostają wypisane w formie odwróconego stosu wnioskowania. Najpierw reasoner
wziął po uwagę regułę która posiada w konkluzji „p”, następnie udowodnił przesłankę „y” na
podstawie reguły „w && (z || o || s) -> y” oraz przesłankę „o” dzięki regule „x && (x || z || w) -> o”.
Czas wykonania algorytmu wynosił 16 [ms] co w porównaniu z 174 [ms] dla forward
chainingu daje w przybliżeniu 10 razy lepszy wynik.
40
Implementacja reasonera hybrydowego
public class HybridReasoner extends Reasoner { private long forwardChainingMs; @Override public boolean performReasoning() { return performReasoning(hypothesis); } private boolean performReasoning(Hypothesis hypothesis) { hypothesisStack.push(hypothesis); startForwardChaining(); List<Rule> rules = findRulesWhichContainsHypothesisInConsequence(hypothesis); boolean result = knowledgeBase.getIntputFacts().contains(new Fact(hypothesis)) || rules.stream().anyMatch(new Predicate<Rule>() { @Override public boolean test(Rule rule) { boolean res = proofRule(rule); if(res) rulesProveStack.push(rule); return res; } }); if(!result) rulesProveStack.clear(); hypothesisStack.pop(); return result; } public void startForwardChaining() { long startTime2 = System.currentTimeMillis(); boolean generatedNewFact; do { generatedNewFact = false; for(Rule rule : knowledgeBase.getRules()) { if(rule.evaluate(knowledgeBase.getIntputFacts()) && knowledgeBase.addNewInputFact(rule.getConsequent())) { generatedNewFact = true; } } } while(generatedNewFact && !isHypothesisProven() && System.currentTimeMillis() - startTime2 < forwardChainingMs); } }
Fragment kodu, klasa HybridReasoner.
41
Krótkie omówienie szczegółów implementacji wnioskowania hybrydowego
Jak widać rdzeniem całego algorytmu jest wnioskowanie w tył. Cały proces odbywa się rekurencyjnie z pomocą uruchamiania co iterację na interwał czasowy metody startForwardChaining();. Reguły sortowane są w kolejności od największej liczby przesłanek jak we wcześniejszych założeniach heurystyki. Dodatkowo w każdej iteracji jedną regułę możemy wykorzystać maksymalnie jeden raz. Jeśli podczas chwilowego przełączenia się na forward chaining nastąpi udowodnienie hipotezy to oczywiście algorytm kończy działanie. Klasa implementuje wszystkie metody z klasy Reasoner, dzięki czemu w przypadku rozwijania projektu łatwiej będzie korzystać ze wszystkich Reasonerów pod wspólnym mianownikiem.
Przykładowy wynik działania programu dla hipotezy y:
Forward chaining fact base: [a, b, l, m, n, o, p, r, s, w, x, y, z] Algorithm done in 120[ms], hypothesis y proven Backward chaining done in 10[ms], hypothesis y proven backward chaining fact base: [a, r, w, x, z] reasoning stack : [w && (z || o || s) -> y] HybridChaining done in 20[ms], hypothesis y proven Hybrid chaining fact base: [a, b, l, m, n, o, p, r, s, w, x, y, z]
Przykładowe wyniki udowadniania tej samej hipotezy „y” przez wszystkie trzy
zaimplementowane algorytmy świetnie ilustrują specyfikę rozwiązania mieszanego. W
przypadku rozwiązania hybrydowego mamy lekko gorszy czas od wnioskowania w tył, ale za
to znacznie bogatszą bazę faktów.
Wyniki badań własnej implementacji
Poniżej zamieszczam wyniki badań dla większej ilości hipotez. Sprawdzana była praktycznie
każda hipoteza. Baza wiedzy była zróżnicowana i zawierała ok 25 reguł o poprzednikach
różnej maści oraz 5 faktów pierwotnych.
42
hipoteza W przód W tył Hybrydowe
Średni czas
wnioskowania
[ms]
m 120.542 15.897 20.123
o 113.213 18.893 22.432
p 112.542 20.324 24.431
r 139.766 18.233 30.453
h 115.653 22.542 22.543
s 121.123 20.324 30.325
t 131.345 22.433 23.099
a 122.653 22.503 19.942
b 127.345 22.145 21.315
c 121.431 21.431 22.341
d 111.531 18.542 23.232
i 116.432 21.654 22.234
j 126.764 20.342 19.786
l 120.457 22.323 22.685
x 121.786 22.434 19.465
w 122.452 21.551 22.546
f 121.522 23.422 18.784
Tabela 3. Zestawienie czasów wnioskowania dla zaimplementowanego reasonera
(przybliżone wartości )
Wykres 3. Zestawienie średnich czasów wnioskowania reasonerów dla poszczególnych hipotez
43
hipoteza Apache Jena Hybrydowe własne
Średni czas
wnioskowania
[ms]
m 13.433 7.766
o 15.432 9.477
p 16.765 10.467
r 13.534 11.474
h 12.465 7.232
s 16.787 9.254
t 13.457 11.786
a 15.483 10.653
b 12.365 10.752
c 16.366 9.642
d 18.367 9.873
i 21.363 10.357
j 16.453 11.375
l 12.454 9.853
x 18.453 10.573
w 19.353 11.987
f 20.123 9.561
Tabela 4. Zestawienie czasów wnioskowania hybrydowego dla popularnego reasonera
Apache Jena i zaimplementowanego reasonera na potrzeby pracy (przybliżone wartości )
hipoteza Pellet Hermit Hybrydowe własne
Średni czas
wnioskowania
[ms]
m 18.232 22.452 7.766
o 19.542 23.874 9.477
p 17.542 22.454 10.467
r 20.543 24.345 11.474
h 18.451 25.875 7.232
s 17.452 25.654 9.254
t 18.655 26.612 11.786
a 19.344 23.654 10.653
b 19.442 25.647 10.752
c 19.452 24.461 9.642
d 20.766 21.464 9.873
i 17.877 22.676 10.357
j 19.234 22.641 11.375
l 20.734 21.461 9.853
x 17.206 22.641 10.573
w 19.735 23.457 11.987
f 18.54 20.651 9.561
Tabela 5. Zestawienie czasów wnioskowania hybrydowego i w przód dla popularnych
reasonerów i zaimplementowanego reasonera na potrzeby pracy (przybliżone wartości )
44
Wykres 4. Zestawienie średnich czasów wnioskowania Apache Jena i własnego reasonera dla
poszczególnych hipotez
Wykres 5. Zestawienie średnich czasów wnioskowania popularnych reasonerów (w przód) i własnego
reasonera dla poszczególnych hipotez
45
Podsumowanie
Analizując wyniki badań można dojść do wniosku, że nasza hybryda jest dobrym
kompromisem pomiędzy wnioskowaniem w przód i w tył. Zależało mi by algorytm był w
stanie udowadniać kilka hipotez równocześnie, co jest możliwe dzięki przełączaniu się na
wnioskowanie w przód. Nie odstaje on również wydajnościowo od klasycznego
wnioskowania w tył- czasy wnioskowania są o ok 10% dłuższe, ale jest to cena jaką trzeba
zapłacić za wzbogacanie bazy faktów.
Oczywiście wyniki badań mogą w dużej mierze zależeć od struktury bazy wiedzy. Z tego
powodu sprawdzałem zachowanie zaimplementowanego algorytmu dla rozmaitych
konfiguracji- od prostej struktury poprzedników każdej reguły do skomplikowanych zdań
logicznych. Ilość faktów wejściowych również została poddana zróżnicowaniu dla
uwiarygodnienia wyników badań.
Porównując zaproponowane rozwiązanie z Apache Jena (najbardziej liczącym się na rynku
hybrydowym reasonerem) można dojść do wniosku, że własna implementacja szybciej
udowadniała przebadane hipotezy. Może to być oczywiście spowodowane rozmiarem silnika
Jena i mnogością konfiguracji meta reguł sterujących wnioskowaniem.
W kontekście reasonerów nie oferujących algorytmów hybrydowych sprawa ma się podobnie.
Zaimplementowany reasoner osiąga około dwa razy lepsze czasy udowadniania hipotez niż
klasyczny „forward chaining” przy użyciu np. Pellet’a. Jeśli zaś rozpatrywać wnioskowanie w
tył klasycznych rynkowych rozwiązań w porównaniu do hybrydy to wypadają one podobnie,
z małą przewagą istniejących już rozwiązań.
Dużym usprawnieniem optymalizacji procesu rozumowania okazały heurystyki znalezione w
pracy Tomasza Jacha, do której odniesienie zawarłem w bibliografii. Jednak w porównaniu
do zaproponowanego tam modelu wnioskowania hybrydowego zamiast meta reguł
sterujących preferencjami wyboru metody użyłem czasowego przełączenia się na
wnioskowanie w przód.
Podsumowując- zgodnie z założeniami udało się zaprojektować, zaimplementować i
przebadać sprawną hybrydową metodę rozumowani. Dodatkowo przy okazji w ramach
przeglądu dziedziny rozwiązań przebadałem sporo liczących się dzisiaj reasonerów i
usystematyzowałem wiedzę na ich temat. Znalazłem też praktycznie zastosowanie biblioteki
JEP w metodach rozumowania, która bardzo pomogła w przetwarzaniu wyrażeń logicznych.
Zastanawiając się nad kierunkiem dalszych potencjalnych prac w zakresie usprawnienia
zaimplementowanej hybrydy skłaniałbym się ku dokładnemu przeanalizowaniu kodu hybrydy
Apache Jena i dodaniu obsługi meta reguł dla sterowania wnioskowaniem (analogicznie jak w
Jena). Dobrze zaimplementowany mechanizm obsługi modelu preferencji mógłby skrócić
czas udowadniania hipotez i dostosować wielkość wyjściowej bazy faktów do preferencji
użytkownika.
46
Bibliografia:
[1] Ajlan Al-Ajlan International Journal of Machine Learning and Computing, Vol. 5, No. 2,
April 2015.
[2] H. Simon. (2010). An Introduction to the Science of Artificial Intelligence. Oracle
ThinkQuest. 4. A. Champandard. (2010). Artificial Intelligence Introduction.
[3] M. Kolp. (2005). Knowledge systems, organizational knowledge management expert
systems. Université catholique de Louvain.
[4] P. Jackson, Introduction to Expert System, 3rd editon, Addison-Wesley, 1999, ch. 4, pp.
16-28.
[5] Tomasz Jach, Uniwersytet Śląski, Wydział Informatyki i Nauki o Materiałach,
Informatyka, Rozprawa doktorska Optymalizacja procesów wnioskowania z wiedzą niepełną,
Katowice, 2013 r.
[6] W. Jaworski , Reprezentacja wiedzy: Ontologie w Semantic Web w:
http://www.mimuw.edu.pl/~wjaworski/RW/5_semantic_web.pdf, dostęp maj 2016.
[7] G. Tonti,, J. M. Bradshaw , R. Jeffers, Semantic Web Languages for Policy Representation and Reasoning: A Comparison of KAoS, Rei, and Ponder, w:
http://www.jeffreymbradshaw.org/publications/IHMC_DEIS_ISWC.pdf, dostęp maj 2016.
[8] Henze, N., Dolog, P., & Nejdl, W. (2004) Reasoning and Ontologies for Personalized E-Learning in the Semantic Web. Educational Technology & Society, 7 (4), 82-97
[9] Joe Kopena, William C. Regli, A Tool for Reasoning with the Semantic Web, Philadelphia, October 28, (2002)
[10] Jos De Bruijn Axel Polleres Rub´en Lara Dieter Fensel, Conceptual Modeling and Reasoning for the Semantic Web (November 2004).
[11] D. Fiol, SearchMonkey: Site Owner Overview w:
https://developer.yahoo.com/searchmonkey/siteowner.html, dostęp: maj 2016.
[12] D. Fensel, LARKC STRATEGIA WNIOSKOWANIE I ARCHITEKTURA, w : http://blog.saltlux.com/md/eu-fp7-project-larkc/, dostęp maj: 2016.
[13] Christian Bizer and Richard Cyganiak, D2R Server – Publishing Relational Databases on the Semantic Web, w: http://wifo5-03.informatik.uni- mannheim.de/bizer/d2r-server/publishing/, dostęp: maj 2016. [14] J. Noll, Prepare for Reasoning with SWRL (kwiecień 2015) w: http://cwi.unik.no/wiki/Prepare_for_Reasoning_with_SWRL, dostęp: maj 2016 [15] Evren Sirin a , Bijan Parsia a , Bernardo Cuenca Grau, Pellet: A Practical OWL-DL Reasoner , Valencia 2004.
47
[16] G. Zugic, Semantic Wikis, w: https://goranzugic.wordpress.com/2010/09/09/semantic-wikis/, dostęp: maj 2016 [17] M. Baker, Reasoners and rule engines w: https://jena.apache.org/documentation/inference/#RULEhybrid, dostęp: maj 2016.