apohllo.pl View RSS

No description
Hide details



HackKrK 11 29 Jan 2013 11:19 AM (12 years ago)

Firma Future Simple organizuje kolejny Hack KRK. Tym razem będziemy implementować konsolowe gry w Rubim. Polecam!

Aktualizacja:

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Instalacja Rubiego 1.9.3 w Ubuntu 8 Aug 2011 11:51 PM (13 years ago)

Prosta instrukcja, jak zainstalować najnowszą wersję Rubiego (1.9.3-p0) w systemie Ubuntu (testowane z 11.04).

1. Najpierw instalujemy niezbędne pakiety za pomocą apt-get-a (m.in. Ruby w wersji 1.8):

$ sudo apt-get install zlib1g-dev libssl-dev libreadline-dev libxml2-dev libsqlite3-dev 
$ sudo apt-get install ruby curl git-core libyaml-dev

2. Następnie ściągamy i instalujemy Ruby Version Manager (w skrócie RVM):

$ curl -L get.rvm.io | bash -s stable

3. Wczytujemy nową konfigurację shella

$ source /home/user/.profile

4. Testujemy działanie RVM:

$ rvm help
[![Build Status](https://secure.travis-ci.org/mpapis/rvm.png)](http://travis-ci.org/mpapis/rvm)
= rvm
* http://github.com/wayneeseguin/rvm
== DESCRIPTION:
...

Jeśli nie widzimy powyższych komunikatów, znaczy to, że instalacja się nie powiodła! Należy przeczytać uważnie komunikat i sprawdzić co jest nie tak.

6. Instalujemy najnowszą stabilną wersję Rubiego:

$ rvm install 1.9.3
Installing Ruby from source...

Instalacja trwa kilka minut, ponieważ w jej trakcie kompilowany jest Ruby.

7. Na koniec ustawiamy Rubiego 1.9.3 jako domyślny interpreter używany w systemie:

$ rvm use 1.9.3 --default
Using /home/user/.rvm/gems/ruby-1.9.3-p0

8. Weryfikujemy powyższe wydając polecenie:

$ ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [i686-linux]

9. Teraz możemy otworzyć konsolę irb i ostatecznie potwierdzić, że mamy najnowszą wersję Rubiego:

$ irb
ruby-1.9.3-p0 :001 > "abc".encoding
 => #<Encoding:UTF-8>

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Rod - Ruby Object Database 8 Jun 2011 10:15 PM (13 years ago)

Rok temu na EuRuKo miałem superkrótką prezentacje na temat biblioteki Rod mojego autorstwa. Wtedy rozwinąłem ten skrót jako “Read-only database”, co wywołało gromki śmiech, bo po co komu baza danych tylko do odczytu? Obecnie nazwę rozwijam (oczywiście jest w tym przesada) jako Ruby Object Database. W praktyce jej podstawowy charakter się nie zmienił, ale z pewnością nazwa jest bardziej chwytliwa :)

Ale do rzeczy – co to za biblioteka? Otóż została ona zaprojektowana jak baza do przechowywania danych, które rzadko ulegają zmianie. Chodzi mi przede wszystkim o dane lingwistyczne, tzn. takie jakie spotykamy w tradycyjnych słownika i książkach (korpusach tekstów). Język oczywiście jest tworem żywym, co odzwierciedlone jest w ewoluującej zawartości słowników, ale zmiany te następują raczej w ciągu lat, czy dziesięcioleci, niż dni czy godzin. Podobnie z zawartością korpusów tekstów – jeśli coś tam trafi, to już raczej nie podlega zmianie (być może usunięciu, jeśli język zmienił się na tyle, że tekst staje się bardzo mało reprezentatywny).

Dla tego typu danych nie potrzeba baz, które kładą specjalny nacisk na wielodostęp, czy transakcje, bo w praktyce modyfikację bazy lepiej wykonać poprzez jej ponowne wygenerowanie, ewentualnie poprzez dodanie nowych danych i powiązań między danymi, do już istniejącej bazy. Z drugiej strony baza tego rodzaju nie musi być trzymana w pamięci, ponieważ analizując tekst potrzebujemy zawsze jedynie fragmentu słownika. Natomiast w przypadku korpusów tekstu trzymanie w pamięci nie wchodzi w rachubę, ze względu na rozmiar danych. Dlatego tak popularne ostatnio bazy oparte o memcache’a i pokrewne nie są zbyt przydatne dla danych lingwistycznych.

Z kolei relacyjne bazy danych nie mogą być wykorzystane przy analizie tekstów, ponieważ zbiór relacji w jakie wchodzą ze sobą poszczególne elementy czy to słownika, czy też korpusu, jest olbrzymi. Wymagane w tym wypadku wielokrotne złączenia tabel wprowadziłyby nieakceptowalny czas przetwarzania.

Zatem Rod pomyślany jest jako baza danych, w której dane nie ulegają zmianie (choć nie wyklucza się ich dodania i uzupełnienie ich związków), a ich rozmiar wyklucza trzymanie w pamięci operacyjnej. Dodatkowe oczekiwania obejmują szybki czas dostępu dla zindeksowanych danych (np. kilku milionów form wyrazowych), który jednak nie wprowadza narzutu przy uruchomieniu bazy danych (wczytanie pełnego indeksu kilku milionów form zajmuje co najmniej kilka sekund). Co więcej – wczytanie pojedynczej informacji (która zwykle jest elementem dużego grafu zależności) nie powinno z jednej strony powodować wczytania wszystkich elementów powiązanych (szybko okazałoby się, że wczytujemy bardzo dużo niepotrzebnych danych), a z drugiej – dzięki słabemu wiązaniu, umożliwiać GC łatwe usuwanie danych z pamięci, nawet jeśli są one osiągalne z aktualnie dostępnych zmiennych. Ten drugi wymóg dotyczy sytuacji, w której wczytano pewne dane, dokonano analizy i dodatkowe informacje nie są już potrzebne, ale dalej rezydują w pamięci. Luźne wiązanie pozwala łatwo się ich pozbyć.

Biblioteka Rod implementuje większość z tych funkcjonalności (obecnie jedynie uzupełnianie związków między danymi nie jest wspierane). W niedalekiej przyszłości zamierzam wydać słownik języka polskiego oraz narzędzie do tworzenia korpusów, które będzie oparte o tę bibliotekę. Z ciekawych własności słownika: powinien on umożliwiać poprawne generowanie opisów dla błędów w formularzach, np. “W formularzu jest 1 błąd/2 błędy 5 błędów”, “Nazwa nie może być pusta”, “Adres nie może być pusty” oraz np. właściwe generowanie opisów typu: “Ania skomentowała twój status”, “Wojtek skomentował twój status”.

Oczywiście wszystko będzie dostępne jako biblioteka Rubiego.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Virtuoso - podstawy 5 Apr 2011 1:10 AM (14 years ago)

Dlaczego Virtuoso?

Obecnie jest już sporo narzędzi pozwalających na przechowywanie danych w formacie RDF oraz zadawanie pytań w języku SPARQL. Ponieważ obecnie nie mam czasu żeby przyjrzeć się szczegółowo nawet tym najbardziej popularnym (AllegroGraph, Sesame 2, OWLime, D2R, OntoBroker, Virtuoso), aby przechowywać dane, które są co prawda dostępne jako RDF, ale nie posiadają dedykowanego SPARQL endpointu, oparłem się na wyborze jakiego dokonali twórcy DBpedii, tj. Virtuoso. Narzędzie to występuje w wersji komercyjnej oraz wolnej, więc z jednej strony można mu się swobodnie przyjrzeć, a z drugiej, czas na to poświęcony raczej nie będzie stracony, jeśli w przyszłości zechcemy wykorzystać je w jakimś komercyjnym projekcie, dla którego potrzebna będzie większa wydajność oraz support.

Instalacja

Virtuoso OpenSource można ściągnąć ze strony producenta lub za pośrednictwem dedykowanego dla naszego systemu operacyjnego narzędzia do zarządzania pakietami (odpowiednie paczki istnieją np. dla Gentoo oraz Debiana), dlatego z instalacją nie powinno być problemu.

Konfiguracja

Zainstalowane ze źródeł Virtuosu (przynajmniej pod Gentoo) nie posiada żadnych plików konfiguracyjnych, dlatego musimy przygotować sami minimalną konfigurację. Może ona wyglądać następująco:

[Database]
DatabaseFile=/var/lib/virtuoso/db/virtuoso.db
TransactionFile=/var/lib/virtuoso/db/virtuoso.trx
ErrorLogFile=/var/lib/virtuoso/db/virtuoso.log
[Parameters]
DirsAllowed=/path/to/dir
[HTTPServer]
ServerPort=8080

Konfigurację tę możemy umieścić np. w pliku /etc/virtuoso.ini.

Poszczególne zmienne konfiguracyjne zasadniczo są samoopisujące – z wyjątkiem może DirsAllowed. Ten parametr ustala ścieżki, z których będziemy mogli ładować pliki zewnętrzne. Ustalenie go jest kluczowe dla punktu, w którym będziemy ładować dane zewnętrzne.

Uruchomienie serwera i klienta

Serwer uruchamiany jest za pomocą polecenia virtuoso-t. Polecenie to przyjmuje kilka opcji, w szczególności kluczowe jest określenie pliku konfiguracyjnego. Służy do tego opcja +configfile. Dodatkowo przy pierwszym uruchomieniu możemy zażądać, aby serwer nie działał w tle (opcja +foreground), dzięki czemu w razie problemów będziemy mogli zobaczyć co jest nie tak.

$ virtuoso-t +configfile /etc/virtuoso.ini +foreground
        Tue Apr 05 2011
12:23:07 INFO: OpenLink Virtuoso Universal Server
12:23:07 INFO: Version 06.01.3127-pthreads for Linux as of Mar  8 2011
12:23:07 INFO: uses parts of OpenSSL, PCRE, Html Tidy
12:23:07 INFO: Database version 3126
12:23:07 INFO: SQL Optimizer enabled (max 1000 layouts)
12:23:08 INFO: Compiler unit is timed at 0.000694 msec
12:23:11 INFO: Roll forward started
12:23:11 INFO: Roll forward complete
12:23:12 INFO: Checkpoint started
12:23:13 INFO: Checkpoint finished, log reused
12:23:15 INFO: HTTP server online at 8080
12:23:15 INFO: Server online at 1111 (pid 15156)

Kiedy uruchomimy serwer, możemy sprawdzić go w działaniu wykorzystując polecenie isql-v. Otwiera ono interaktywną sesję pracy z serwerem:

$ isql-v
SQL> sparql select * where {?s ?p ?o} limit 10;

Powłoka klienta pozwala na bezpośrednie przeglądanie bazy danych, na której działa Virtuoso, za pomocą zwykłych poleceń SQL-owych. Dlatego zapytania SPARQL-owe muszą być poprzedzone słowem kluczowym SPARQL. Przykładowe zapytanie przedstawione jest powyżej. Niemniej dla świeżej instalacji Virtuoso nie zwróci ono żadnych rezultatów.

Ładowanie istniejących danych

Żeby poeksperymentować z zapytaniami SPARQL musimy załadować jakieś dane RDF. Są one dostarczane przez wiele organizacji (np. DBpedię, Umbel, itp) w postaci RDF+XML lub innego popularnego formatu, np. n3. Zazwyczaj dane takie dostępne są w postaci jednego dużego pliku lub, w przypadku bardzo dużych zbiorów, w postaci kilku mniejszych plików.

Możemy je załadować do własnej instancji Virtuoso wykonując następujące kroki:
  1. w pliku konfiguracyjnym zezwalamy na ładowanie plików z katalogu, w którym przechowujemy ściągnięte pliki
  2. ściągamy i uruchamiamy skrypt pozwalający na masowe ładowanie danych
  3. w konsoli Virtuoso wykonujemy polecenie/a ld_dir
  4. w konsoli Virtuoso wykonujemy polecenie df_loader_run

Pierwszy krok został opisany w punkcie “Konfiguracja”.

Po ściągnięciu pliku, wskazanego w drugim punkcie, zapisujemy go w aktualnym katalogu, np. pod nazwą rdfloader.sql, następnie w tym samym katalogu wywołujemy polecenie isql-v. Następnie w konsoli SQL wywołujemy polecenie load rdfloader.sql:

$ ls
rdfloader.sql
$ isql-v
SQL> load rdfloader.sql;

Jeśli za kilka dni będziemy chcieli załadować kolejną paczkę danych, to procedury tej nie trzeba będzie już powtarzać.

Kolejny krok polega na wskazaniu katalogu, z którego chcemy załadować dane. Polecenie ld_dir przyjmuje trzy argumenty:

Pierwszy argument nie wymaga wyjaśnienia. Drugi argument pozwala określić szablon (tak jak dla polecenia ls), np. ’*.n3’ lub wskazać konkretny plik, np. dbpedia.n3. Trzeci argument jest o tyle istotny, że pozwala przechowywać w jednej instancji semantycznej bazy dane z różnych źródeł i odwoływać się do nich niezależnie za pomocą klauzuli WHERE. Warto wybrać nazwę wskazującą źródło danych w postaci adresu URL, np. http://dbpedia.org.

Przykładowe polecenie może wyglądać następująco:

SQL> ld_dir('/home/user/rdf/dbpedia','*.n3','http://dbpedia.org');

Wbrew oczekiwaniom polecenie to nie załaduje od razu danych do bazy. Dopiero kolejne polecenie df_loader_run, spowoduje załadowanie danych. Przed jego wykonaniem należy uzbroić się w cierpliwość, gdyż może zająć to całkiem sporo czasu.

SQL> rdf_loader_run ();

Przykładowe użycie

Jeśli wszystko przebiegło poprawnie, to powinniśmy mieć możliwość korzystania z załadowanych danych poprzez SPARQL end-point. Możemy go najpierw przetestować w konsoli isql-v:

sparql select * from <http://dbpedia.org> where {?s ?p ?o} limit 5;
http://dbpedia.org/resource/Autism          http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://www.w3.org/2002/07/owl#Thing
http://dbpedia.org/resource/Alabama         http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://www.w3.org/2002/07/owl#Thing
http://dbpedia.org/resource/Aristotle       http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://www.w3.org/2002/07/owl#Thing
http://dbpedia.org/resource/Academy_Award   http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://www.w3.org/2002/07/owl#Thing
http://dbpedia.org/resource/Actrius         http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://www.w3.org/2002/07/owl#Thing

Innym sposobem dostępu jest wykorzystanie wbudowanego serwera WWW. Otwieramy stronę pod adresem http://localhost:8080/sparql i od razu możemy zadawać zapytania SPARQL.

Możemy również przetestować działanie end-pointu z poziomu jakiegoś języka programowania, np. Rubiego:

require 'sparql/client'
client = SPARQL::Client.new("http://localhost:8080/sparql")
results = client.query("select * where {?subject ?predicate ?object} limit 5")
results.each{|r| puts "#{r.subject} #{r.predicate} #{r.object}"}

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Rails 3 and UJS with jQuery 27 Nov 2010 11:56 PM (14 years ago)

Recently I tried to convert my Rails 2.3 application into Rails 3.0. There are various tutorials covering this problem, so I just concentrate on one issue which is not well described – namely the UJS functionality introduced in Rails 3.

Generally I agree with the idea, that UJS is a good solution – the HTML we had with calls link_to_remote and the like was really ugly, and this ugliness is not just something unimportant IMHO (especially when you have to look at the page source). So I welcome this feature appreciatively.

So it seemed that the switch should to be as easy, as replacing the old:

link_to_remote "tilte", :url => {...}, :update => "some_id"

with

link_to "title", {...}, :remote => true

but… as you might see in this piece of code above, the :update key, which I found very useful, is missing in the new syntax. I thought – “Strange”, but who cares – there must be some rationale for that, just another piece of Rails/jQuery magic. But when I started googling, I “discovered” that there is no good substitution for :update. Especially in Ryan’s recent railscast the solution was really disappointing, I mean this line of code in index.js.erb:

$("#products").html("<%= escape_javascript(render("products")) %>");

What?! Do I have to write this piece of sh… for every remote action? Where is the beauty of Rails’ DRYness?

But just the next day after implementing this in my application, I thought “There must be some solution for that”. And there is!

If you wish to preserve the old behavior of link_to_remote without lousing the benefits of UJS, do the same as you did, namely:

link_to "title", {...}, :remote => true, :"data-update" => "some_id"

(We use :"data-update" instead of :update to be more HTML 5 compliant. You could use :update, but then you would have to adapt the code below appropriately.)

And then add this little piece of code to your application.js:

jQuery(function($) {
$("a[data-update]").live("ajax:success", function(data,status,xhr){
      $("#"+$(this).attr("data-update")).html(status);
    });
});

And that’s it! The :update behavior should work as previously (and don’t ask me why I use “status” variable for something which has semantic of “data” – the names are taken directly from the official rails.js file).

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

ISWC 2010 dzień 1 19 Nov 2010 2:37 AM (14 years ago)

mc shraefel – invited talk

Nie wiem dokładnie o co chodzi z imieniem i nazwiskiem Pani “mc shraefel”, ale wszędzie pojawia się ono z małej liter, więc pozostaję przy tej konwencji.

Prezentacja zaczęła się w nieoczekiwany sposób, gdyż uczestnicy musieli wstać, machać rękami i bujać się na biodrach. Wśród niektórych wywołało to małą konsternację, ale niewątpliwie wszyscy się obudzili, a niektórzy przynajmniej na chwilę odłożyli swoje komputery.

W zasadzie cała prezentacja mc, koncentrowała się na zagadnieniach usability technologii semantycznych. Podstawowa jej obserwacja, która chyba wywołała najwięcej niezadowolenia audytorium, dotyczyła faktu, że właściwie każda z prezentowanych jej aplikacji opartych o Semantic web, dla przeciętnego użytkownika Internetu w zasadzie była niezrozumiała. Trudno nie zgodzić się jednak z tą obserwacją, jeśli widzi się, że kolejne aplikacje pokazują dane RDF w coraz to nowych konfiguracjach, z coraz to nowymi ikonkami, ale nic sensownego z tego nie wynika. Oczywiście jest to zgrubna ocena, ale też ważny sygnał dla firm, które chciałyby komercjalizować tego typu technologie. Oczekiwanie, że użytkownik oglądając jakąś dziwną tabelkę z dziwnymi napisami będzie zachwycony jest mało realne.

Oczywiście jako przeciwwaga pokazany został interfejs projektu, nad którym pracuje mc. Zasadniczo w ogóle nie było wiadomo, że jest to aplikacja Semantic Web – interfejs był tekstowy. Użytkownik mógł wprowadzać zapytania w języku zbliżony do naturalnego, no i na tym cała rzecz się opierała (coś podobnego do firefoxowego Ubiquity).

Konkluzją prezentacji było stwierdzenie – niech tematem kolejnej ISWC będą zwykli użytkownicy i ich potrzeby, a nie kolejne dyskusje nad przewagą OWL-a nad RDFS i vise-versa.

Doctoral consortium i NLP

Po prezentacji mc shraefel przeniosłem się do sali, w której prezentacje mieli studenci. Przyznam szczerze, że prezentacje mnie nie powaliły. Generalnie większość z nich miała podobny problem – chcieli poruszyć zbyt wiele tematów w jednej pracy. Co więcej, choć ambicje prezentujących były duże, to prezentacje wycinkowe i zazwyczaj koncentrowały się na zagadnieniach już dość dobrze zbadanych (np. ekstrakcja relacji taksonomicznych z Wikipedii). Dlatego szybko przeniosłem się na prezentację Supporting Natural Language Processing with Background Knowledge: Coreference Resolution Case.

W prezentowanym artykule autorzy pokazują, jak można wykorzystać statystyczne algorytmy w połączeniu z wiedzą dostępną w Semantic Web, aby ulepszyć wyniki uzyskiwane dla różnych zadań z dziedziny ekstrakcji informacji, w tym wypadku w zadaniu rozpoznawaniu koreferencji między dokumentami. Autorzy proponują, aby użyć Wikipedii jako punktu odniesienia dla innych źródeł wiedzy. Niewątpliwie nie jest to zaskakujące rozwiązanie. Duża część artykułu poświęcona jest zagadnieniu wyboru tych relacji, spośród wielu występujących w źródłach Semantic Web, które istotne są z punktu widzenia skuteczności algorytmu. Wiadomo bowiem, że dane dostępne jako Linked Data nie są zbalansowane i nierzadko dla określonych zasobów (np. Obamy) istnieją setki faktów, a dla innych zaledwie kilka. Prezentacja niewątpliwie ciekawa, ale w moim przekonaniu zastanawiające jest użycie statystycznych metod do określenia istotnych cech zasobów, zamiast wykorzystanie jawnej reprezentacji, która jest jedną z podstawowych zalet zasobów udostępnianych w jako Linked Data.

Z pozostałych prezentacji, które obejrzałem tego dnia, chyba żadna nie zapadła mi specjalnie w pamięć. Były to m.in. dyskusja panelowa nad formatem RIF, “I18n of Semantic Web Applications”, “Mapping Master: a Flexible Approach for Mapping Spreadsheets to OWL” oraz “ISReal: An Open Platform for Semantic-Based 3D Simulations in the 3D Internet”.\

Tego dnia pokazywałem również swoje demo, w którym dla danych udostępnianych jako Linked Data, tworzone były polskie opisy. Niestety ze względu na tymczasową niedostępność serwisu MusicBrainz, demo nie działało :( No cóż – taka natura Semantic Web. Ale przynajmniej mogłem sobie porozmawiać z kilkoma osobami, które udawały, że chcą się nauczyć języka polskiego (ponieważ nie miałem plakatu, zamieściłem tylko krótką notkę, że można nauczyć się naszego języka ;) ). Kilka dyskusji było niewątpliwie ciekawych, ale ich konkluzje pozostawiam dla siebie.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

ISWC 2010 COLD 7 Nov 2010 4:21 PM (14 years ago)

Ciekawsze prezentacje z warsztatów COLD w ramach konferencji International Semantic Web Conference 2010

Capturing Emerging Relations between Schema Ontologies on the Web of Data

Autorzy pokazują jak można ustalać relację ekwiwalencji pomiędzy klasami wykorzystywanymi w Linked Data. Zasadnicza idea opiera się na wykorzystaniu relacji “sameas” na poziomie instancji. Okazuje się, że proste drzewo decyzyjne pozwala uzyskać precyzję na poziomie przekraczającym 90%. Problem, który utrudnia wykorzystanie rezultatów tego rodzaju, jest m.in. zmienność schematów konceptualnych używanych w różnych bazach wiedzy. Ponadto operowanie na poziomie instancji dużych zbiorów danych jest bardzo czasochłonne.

The R2R Framework: Publishing and Discovering Mappings on the Web

Autorzy przedstawiają metodykę oraz język, który mają pomóc w rozwiązaniu jednego z podstawowych problemów Semantic Web, tzn. występowania wielu niezależnych taksonomii. Podstawowa idea polega umożliwieniu publikowania oraz odnajdywania mapowań pomiędzy różnymi schematami konceptualnymi.

Autorzy wymieniają następujące problemy, który pojawiają się, kiedy używamy różnych schematów konceptualnych, a nawet tych samych schematów konceptualnych w różnych źródłach danych:

Autorzy proponują nowy język R2R zbudowany na podstawie SPARQL, który pozwalałby na opisywanie przekształceń, które muszą być dokonane aby dopasować do siebie różne źródła danych, ponieważ dotychczasowe rozwiązania zdefiniowane w OWL i SKOS są niewystarczające do rozwiązania wszystkich wyżej przedstawionych problemów.

Propozycja polega na dodanie rozbudowanych szablonów mapowania, które uwzględniają wszystkie wyżej wymienione problemy. Ponadto zaproponowane rozwiązanie umożliwia tworzenie łańcuchów przetwarzania (tzn. mapowania poprzez schematy pośrednie) oraz uwzględnia meta dane na temat twórcy mapowania, jego jakości, etc.

Rozwiązanie wydaje się jednak dosyć nietrafione – istnieje wiele formalnych rozwiązań, które adresują powyższe problemy. Zdecydowanie lepiej byłoby objąć w rozwiązaniu tylko te elementy, które nie dają się załatwić na poziomie deklaratywnym. W szczególności odnosi się to do dopasowania klas, własności oraz jednostek (w końcu można wprost opisać jednostki, które używane są w określonym DS, albo wymusić używanie określonych jednostek w samej ontologii). W szczególności rezygnacja z wykorzystania predykatów sameAs, equivalentClass, equivalentProperty wydaje się najgorszym pomysłem.

Wydaje się natomiast, że niektóre aspekty są zupełnie pomijalne – np. etykieta A. Einstein vs Albert Einstein. Jeśli tylko będzie ustalona relacja sameAs pomiędzy odpowiednimi zasobami, takie różnice będą zupełnie nieistotne (jest to jedna z podstawowych idei leżących u podstaw Semantic Web – tzn. reidentyfikacja przez URL a nie te lub inne własności).

PS. Autorzy są twórcami DBpedii. Rozmawiałem z autorem prezentacji i wyjaśnił, że predykaty sameAs, etc. będą wykorzystywane przez prezentowane narzędzie, ale po co zatem dodawać nowe rozwiązanie służące do tego samego?

Consuming multiple linked data sources: Challenges and Experiences

Zasadniczy problem poruszany w artykule dotyczy efektywnego wykonywania zapytań w języku SPARQL obejmujących wiele zbiorów danych. Autorzy zwracają uwagę na dwa aspekty zagadnienia: Dotychczasowe podejście do problemu przedstawione jest na przykładzie dwóch wcześniejszych rozwiązań:

Propozycja przedstawiona przez autorów opiera się na doświadczeniu zdobytym z narzędziem RKBExplorer. Służy ono do dostarczania informacji na temat społeczności praktyków pracujących nad jakimś zagadnieniem naukowym. W szczególności narzędzie to powinno dostarczać informacje na temat osób, ich publikacji, tematów badań itp. Zaproponowane rozwiązanie sprowadza się do dostarczenie specyficznych połączeń zapytań, które mają być wykonywane na wielu zbiorach danych. W szczególności chodzi o to, by fragmenty zapytania mogły być wykonywane wewnątrz jednego zbioru danych, natomiast całość może obejmować wiele zbiorów. Choć rozwiązanie to posiada istotne ograniczenia, dla zadania, w którym było wykorzystywane uzyskana wydajność była zadowalająca. Co więcej zbiory danych różnego typu (surowe dane RDF oraz dane dostępne za pomocą języka SPARQL) są obsługiwane w tym rozwiązaniu.

IBM Jeopardy! Challenge

Zdecydowanie najciekawsza prezentacja z tych warsztatów – przedstawiciel IBM-a – Chris Welty przedstawił projekt o rozmachu podobny do Deep Blue. Duży zespół naukowców z IBM Research pracuje nad systemem odpowiadającym na pytania, który mógłby konkurować z ludźmi w grze podobnej do naszego “Va Banque” (w istocie rzeczy Va Banque był realizowany na licencji Jeopardy). Cały problem polega na tym, że osoby wygrywające ten teleturniej zazwyczaj odpowiadają w ciągu kilku sekund, i w przeważającej liczbie przypadków nie mylą się. Dodatkowym utrudnieniem jest fakt, że pytanie zadawane jest nie wprost.

Zatem system, który mógłby konkurować z ludźmi musiałby poprawnie analizować zdanie, posiadać olbrzymią wiedzę faktograficzną oraz określać właściwą odpowiedź w czasie kilku sekund. Niestety w gruncie rzeczy uczestnicy konferencji nie dowiedzieli się zbyt wiele, poza ogólnikowymi stwierdzeniami, że kluczową własnością systemu, jest zdolność do prawidłowej oceny odpowiedzi. Padło też dosyć enigmatyczne stwierdzenie, że w systemie tego rodzaju niezbyt istotna jest wiedza “zdroworozsądkowa”, której tak wiele uwagi poświęcają twórcy ontologii, ale wiedza faktograficzna. Z pytania, które zadałem Weltyemu wynikało jednak, że chodzi tutaj przede wszystkim o odpowiednie określenie kategorii semantycznej obiektu podlegającego ocenie. Niewątpliwie jest to wiedza faktograficzna, ale z drugiej strony wątpię, by można obyć się bez pewnych inferencji realizowanych na jej podstawie.

Dosyć zabawne było również rozwiązanie problemu ograniczeń czasowych – system generuje bowiem tysiące hipotetycznych odpowiedzi i każda z nich analizowana jest na odrębnej maszynie. Zatem system działa w oparciu o wielotysięczny klaster komputerów. A nad samym systemem pracuje kilkudziesięcioosobowa grupa naukowców z IBMa. Nie dowiedzieliśmy się również, jaka jest jego obecna skuteczność, choć przez przypadek pojawił się taki slajd (którego miało nie być… :] )

