Metody rozumowania dla Semantic Web
Transkrypt
Metody rozumowania dla Semantic Web
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 1 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 2 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. 3 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: 4 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. 5 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. 6 Rysunek 2. Położenie warstwy SPARQL w kontekście innych pojęć związanych z wnioskowaniem semantycznym. Źródło: [13] 7 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. 8 Rysunek 3. Architektura silnika Pellet, źródło [15] 9 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: 10 “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?) 11 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 . 12 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) 3) 4) |_(CaliforniaRegion locatedIn USRegion) |_(SonomaRegion locatedIn CaliforniaRegion) |_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. 13 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 14 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. 15 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] 16 2. BiomedGT– rozwiązanie typowo ukierunkowane na konkretną dziedzinę wiedzybiotechnologię. 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. 17 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] 18 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 19 Ż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. 20 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ę. 21 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 22 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 23 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. 24 Rysunek 9. Wizualizacja struktury ontologii Wine, wygenerowane przez OVL Viz 25 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 26 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 27 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. 28 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 29 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: 30 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. Czas wnioskowania [ms] Pellet 16.845 17.834 15.438 15.524 16.65 17.456 15.832 16.817 17.898 16.812 Hermit 1.3.8.3 47.118 48.028 45.318 45.818 48.077 43.013 46.028 44.113 45.013 47.045 Incremental pellet 10.732 11.554 11.165 11.285 11.355 12.545 13.115 11.245 11.315 13.115 Tabela 1. Zestawienie czasów wnioskowania w przód dla popularnych dzisiaj reasonerów (przybliżone wartości ) 31 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 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 Czas wnioskowania [ms] 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 32 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. 33 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. 34 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. 35 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 x y x w w x s x && && && && && -> && -> && (y (w (o (x (z z (z r (y || || && || || z || w) o || w) w) -> p z || w) o || s) -> m -> l -> o -> y || r || w) -> p || z || w) -> r 36 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ł. 37 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. 38 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. 39 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. 40 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. 41 hipoteza W przód W tył Hybrydowe 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 Średni czas wnioskowania b 127.345 22.145 21.315 [ms] 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 42 hipoteza Apache Jena Hybrydowe własne 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 Średni czas wnioskowania b 12.365 10.752 [ms] 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 ) Średni czas wnioskowania [ms] hipoteza m o p r h s t a b c d i j l x w f Pellet 18.232 19.542 17.542 20.543 18.451 17.452 18.655 19.344 19.442 19.452 20.766 17.877 19.234 20.734 17.206 19.735 18.54 Hermit 22.452 23.874 22.454 24.345 25.875 25.654 26.612 23.654 25.647 24.461 21.464 22.676 22.641 21.461 22.641 23.457 20.651 Hybrydowe własne 7.766 9.477 10.467 11.474 7.232 9.254 11.786 10.653 10.752 9.642 9.873 10.357 11.375 9.853 10.573 11.987 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 ) 43 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 44 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. 45 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. 46 [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. 47