W każdym razie system wzbudził duże zainteresowanie i niewątpliwie można się spodziewać, że niedługo zostanie pokazany całemu światu, jako kolejne wielkie dzieło IBMa.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Zestawienie poleceń: Git i SVN 5 Jun 2010 4:00 AM (14 years ago)

Yehuda Katz opublikował artykuł, w którym pokazuje, jak wygląd jego typowa sesja edycji kodu w kontekście Git-a. Cały artykuł warty jest przeczytania, natomiast tabelka, która pojawia się na końcu zdecydowanie może służyć za ściągę z Gita, dla wcześniejszych użytkowników SVN-a. Pozwalam ją sobie przerysować:

Operacja git svn
Klonowanie repozytorium git clone git://github.com/rails/rails.git svn checkout http://dev.rubyonrails.org/svn/rails/trunk
Przygotowywanie zmian git add, git commit brak lub ręczne przygotowanie diff-a
Ściąganie zmian z repozytorium git pull --rebase svn up
Rozstrzyganie konfliktów git add, git rebase --continue svn resolve
Rozstrzyganie konfliktów (bez—rebase) git add, git commit brak
Wycofywanie zmian (przygotowanych do wysłania) git reset --hard svn up -rOLD potem zaaplikowanie diff-a (jeśli pamiętałeś żeby go zrobić)
Publikowanie do repozytorium git push svn commit

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Musicbrainz w Rubim 22 May 2010 3:44 AM (14 years ago)

SemanticWeb i Ruby

Niestety nie mam zbyt wiele czasu, aby tłumaczyć ideę SemanticWeb. W dwóch słowach można powiedzieć, że chodzi możliwość pobierania danych z Internetu w sposób zbliżony do podbierania danych z relacyjnej bazy danych. Oczywiście biorąc pod uwagę immanentny internetowy pluralizm, trudno wyobrażać sobie, że taka “baza danych” mogłaby posiadać wspólny schemat, dlatego też jednym z kluczowych elementów SemanticWeb jest koncepcja ontologii – w tym kontekście: specyfikacji pojęć, które służą do opisu danych.

Na dzień dzisiejszy jedną z najbardziej doniosłych manifestacji tej idei jest Linked Open Data i słynna chmura ontologii, czyli obrazek, który ma nas przekonać, że inwestując w ideę SemanticWeb, można już pobrać bardzo dużo danych w ten sposób i, co więcej, dane te nie będą odizolowane, ale przynajmniej w pewnym stopniu powiązane z innymi danymi, publikowanymi przez rozmaite podmioty.

Jednym z kluczowych elementów SemanticWeb staje się DBpedia, która jest ontologią powstałą na bazie informacji wyekstrahowanych z angielskiej (ale nie tylko) Wikipedii. Coraz więcej innych zasobów jest “linkowanych” do DBpedii, dzięki czemu staje się ona w dużej mierze ontologią (schematem) odniesienia.

Czy faktycznie można już wykorzystywać powiązania pomiędzy poszczególnymi źródłami wiedzy pozostaje kwestią dyskusyjną (np. przedstawione na obrazku powiązanie DBpedii z Musicbrainzem wydaje się mocno wątpliwe, gdyż najistotniejsze elementy – czyli klasy, nie są powiązane), niemniej jednak warto śledzić rozwój tej koncepcji, gdyż istotnie staję się ona coraz poważniej traktowana również przez instytucje komercyjne (np. Reuters, BBC).

Jako, że moim ulubionym językiem jest Rubi, jakiś czas temu testowałem możliwość wykorzystania biblioteki ActiveRDF do pobierania danych z DBpedii. W tamtym poście jest w zasadzie tylko kod i jeśli nie miało się styczności z ActiveRDF trudno cokolwiek z niego wywnioskować. W niniejszym poście chciałbym przedstawić inny przykład wykorzystania ActiveRDF, tym razem do pobierania danych z Musicbrainza, czyli wielkiej bazy zawierającej dane dotyczące tysięcy muzyków, płyt, utworów muzycznych i tym podobnych.

ActiveRDF

ActiveRDF, jak można wnioskować na podstawie nazwy, ma uczynić nasze życie z SemanticWeb znacznie prostszym (podobnie jak ActiveRecord czyni prostszym (?) obsługę relacyjnych baz danych). Niestety po tym jak twórca tej biblioteki, czyli Eyal Oren przestał się nią opiekować, straciła ona swoja początkową stabilność, a, co gorsza, wiele przykładów, które zostały udokumentowane, przestało działać w kolejnych wersjach. Jest to pewna przypadłość języków dynamicznych, w szczególności Rubiego, że twórcy rozwiązań mniejszą wagę przywiązują do zachowania stabilnego API – w myśl zasady: “lepsze wrogiem dobrego”, zapominając jednak, że często “działające lepsze od żadnego”. Pomijając jednak te filozoficzne dywagacje, warto wspomnieć, że obecnie ActiveRDF ma swoje konto na Githubie i jest rozwijane. Niemniej jednak uruchomienie najnowszej (1.7.0) wersji, w szczególności jeśli używamy Rubiego 1.9 nie jest wcale banalne.

Niestety aktualny opiekun biblioteki nie otagował tej wersji, nie wysłał jej także na gemcuttera, przez co skazani jesteśmy na budowanie gema ze źródeł, co wcale nie jest takie banalne (specyfikacja gemów zdefiniowana jest z użyciem jewelera, który jest niekompatybilny z Rubim 1.9). Dlatego najprościej jest ściągnąć mojego brancha 1_7_0

$ git clone git://github.com/apohllo/ActiveRDF.git
...
$ cd ActiveRDF

Niestety nie obejdzie się bez użycia Rubiego 1.8 do zbudowania gema. Ja korzystam z Gentoo, dlatego mogę zmienić wersję wykonując polecenie:

$ sudo eselect ruby set 1
Successfully switched to profile:
  ruby18
$ /usr/bin/ruby18 /usr/bin/rake build
(in /home/fox/src/ruby/ActiveRDF)
Gokdok is not available. Install with: gem install gokdok
Rcov or dependency is not available
Generated: activerdf_net7.gemspec
activerdf_net7.gemspec is valid.
WARNING:  no rubyforge_project specified
WARNING:  deprecated autorequire specified
  Successfully built RubyGem
  Name: activerdf_net7
  Version: 1.7.0
  File: activerdf_net7-1.7.0.gem
$ sudo eselect ruby set 2
Successfully switched to profile:
  ruby19
$ sudo gem install pkg/activerdf_net7-1.7.0.gem

Można również skorzystać z rvm, ale nie będę tego opisywał w szczegółach.

Kiedy mamy już zbudowany i zainstalowany gem activerdf w wersji 1.7.0 musimy jeszcze doinstalować odpowiedni adapter RDF. Ponieważ Musicbrainz eksponuje sparql endpoint, musimy doinstalować właśnie ten adapter:

$ cd activerdf-sparql/
$ gem build activerdf-sparql.gemspec
WARNING:  no email specified
WARNING:  no homepage specified
WARNING:  no rubyforge_project specified
WARNING:  description and summary are identical
  Successfully built RubyGem
  Name: activerdf-sparql
  Version: 1.3.6
  File: activerdf-sparql-1.3.6.gem
$ sudo gem install activerdf-sparql-1.3.6.gem
...

W tej chwili jesteśmy już w pełni wyposażeni aby korzystać z ActiveRDF w najnowszej wersji w Rubim 1.9

Musicbrainz

Sparql endpoint Musicbrainz jest obsługiwany przez serwer d2r, który oficjalnie nie jest wspierany przez aktualny adapter ActiveRDF. Najwyraźniej jednak standard SPARQL staje się na tyle dojrzały, że nie ma zbyt wielu różnic pomiędzy poszczególnymi implementacjami, dzięki czemu można wykorzystać np. implementację dla serwera Virtuoso.

require 'active_rdf'
include ActiveRDF
ConnectionPool.add(:type => :sparql, :url => 'http://dbtune.org/musicbrainz/sparql', :engine => :virtuoso)

Powyższy kod tworzy połączenie z ontologią Musicbrainz. Następnie rejestrujemy najistotniejsze przestrzenie nazw (FOAF:http://www.foaf-project.org/, oraz MusicOntology:http://musicontology.com/):

ActiveRDF::Namespace.register :foaf, 'http://xmlns.com/foaf/0.1/'
ActiveRDF::Namespace.register :mo, 'http://purl.org/ontology/mo/'

W zasadzie w tym momencie moglibyśmy już przeglądać zawartość Musicbrainza, ale jest jeszcze jeden haczyk – otóż najwyraźniej serwer D2R nie radzi sobie z zapytaniami, w których explicite podane są typy atrybutów (np. dla łańcucha znaków). Dlatego też musimy ustawić zmienną globalną (sic!) $activerdf_without_datatype na true:

$activerdf_without_datatype = true

Mam nadzieję, że w kolejnych wersjach ActiveRDF można będzie zrobić to w bardziej cywilizowany sposób. Tak, czy owak, w tej chwili możemy już przeglądać szczegółowe informacje na temat muzyków, zespołów i innych, np. W teorii wygląd prosto, ale w praktyce (ze względu na rozproszony charakter wiedzy), sprawy się komplikują:

sting = ActiveRDF::Query.new.select(:x).where(:x, FOAF::name, "Sting").execute[0]
sting.foaf::name.first
#=> "Sting" 
groups = ActiveRDF::Query.new.select(:x).where(:x, FOAF::member, sting).execute
groups.each{|g| puts g.foaf::name.first}
Strontium 90
The Police

W powyższym przykładzie z bazy pobieram zasób, który reprezentuje Stinga. Następnie odpytujemy się o jego “nazwę” – i tutaj właśnie pierwsza niespodzianka, bo musimy dla tej nazwy (które też jest zasobem) wywołać metodę “first”. Powód tego (w moim najlepszym mniemaniu) jest taki, że moglibyśmy mieć w kilku źródłach wiedzy różne wartości tego predykatu i musimy mieć dostęp do wszystkich.

Następnie pobieramy informacje o zespołach, w których grał Sting. Wykorzystujemy do tego predykat FOAF:member, który wiąże grupę z jej członkami (grupa jest podmiotem w tej relacji). Dostajemy dwa rezultaty, do których dobieramy się tak jak wcześniej.

Na koniec pobierzemy informacje o zarejestrowanych koncertach, w których Sting był wiodącym wokalistą:

performances = ActiveRDF::Query.new.select(:x).where(:x, MO::lead_singer, sting).execute
performances.each{|g| puts g.label}
#=> Sting performing (recorded on album Why Don't You Answer?)
#=> Sting performing (recorded on album Zenyattà Mondatta)

Jak widać powyżej, w bazie widnieją tylko informacje o dwóch zarejestrowanych koncertach.

Podsumowanie

Pomimo problemów jakie trzeba rozwiązać, korzystając z wiedzy zawartej w SemanticWeb, można przyjąć na chwilę obecną, że technologie semantyczne są już “używalne”, a w Rubim, czego mogliśmy się spodziewać, po przezwyciężeniu problemów konfiguracyjnych, można całkiem przyjemnie je przetwarzać.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

poliqarpr 0.0.5 10 Dec 2009 4:08 AM (15 years ago)

Poliqarpr jest nakładką dla Rubiego, pozwalającą w prosty sposób korzystać z serwera Poliqarp.

Poliqarp – serwer korpusów

Sam Poliqarp został pomyślany jako narzędzie ułatwiające pracę z korpusami tekstów. Jego zasadnicze przeznaczenie to wyszukiwanie fragmentów tekstów na potrzeby różnych zadań z dziedziny przetwarzania języka naturalnego. W obecnej chwili jest wykorzystywany w projekcie Narodowego Korpusu Języka Polskiego, ale został zaprojektowany w sposób, który pozwala stosować go również dla innych języków.

Co więcej – język zapytań Poliqarpa pozwala wyszukiwać słowa w korpusie nie tylko w oparciu o odmienione formy (wtedy nie różniłby się on specjalnie od funkcjonalności baz danych z wyszukiwaniem pełnotekstowym), ale pozwala np. określić, formę podstawową (tzw. lemat) słowa, a znalezione zostaną wszystkie wystąpienia, również form derywowanych (np. możemy zadać pytanie o “bój”, a w wynikach otrzymamy formy odmienione: boju, boje, bojom).

Również ta funkcjonalność nie jest związana wyłącznie z językiem polskim (choć ma zastosowanie głównie dla języków fleksyjnych), ani nie jest przywiązana do jednego zbioru tagów. Dzięki temu, w zależności od zastosowanego narzędzia, możemy korzystać z alternatywnych zbiorów tagów, nawet w ramach jednego języka.

Poliqarpr – klient napisany w Rubim, dla serwera Poliqarp

Poliqarpr, jak było wspomniane, jest napisanym w Ruby klientem, dla serwera Poliqarp. Jest on dostępny w publicznym repozytorium na GitHubie. Możemy go stamtąd pobrać za pomocą poniższego polecenia:

$ git clone git://github.com/apohllo/poliqarpr.git

Oczywiście jest on również dostępny jako gem na gemcutterze:

 # sprawdzamy wersję rubygems
$ gem -v
1.3.5 #=> OK!
 # dodajemy gemcutter do listy repozytoriów, jeśli wcześniej na niej nie był
$ gem sources -a http://gemcutter.org 
 # instalujemy poliqapr
$ gem install poliqarpr -a http://gemcutter.org
Successfully installed poliqarpr-0.0.5
1 gem installed
Installing ri documentation for poliqarpr-0.0.5...
Installing RDoc documentation for poliqarpr-0.0.5...

Jeśli wszystko przebiegnie bez zakłóceń możemy zacząć testować poliqarpa. Ponieważ jednak bez korpusu nie ma to większego sensu, dostępny jest również gem poliqarpr-corpus, który zawiera przykładowy korpus dla języka polskiego (zrównoważony słownik frekwencyjny).

Instalacja jest równie prosta:

$ gem install poliqarpr-corpus

W tym momencie musimy uzbroić się w odrobinę cierpliwości, bo korpus ma rozmiar kilku megabajtów.

Poliqarpr nie jest jedynym klientem dla serwera Poliqarp – dostępna jest również wersja w Javie, napisana przez autorów serwera. W stosunku do klienta javowego otrzymujemy jednak kilka udogodnień:

W szczególności to, że rezultaty zapytań są klasami, pozwala w łatwy sposób tworzyć paginację. Po szczegóły najlepiej zajrzeć do dostępnych w repozytorium speców.

Przykład użycia

Przypuśćmy, że mamy na naszym komputerze korpus języka polskiego o wielkości 250 mln segmentów, pobrany ze strony korpus.pl. Załóżmy, że znajduje się w katalogu /home/user/korpus. Co należy zrobić, aby można było go wygodnie przeglądać lub wykorzystać w programie napisanym w Rubim?

Po pierwsze musimy upewnić się, że serwer poliqarp jest zainstalowany i działa. Najprościej wykonać w linii poleceń następującą komendę:

$ poliqarpd &

Jeśli nie pojawią się żadne błędy, oznaczać to będzie, że serwer poliqarp został uruchomiony.

Następnie możemy skorzystać z serwera w programie napisanym w Rubim. Na wstępie musimy załadować zainstalowany wcześniej gem, stworzyć klienta oraz załadować korpus:

require 'poliqarpr'
client = Poliqarp::Client.new("TEST")
client.open_corpus("/home/user/korpus/all")
client.right_context = 10
client.left_context = 10
client.lemmata = :all
client.buffer_size = 1000

Kiedy tworzymy klienta, możemy przekazać opcjonalny parametr będący nazwą sesji z serwerem (pozwala odróżniać od siebie wiele jednocześnie połączonych klientów). Potem możemy otworzyć korpus (polecenie open_corpus), podając ścieżkę do jego katalogu, wraz z nazwą (tutaj używamy korpusu 250 mln segmentów, którego nazwa to “all”).

Opcjonalnie możemy również ustawić różne parametry dot. zwracanych rezultatów:

Kiedy dokonamy tych wstępnych ustaleń, możemy pobrać wyniki, dla wybranego zapytania (szczegóły składni języka zapytań omówione są w artykule na stronie dr. hab. Adama Przepiórkowskiego):

result = client.find("[base=kot]")
result[0..5].each do |excerpt|
  putes excerpt
end
 # – kukułka – piła – kot Zaznacz te obrazki, które
 # burza osy – ptaki – kot ptak – zegar – samochód
 # – orkiestra – telefon – kot Posłuchaj uważnie nagranych dźwięków i
 # ptaszek – burza lew – kot lecąca z kranu woda –
 # strumyk telefon – sowa – kot baran – lew – ptaszek

W powyższym przykładzie szukamy w korpusie wszystkich fragmentów, w których występuje wyraz “kot” w dowolnej formie. Następnie wyświetlany 6 pierwszych rezultatów. Każdy z rezultatów jest jednak pełnoprawnym obiektem, więc możemy przyjrzeć mu się szczegółowo:

result[0].author
#=> Małgorzata Pamuła
result[0].title
#=> Wczesne nauczanie języków obcych...
result[0].short_context.join("")
#=>  – kukułka – piła – kot Zaznacz te obrazki, które

API w chwili obecnej jest nieźle rozbudowane i udokumentowane, więc nie będę omawiał go szczegółowo.

Na koniec nie możemy zapomnieć o zamknięciu połączenia z serwerem:

client.close

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?