Upload
duongkhue
View
226
Download
0
Embed Size (px)
Citation preview
TEHNIČKO VELEUČILIŠTE U ZAGREBU
POLITEHNIČKI SPECIJALISTIČKI DIPLOMSKI
STRUČNI STUDIJ
Specijalizacija informatika
Davor Lozić
Ruby aplikacija za strojno učenje temeljena na
OrientDB bazi podataka
Zagreb, srpanj 2016.
TEHNIČKO VELEUČILIŠTE U ZAGREBU
POLITEHNIČKI SPECIJALISTIČKI DIPLOMSKI
STRUČNI STUDIJ
Specijalizacija informatika
Davor Lozić
JMBAG: 0246039199
Ruby aplikacija za strojno učenje temeljena na
OrientDB bazi podataka
Povjerenstvo:
dr. sc. Miroslav Slamić, profesor visoke škole, predsjednik _______________
Tin Kramberger, struč. spec. ing. techn. inf., predavač, član _______________
Aleksander Radovan, dipl. ing., viši predavač, mentor _______________
Zagreb, srpanj 2016.
Zahvala:
Veliku zahvalnost dugujem svom mentoru, v. pred. Aleksanderu Radovanu, dipl. ing. koji je bio munjevito
brz s odgovorima na sva moja pitanja i koji bi unutar 24 sata pregledao svaku inačicu ovog rada koju bih
mu poslao u bilo koje doba dana.
Također, zahvaljujem timu tvrtke Orient Technologies Pvt. Ltd. koji su u nekoliko navrata ubrzali
algoritme u ovom radu i bili dostupni za sva moja pitanja te mi pružili besplatne tjedne edukacije.
Velika hvala i prof. dr. sc. Mario-Osvinu Pavčeviću za predavanja i odgovore na sva moja pitanja na
kolegiju Teorija grafova na Fakultetu elektrotehnike i računarstva Sveučilišta u Zagrebu.
I na kraju, najveća zahvala mojoj majci koja me svaki dan podsjećala kako moram manje raditi, a više
pisati diplomski te me nasmijavala kako, dok sam bio mali i nisam znao govoriti me sve razumjela, a sada
kada sam odrastao i dok čita moj diplomski, više me ništa ne razumije.
Sažetak
Ovaj se radi bavi implementacijom algoritama iz područja strojnog učenje na OrientDB graf bazi
podataka. Rad pokazuje kako graf, kao struktura proizašla iz matematike, jednostavnije i zahvalnije
prikazuje odnose među entitetima te omogućuje lakše uočavanje njihovih svojstava. Rad objektivno
prikazuje dobre i loše strane samog pristupa, odabira dodatnih tehnologija, algoritama, same OrientDB
baze podataka te daje teoretsku podlogu za daljnja istraživanja na području analize socijalnih mreža.
Praktični dio rada bavi se implementacijom MovieLens baze podataka te prijedlogom novih filmova u
odnosu na ocijenjene filmove u prošlosti. U sustavu je implementiran Pearsonov korelacijski koeficijent,
ali se navode i alternative poput euklidske udaljenost ili Jaccard indeksa.
Sadržaj
Popis formula................................................................................................................................. 7
Popis pojmova i kratica ................................................................................................................ 8
Popis programskih isječaka ......................................................................................................... 9
Popis tablica................................................................................................................................. 10
Popis slika .................................................................................................................................... 11
1. Uvod ........................................................................................................................................ 1
2. Kolektivna inteligencija......................................................................................................... 3
2.1. MovieLens......................................................................................................................... 3
3. Pronalazak sličnih korisnika ................................................................................................ 4
3.1. Euklidska udaljenost......................................................................................................... 5
3.2. Pearsonov korelacijski koeficijent ..................................................................................... 6
3.3. Jaccard indeks .................................................................................................................. 8
3.4. Zaključak mjera sličnosti .................................................................................................. 9
4. Teorija grafova..................................................................................................................... 10
4.1. Definicija grafa ............................................................................................................... 10
4.2. Šetnje, ciklusi i putevi ..................................................................................................... 11
4.3. Bipartitni grafovi ............................................................................................................ 12
5. Analiza socijalnih mreža teorijom grafova ....................................................................... 14
5.1. Međujstvo ....................................................................................................................... 14
5.2. Eigenvektor..................................................................................................................... 15
5.3. Zaključak SNA analize.................................................................................................... 16
6. OrientDB .............................................................................................................................. 17
6.1. NoSQL ............................................................................................................................ 17
6.2. Problemi s relacijskim modelom ..................................................................................... 18
6.3. OrientDB graf baza i rješavanje problema spajanja nekoliko tablica ............................. 18
6.4. Pokretanje OrientDB baze .............................................................................................. 20
6.5. Korištenje OrientStudia .................................................................................................. 21
6.6. SQL................................................................................................................................. 23
6.7. Klase ............................................................................................................................... 24
7. MovieLens baza unutar OrientDB sustava ....................................................................... 26
7.1. Spajanje Jave i OrientDB baze podataka ........................................................................ 26
7.2. Sustav za preporuku novih filmova ................................................................................. 27
8. Ruby i Rails .......................................................................................................................... 33
9. Zaključak .............................................................................................................................. 35
10. Literatura......................................................................................................................... 36
Popis formula
Euklidska udaljenost (1)
Normalizirana euklidska udaljenost (2)
Pearsonov korelacijski koeficijent (3)
Jaccard indeks (4)
Šetnja u teoriji grafova (5)
Lema o rukovanju (6)
Međujstvo (7)
Izračun eigenvektora (8)
Popis pojmova i kratica
ACID - atomnost, konzistentnost, izoliranost i trajnost (engl. Atomicity, Consistency, Isolation,
Durability)
CSV - zarezom odvojene vrijednosti (engl. comma separated value)
HTTP (engl. HyperText Transfer Protocol)
JSON (engl. JavaScript Object Notation)
SNA - analiza socijalnih mreža (engl. social network analysis)
SQL - strukturirani upitni jezik (engl. structured query language)
Popis programskih isječaka
Isječak 1 - testni podaci u programskom jeziku Python
Isječak 2 - implementacija euklidske udaljenosti u programskom jeziku Python
Isječak 3 - implementacija Pearsonovog korelacijskog koeficijenta u programskom jeziku Python
[1]
Isječak 4 - implementacija Jaccard indeksa u programskom jeziku Python
Isječak 5 - pokretanje OrientDB baze u normalnom načinu rada
Isječak 6 - jednostavno straničenje
Isječak 7 - osnovne SELECT naredbe
Isječak 8 - SQL INSERT naredba
Isječak 9 - SQL DELETE naredba
Isječak 10 - izrada klase Osoba
Isječak 11 - dodavanje nove osobe
Isječak 12 - unos korisnika bez OIB-a, upit koji se neće uspješno izvršiti
Isječak 13 - spajanje Jave i OrientDB baze
Isječak 14 - unos MovieLens korisnika u OrientDB sustav
Isječak 15 - izrada klase Korisnik
Isječak 16 - unos korisnika iz CSV-a u OrientDB
Isječak 17 - dohvaćanje liste filmova koje je korisnik ocijenio
Isječak 18 - pomoćne funkcije za obradu liste filmova
Isječak 19 - implementacija Pearsonovog korelacijskog koeficijenta
Isječak 20 - funkcija koja poziva izračun koeficijenta i odabire nove filmove
Isječak 21 - instalacija orientdb4r biblioteke
Isječak 22 - Rails kontroler
Popis tablica
Tablica 1 - primjer NoSQL baza podataka
Tablica 2 - Usporedba relacijskog modela, dokument modela i dokument modela u OrientDB bazi
podataka
Tablica 3 - usporedba relacijskog modela, graf modela i graf modela u OrientDB bazi
Popis slika
Slika 1 - dva filmska kritičara s visokim stupnjem korelacije (slika preuzeta iz knjige T. Segaran
„Programming Collective Intelligence“, 12. stranica) [1]
Slika 2 - dva filmska kritičara s niskim stupnjem korelacije (slika preuzeta iz knjige T. Segaran
„Programming Collective Intelligence“, 12. stranica) [1]
Slika 3 - Jaccard indeks - presjek zajedničkih elemenata (slika izrađena unutar WolframAlpha
sustava)
Slika 4 - Königsbergovi mostovi predstavljeni grafom
Slika 5 - Usmjereni graf s težinama
Slika 6 - vrh B sa stupnjem vrha 4
Slika 7 - primjer ciklusa
Slika 8 - bipartitni graf
Slika 9 - potpuni bipartitni graf
Slika 10 - vrh A s najvećim međujstvom
Slika 11 - vrh A ima najveći eigenvektor
Slika 12 - graf model se oslanja na dokument model
Slika 13 - prikaz uspješno inicijaliziranog OrientDB sustava u normalnom načinu rada
Slika 14 - OrientStudio prijava
Slika 15 - različiti moduli za upravljanje OrientDB bazom podataka
Slika 16 - primjer jednostavnog SQL upita
Slika 17 - ispis pogreške prilikom dodavanja korisnika bez OIB-a
Slika 18 - MovieLens popis datoteka
Slika 19 - arhitektura sustavaSlika 1 - dva filmska kritičara s visokim stupnjem korelacije (slika
preuzeta iz knjige T. Segaran „Programming Collective Intelligence“, 12. stranica) [1]
1
1. Uvod
Teorija grafova je znanost proizašla iz matematike, a pronalazi sve više primjene u opisu relacija u
fizičkim, biološkim, sociološkim i informacijskim procesima. Sustavi temeljeni na teoriji grafova jedni su
od obećavajućih alternativa ili dopuna relacijskim bazama podataka. Ovaj se rad temelji na primjenama
teorije grafova u informacijskim sustavima, ponajviše u strojnom učenju. Strojno učenje u sustavima
velikih količina podataka (engl. big data) donosi značajne pomake u mnogim aspektima poslovanja.
Statistike pokazuju da analitičari specijalizirani za obradu velikih količina podataka uvelike utječu na
poslovanje tvrtki. U radu je korištena „MovieLens“ baza podataka koja u trenutku pisanja rada ima 21
milijun ocjena i 510 tisuća oznaka primijenjenih na 30 tisuća filmova koje je dodijelilo 230 tisuća
korisnika. Podaci dolaze u formatiranom obliku odvojeni zarezom (engl. comma separated values), a prvi
se dio praktičnog rada bavi migracijom ovakvog seta podataka u OrientDB graf bazu podataka. U radu je
nakon prikazanih teorijskih temelja obrađena OrientDB graf baza podataka u kojoj će se nalaziti
MovieLens setovi i nad kojom se izvršavaju algoritmi za strojno učenje. Cilj praktičnog rada je da sustav
na osnovi postojećeg seta podataka predloži korisniku nove filmove koje bi mogao gledati.
Teoretski dio rada bavi se pojmovima kolektivne inteligencije, osnova strojnog učenja, algoritmima za
pronalazak sličnosti i pogledom na teoriju grafova s matematičkom podlogom. Rad je podijeljen u
poglavlja gdje poglavlja objašnjavaju:
Poglavlje 2. Kolektivna inteligencija bavi se pojmom kolektivne inteligencije, Netflix natjecanjem te
objašnjava MovieLens bazu podataka.
Poglavlje 3. Pronalazak sličnih korisnika uvodi pojam mjere sličnosti i mjere udaljenosti, euklidsku
udaljenost, Pearsonov korelacijski koeficijent, Jaccardov indeks te daje završni zaključak i usporedbu
kada koristiti koju mjeru.
Poglavlje 4. Teorija grafova bavi se osnovnim konceptima teorije grafova, objašnjava 7 mostova
Königsberga, prikazuje primjere ciklusa, šetnji, puteva, objašnjava pojam stupnja vrha, bipartitnog grafa
te leme o rukovanju.
Poglavlje 5. Analiza socijalnih mreža teorijom grafova otkriva kako koristiti teoriju grafova prilikom
analize socijalnih mreža, što su međujstvo i eigenvektor te kako radi Googleov poznati PageRank
algoritam koji je ključan kod pretraživanja stranica.
Poglavlje 6. OrientDB objašnjava osnovne koncepte OrientDB sustava, usporedbu NoSQL i relacijskih
baza podataka, navodi probleme relacijskih sustava te prikazuje osnove OrientStudia.
Poglavlje 7. MovieLens baza unutar OrientDB sustava otkriva kako se programski jezik Java može
povezati s OrientDB-om, objašnjava dijelove projekta OrientLens koji omogućuje prijenos MovieLens
2
baze u OrientDB. Poglavlje također objašnjava i sam algoritam za preporuku novih filmova, arhitekturu
sustava te prikazuje konkretnu implementaciju.
Poglavlje 9. Zaključak izvodi osnovne zaključke i subjektivno mišljenje autora o cijelom procesu
istraživanja i korištenja OrientDB okruženja.
3
2. Kolektivna inteligencija
Kolektivna inteligencija ili skupna inteligencija (engl. Collective Intelligence) definira se kao sposobnost
ili mogućnost grupe da riješi probleme bolje nego njeni pojedini članovi [2]. Direktor MIT-ovog odjela za
kolektivnu inteligenciju, Thomas W. Malone postavlja pitanje: „Kako treba povezati ljude i računala, a da
grupno imaju inteligentnije postupke od pojedinih ljudi ili računala?“ [3] Sam pojam osmislio je francuski
filozof Pierre Levy 1994. godine kako bi predvidio utjecaj internetskih tehnologija na kulturu i
konzumaciju znanja. Levy je najavljivao da će se zbog brzog širenja velikog broja informacija, mreža
mobilizirati i koordinirati inteligenciju, znanje, vještine i maštu čovječanstva. Kao dio njegove utopijske
vizije kolaboracijskog znanja, predvidio je prelazak s „mislim, dakle jesam“ na „mislimo, dakle jesmo.“
[4] Filimon Stremtan u svom radu govori o kolektivnoj inteligenciji kao obliku inteligencije koji proizlazi
iz kolaboracije i natjecanja mnogih pojedinaca te spominje kako se ona nalazi u raznim oblicima stvaranja
svijesti donošenja odluka u bakterijama, životinjama, ljudima i računalima [5]. Kao dio kolektivne
inteligencije pojavljuju se sustavi za predlaganje i donošenje odluka koji se aktivno razvijaju još od ranih
90ih godina [6] te tvrtke kao što su Amazon, Google i Netflix ovise o njemu [7].
Netflix kao pružatelj „video na zahtjev“ usluga je 2006. godine objavio veliki set podataka o ocjenama
filmova iz svog sustava te organizirao natjecanje u kojemu će tim koji uspije poboljšati njihov sustav za
predlaganje filmova za 10%, dobiti nagradu od milijun dolara [8]. Njihov podatkovni set sadrži 100
milijuna vremenski označenih ocjena u rasponu od kraja 1999. godine do kraja 2005. godine. U
podatkovnom setu nalazi se oko 480 189 anonimnih korisnika i 17 770 filmova [9]. Zanimljivo je to što
prvi i drugi tim imaju potpuno jednake rezultate, a vrijeme njihove predaje rješenja razlikuje se u samo
dvadesetak minuta [10].
2.1. MovieLens
MovieLens je stranica na kojoj je moguće davati ocjene filmovima te tražiti sustav preporuku za sljedeći
film. Sustav je koncipiran upravo na kolektivnoj inteligenciji te je čitava baza javno dostupna [11].
Trenutno najnovija (01/2016) i najveća MovieLens baza sadrži oko 22 milijuna ocjena, 33 tisuće filmova
i 240 tisuća korisnika [12].
4
3. Pronalazak sličnih korisnika
Potrebno je pronaći u kojoj mjeri su dva korisnika sustava slična. Ta mjera se zove mjera sličnosti (engl.
similarity score) i postoje različite implementacije. Potrebno je naglasiti kako se mjera sličnosti dobije
često kao recipročna vrijednost mjere udaljenosti (engl. distance score). Primjeri mjera udaljenosti su
Euklidska udaljenost, Pearsonov korelacijski koeficijent, Manhattan udaljenost itd. Za objašnjenja mjera
udaljenosti, bit će korišten sljedeći skup podataka:
podaci = {
'Petra': {
'zvjezdani ratovi': 3,
'gospodar prstenova': 3,
'titanik': 5,
'matrix': 3,
'planet majmuna': 1,
'odbjegla nevjesta': 5,
'prljavi ples': 5
},
'Davor': {
'titanic': 2,
'zvjezdani ratovi': 5,
'batman': 5,
'matrix': 5,
'prljavi ples': 2,
'odbjegla nevjesta': 2,
'gospodar prstenova': 5,
'planet majmuna': 4
},
'Ivana': {
'planet majmuna': 5,
'zvjezdani ratovi': 5,
'batman': 4,
'matrix': 5,
'prljavi ples': 2,
'titanic': 2,
'odbjegla nevjesta': 1,
'gospodar prstenova': 5,
}
}
Isječak 1 - testni podaci u programskom jeziku Python
Iz skupa je vidljivo da je par (Davor, Ivana) puno sličniji od bilo koje druge kombinacije, što će algoritmi
u nastavku i dokazati.
5
3.1. Euklidska udaljenost
Jedan od najjednostavnijih algoritama za računanje mjere udaljenosti je euklidska udaljenost koja računa
udaljenost između dvije točke u koordinatnom sustavu. Ako su x i y točke u koordinatnom sustavu,
euklidska udaljenost definira se kao [13]:
𝑑(𝑥, 𝑦) = √∑(𝑥𝑖 − 𝑦𝑖)2
𝑛
𝑖=1
(1)
Obzirom da ovakva formula može dati poprilično veliki raspon rezultata, u radu „Euklidska
udaljenost“ Paul Barrett pokazuje mogućnost normalizacije formule [14]:
𝑑(𝑥, 𝑦) = √∑(𝑥𝑖 − 𝑦𝑖)2
𝑛
𝑛
𝑖=1
(2)
Implementacija euklidske udaljenosti prikazana je u programskom jeziku Python:
def euklid_slicnost(podaci, osoba1, osoba2):
# uzmi u obzir jedino zajedničke filmove
zajednicki_filmovi = {}
for film in podaci[osoba1]:
if film in podaci[osoba2]:
zajednicki_filmovi[film] = 1
# ako nema zajedničkih filmova, zaključi da nisu slični
if len(zajednicki_filmovi) == 0: return 0
zbroj_kvadrata = sum([pow(podaci[osoba1][film] –
podaci[osoba2][film], 2)
for film in podaci[osoba1] if film in podaci[osoba2]])
return 1/(1+zbroj_kvadrata)
print(euklid_slicnost(podaci, 'Davor', 'Ivana')) # 0.5
print(euklid_slicnost(podaci, 'Davor', 'Petra')) # 0.025
print(euklid_slicnost(podaci, 'Ivana', 'Petra')) # 0.294
Isječak 2 - implementacija euklidske udaljenosti u programskom jeziku Python
Funkcija euklid_slicnost prima listu filmova i imena dvije osobe kao parametre te uzima u obzir samo
zajedničke filmove. U slučaju da ne postoje zajednički filmovi, algoritam zaključuje da dvije osobe nisu
6
slične (vraća pozivatelju 0 kao rezultat). Funkcija potom računa euklidsku udaljenost i vraća recipročnu
vrijednost tako da je rezultat uvijek u intervalu [0, 1]. Ako su dvije osobe dale identične ocjene za
zajedničke filmove, rezultat je 1.
3.2. Pearsonov korelacijski koeficijent
Pearsonov korelacijski koeficijent (engl. Pearsons correlation score) je sofisticiraniji način za
označavanje sličnosti. Korelacijski koeficijent govori koliko dobro dva skupa podataka prianjaju ravnoj
liniji. U knjizi „Programiranje kolektivne inteligencije“ (engl. Programming collective intelligence) [1],
Toby Segaran prikazuje četiri korisnika grafovima:
Slika 2 - dva filmska kritičara s niskim stupnjem korelacije
(slika preuzeta iz knjige T. Segaran „Programming Collective Intelligence“, 12. stranica) [1]
Očito je da je par „Jack Matthews“ i „Lisa Rose“ sličniji od para „Mick LaSalle“ i „Gene Seymour“. U
radu „Alternativa Pearsonovom i Spearmanovom korelacijskom koeficijentu“ (engl. Alternatives To
Pearson’s and Spearman’s Correlation Coefficients), Florentin Smarandache definira Pearsonov
korelacijski koeficijent r kao [15]:
𝑟 = ∑ 𝑋𝑌 −
∑ 𝑋 ∑ 𝑌𝑁
√(∑ 𝑋2 −(∑ 𝑋)2
𝑁)(∑𝑌2 −
(∑ 𝑌)2
𝑁)
(3)
Slika 1 - dva filmska kritičara s visokim stupnjem korelacije (slika preuzeta iz knjige T. Segaran „Programming Collective
Intelligence“, 12. stranica) [1]
7
Prednost Pearsonovog korelacijskog koeficijenta nad euklidskom udaljenošću je da pronalazi tzv.
inflaciju ocjena (engl. grade inflation) [1] tj. uzima u obzir i informaciju da osoba ima preferenciju davati
niske ili visoke ocjene. Koeficijent se nalazi u rasponu između [-1, 1]. Brojnik u formuli je kovarijanca
(engl. covariance) - vrijednost koja pokazuje linearnu povezanost tj. ako se promijeni varijabla X, koliko
će se promijeniti varijabla Y. Problem s kovarijancom je nestandardiziranost tj. vrijednost može biti u
rasponu [-∞,+∞]. Nazivnik u formuli standardizira kovarijancu te daje rješenje u rasponu između [-1, 1].
Toby Segaran je u svojoj knjizi Programiranje kolektivne inteligencije [1] napisao implementaciju
sličnosti pomoću Pearsonovog korelacijskog koeficijenta u programskom jeziku Python:
def pearson_slicnost(podaci, osoba1, osoba2):
# uzmi u obzir jedino zajedničke filmove
zajednicki_filmovi = {}
for film in podaci[osoba1]:
if film in podaci[osoba2]:
zajednicki_filmovi[film] = 1
# broj zajedničkih elemenata
n = len(zajednicki_filmovi)
# ako nema zajedničkih filmova, zaključi da nisu slični
if n==0: return 0
# zbroji sve ocjene
suma1 = sum([podaci[osoba1][film] for film in zajednicki_filmovi])
suma2 = sum([podaci[osoba2][film] for film in zajednicki_filmovi])
# zbroj kvadrata
suma1kvadrata = sum([pow(podaci[osoba1][film],2)
for film in zajednicki_filmovi])
suma2kvadrata = sum([pow(podaci[osoba2][film],2)
for film in zajednicki_filmovi])
# suma produkata
sumaP = sum([podaci[osoba1][film] * podaci[osoba2][film]
for film in zajednicki_filmovi])
# Pearsonov korelacijski koeficijent
num = sumaP - ((suma1 * suma2) / n)
den = sqrt((suma1kvadrata - pow(suma1, 2) / n) *
(suma2kvadrata - pow(suma2, 2) / n))
# ako je nazivnik 0, zaključi da nisu slični
if den == 0: return 0
koeficijent = num / den
return koeficijent
8
print(pearson_slicnost(podaci, 'Davor', 'Ivana')) # 0.9258
print(pearson_slicnost(podaci, 'Davor', 'Petra')) # -0.6919
print(pearson_slicnost(podaci, 'Ivana', 'Petra')) # -0.8447
Isječak 3 - implementacija Pearsonovog korelacijskog koeficijenta u programskom jeziku Python [1]
3.3. Jaccard indeks
Jaccard indeks (ili Jaccard indeks sličnosti) najčešće se koristi u teoriji skupova i kada su podaci
kategorički. Riječ dobar definira se kada je kritičar dao ocjenu veću od 3 (dakle, 4 i 5), a riječ loš kada je
film manji od 4 (dakle, 1, 2, 3) te se podijele svi filmovi u te dvije kategorije, po korisniku. Autori rada
„Korištenje Jaccard indeksa za pronalazak sličnosti ključnih riječi“ (engl. Using of Jaccard Coefficient for
Keywords Similarity) [16] definiraju Jaccard indeks sličnosti kao rezultat dijeljenja broja zajedničkih
elemenata s brojem svih elemenata:
J(A, B) =|𝐴⋂ 𝐵|
|𝐴⋃ 𝐵|
(4)
Slika 3 - Jaccard indeks - presjek zajedničkih elemenata (slika izrađena unutar WolframAlpha sustava)
Jaccard indeks implementiran u programskom jeziku Python:
def jaccard_slicnost(podaci, osoba1, osoba2):
# pronalazak filmova koji su ocijenjeni ocjenom 4 ili 5
dobri1 = set()
for film in podaci[osoba1]:
filmovi = podaci[osoba1]
if filmovi.get(film) > 3:
dobri1.add(film)
# pronalazak filmova koji su ocijenjeni ocjenom 4 ili 5
dobri2 = set()
for film in podaci[osoba2]:
filmovi = podaci[osoba2]
9
if filmovi.get(film) > 3:
dobri2.add(film)
# zajednički filmovi
zajednicki = len(set.intersection(*[dobri1, dobri2]))
# unija svih "dobrih" filmova
unija = len(set.union(*[dobri1, dobri2]))
# izračun koeficijenta
return zajednicki / unija
print(jaccard_slicnost(podaci, 'Davor', 'Ivana')) # 1.0
print(jaccard_slicnost(podaci, 'Davor', 'Petra')) # 0.0
print(jaccard_slicnost(podaci, 'Ivana', 'Petra')) # 0.0
Isječak 4 - implementacija Jaccard indeksa u programskom jeziku Python
3.4.Zaključak mjera sličnosti
Prema rezultatima i implementacijama algoritama može se zaključiti da je euklidska udaljenost
najjednostavniji algoritam za implementaciju. Problem s euklidskom udaljenošću je što ne uzima u obzir
ima li neka osoba preferenciju davati niske ili visoke ocjene. Iz rezultata je također vidljivo i da Jaccard
koeficijent sličnosti nije „osjetljiv“ te da bi se trebao koristiti samo s kategoričkim podacima. Jaccard
koeficijent sličnosti mogao bi se iskoristiti kada bi se filmovima dodijelile oznake (horor, komedija, i sl.)
te grupirati (engl. clustering) korisnike po tipu filma koje preferiraju. Ta informacija mogla bi dati točniju
informaciju kod prijedloga sljedećeg filma korisniku. Ako korisnik gleda isključivo horore i komedije, a
najsličnija osoba preferira komedije i akcijske filmove, trivijalna je odluka da sljedeća preporuka bude
komedija.
U ovom radu, ako nije navedeno drugačije, korišten je Pearsonov korelacijski koeficijent.
10
4. Teorija grafova
Pisana povijest teorije grafova počinje objavom „7 mostova Königsberga“ švicarskog matematičara
Leonarda Eulera 1736. godine [17] [18]. Istočni pruski grad Königsberg (današnji Kaliningrad) zauzimao
je obje strane rijeke Pregel i otok Kneiphof. Grad je imao 7 mostova, a postavljen je problem može li se
obići cijeli grad, a da se svaki most prijeđe jednom i samo jednom [19]. Euler je uspio dokazati da je
problem nemoguće riješiti i dokaze je iznio u svom radu „Rješenje jednog problema u svezi s
geometrijom položaja“ (lat. Solutio Problematis ad Geometriam Situs Pertinentis) [20], prijevod preuzet
iz skripte „Uvod u teoriju grafova“ (Anamari Nakić, Mario-Osvin Pavčević) [21].
4.1. Definicija grafa
Slika 4 prikazuje graf Königsbergovih mostova. Vrhovi prikazuju tlo (područja, otoke), a bridovi
prikazuju mostove. Graf G je uređeni par 𝐺 = (𝑉, 𝐸) u kojemu je V (engl. vertex) skup vrhova i E (engl.
edge) skup bridova [22]. Skupovi V i E su disjunktni tj. nemaju zajedničkih elemenata.
Slika 4 - Königsbergovi mostovi predstavljeni grafom
Slika 5 - Usmjereni graf s težinama
Ako je graf usmjeren i ima težine, najčešće se to naznačuje na bridovima kao na Slici 5. Na istoj se slici
odmah može uočiti problem najkraćeg puta. Jedan od primjera je kako najlakše doći iz točke B u točku D.
Ako je graf 𝐺 = (𝑉, 𝐸) i 𝑣 ∈ 𝑉 i 𝑒 = {𝑣}, tada brid izlazi i ulazi u isti vrh (engl. self-loop) [23]. Ako graf
ima samo jedan vrh, naziva se trivijalnim [24]. Ako drugačije nije navedeno, primjeri u ovom radu
odnose se na ne-trivijalne, jednostavne grafove. Bitan je i stupanj vrha koji se definira kao broj
incidentnih rubova i gdje se petlje broje dva puta. Stupanj vrha B na Slici 6 je 4.
11
Slika 6 - vrh B sa stupnjem vrha 4
Slika 7 - primjer ciklusa
4.2. Šetnje, ciklusi i putevi
Šetnja (engl. walk) po grafu definira se kao lista vrhova i rubova 𝑊 = 𝑣0𝑒1𝑣1𝑒2, … , 𝑣𝑘−1𝑒𝑘𝑣𝑘 koji nisu
nužno jedinstveni [25]. Bitno je primijetiti da je jedna šetnja nužno i podgraf (engl. subgraph), tako da se
šetnja može prikazati i kao skup rubova i vrhova kao što ih predstavlja Paul Van Dooren u radu „Teorija
grafova i primjene“ (engl. Graph Theory and Applications) [26]:
𝑉 = { 𝑣𝑜, 𝑣1 , … , 𝑣𝑘 } 𝐸 = { (𝑣𝑜, 𝑣1), … , (𝑣𝑘−1, 𝑣𝑘) } (5)
gdje rub j spaja vrhove j-1 i j.
Rep (engl. trail) je šetnja u kojoj su svi rubovi različiti (jedinstveni), a put (engl. path) je šetnja u kojoj svi
vrhovi različiti (jedinstveni) [27], a time i rubovi. Ciklus je put od jednog vrha, prolazak kroz druge
vrhove i povratak u početni vrh tj. svi vrhovi u ciklusu su različiti osim prvog i zadnjeg [28]. Slika 7
prikazuje primjer ciklusa.
12
4.3. Bipartitni grafovi
Prema [29], bipartitni graf je neusmjereni graf 𝐺 = (𝑉, 𝐸) kojemu se vrhovi V mogu
particionirati/podijeliti u dva podskupa L i R tako da je svaki rub spojen s jednim vrhom iz skupa L i s
jednim vrhom iz skupa R. Slika 8 prikazuje bipartitni graf.
Slika 8 - bipartitni graf
Slika 9 - potpuni bipartitni graf
Prema [30], potpuni bipartitni graf je onaj graf koji ne sadrži ciklus neparne duljine, a tvrdnja se može
dokazati jednostavnim „bojanjem grafa“ (engl. graph coloring). Victor Adamchik u svom radu Teorija
Grafova [31] postavlja dva zanimljiva problema koji se mogu riješiti bipartitnim grafovima:
1. Vlasnik tvrtke ima M djelatnika i N poslova. Svaki djelatnik je kvalificiran za neke poslove.
Kako posložiti poslovanje?
2. X muškaraca i Y žena želi se vjenčati te svatko od njih odgovori tko je sve potencijalni kandidat.
Kako složiti rješenje, a da se svatko vjenča s barem jednom osobom suprotnog spola?
Broj rubova u potpunom bipartitnom grafu je 𝑚 ∗ 𝑛 te ako je graf regularan onda je 𝑚 = 𝑛. Poznata je i
lema o rukovanju (engl. handshaking lemma) koja kaže da je u svakom grafu zbroj stupnjeva vrhova
jednak dvostrukom broju rubova. Andrea Aglić-Aljinović u svom radu „ekstremalna kombinatorika“
definira lemu o rukovanju: „U društvu od konačno mnogo ljudi, uz pretpostavku da se nitko ne rukuje s
istom osobom više od jednom i da se nitko ne rukuje sam sa sobom, broj ljudi koji se rukovao neparan
broj puta je paran.“ [32] Lema o rukovanju je posljedica upravo formule (6):
∑ deg (𝑣)
𝑣∈𝑉
= 2|𝐸| (6)
13
U svom radu „Kolaboracijsko filtriranje pomoću težinskih bipartitnih graf projekcija“ (engl.
Collaborative Filtering using Weighted BiPartite Graph Projection) [33], Sumedh Sawant upravo je
pomoću bipartitnih grafova napravio sustav za predlaganje za Yelp podatkovno natjecanje (engl. Yepl
dataset challenge).
14
5. Analiza socijalnih mreža teorijom grafova
Analiza socijalnih mreža (engl. social network analysis), dalje u tekstu SNA, daje moćne mogućnosti za
proučavanje veza između ljudi prikazane kao binarne ili težinske matrice susjedstva [34]. Ovakva analiza
bila bi potrebna kada bi u sustavu za predlaganje filmova bilo omogućeno komentiranje filmova i
međusobna interakcija među korisnicima te ovaj dio rada predstavlja teoretsku predispoziciju za daljnje
razvijanje sustava. Ocjena filma može dati vrijednost koliko se korisniku svidio film, ali ne i zašto se
korisniku film sviđa ili ne. Analizom komentara i interakcija s drugim korisnicima, moguće je doći do
subjektivnih elemenata korisnika o filmu koji se ne vide iz same ocjene.
U svom radu „Analiza socijalnih mreža pomoću sna“, Carter T. Butts govori da su: „tehnike bazirane na
eigenrješenjima (eigenvektor i Bonacich mjera centralnosti, multidimenzionalno skaliranje),
kombinatorijska optimizacija (permutacijska pretraga u ekvivalentnoj analizi, strukturna
udaljenost/izračun kovarijance), računanje najmanjeg puta (međujstvo (engl. betweenness), mrežni
promjer) i Monte Carlo integracija (QAP i CUG testovi) centralne prakse SNA analize te veliki dio
trenutnih istraživanja ovog područja ne bi mogao biti izveden bez pristupa jeftinim računalnim alatima.“
[35]
5.1. Međujstvo
Međujstvo (engl. betweenness) je globalna mjera centralnosti, zasnovana na enumercijama računanja
najmanjeg puta [36]. Međujstvo pokazuje koliko je puta najkraći put prolazio kroz neki vrh. Ako je neki
vrh „most“ u grafu, onda taj vrh ima relativno veliko međujstvo. Prema [37], međujstvo se matematički
može prikazati kao:
𝐶𝐵(𝑣) = ∑𝜎𝑠𝑡(𝑣)
𝜎𝑠𝑡𝑠≠𝑡≠𝑣
(7)
Slika 10 prikazuje vrh A s najvećim međujstvom. Ključno je vidjeti da kada ne bi bilo vrha A koji služi
kao most u grafu, veze među grupama (podgrafovima) bi se izgubile.
15
Slika 10 - vrh A s najvećim međujstvom
5.2. Eigenvektor
Eigenvektor (engl. eigenvector) mjera je centralnosti koja prikazuje ideju da nije važno koliko ljudi osoba
poznaje nego koje ljude poznaje. Direktor velike tvrtke može poznavati 300 ljudi u svojoj tvrtki, ali ono u
čemu je njegova snaga u mreži je koliko poznaje drugih direktora. Jedan Facebook profil može imati
5000 „lažnih profila“ kao prijatelje, dok drugi profil može imati samo jednog prijatelja na Facebooku,
Marka Zuckerberga. Jednostavno je zaključiti da je drugi profil „bitniji“ u mreži. Slika 11 prikazuje vrh A
s najvećim eigenvektorom. Prema [38], eigenvektor se može definirati kao:
𝐶𝑖𝑒 =
1
𝜆∑ 𝑦𝑖,𝑗𝐶𝑗
𝑒
𝑗:𝑗≠𝑖
(8)
[39] piše o PageRank algoritmu, Googleova varijanta eigenvektor centralnosti. Prema tom radu, Google
broji koliko se kvalitetnih stranica veže na ciljanu stranicu te joj time daje adekvatnu važnost prilikom
pretraživanja.
16
Slika 11 - vrh A ima najveći eigenvektor
5.3. Zaključak SNA analize
SNA kao interdisciplinarno područje može pronaći najutjecajnije elemente mreže. Sustav za predlaganje
filmova može imati socijalnu komponentu gdje ljudi, osim ocjenjivanja, mogu i komentirati filmove te ih
predlagati. Ako sustav želi doprijeti do velikog broja ljudi, ključno je pronaći najbitnije elemente mreže i
tražiti preporuku.
U knjizi „Analiza socijalnih mreža u telekomunikacijama“ (engl. Social Network Analysis in
Telecommunications) [40] autor navodi i da se SNA analiza može iskoristiti ne samo za individualnu
analizu, nego analizu cjelokupnog sustava i odnosa među elementima.
Na mrežu se može gledati kao jednu cjelinu ili kao tzv. egocentričnu mrežu u kojoj se analiziraju odnosi u
odnosu na jedan element mreže. Središte SNA analitike je teorija grafova koja daje razinu apstrakcije i
koja može matematički poduprijeti marketinške ili poslovne odluke.
17
6. OrientDB
Prema [41], OrientDB je više-modelni (engl. multi-model) sustav za upravljanje bazom podataka s graf i
dokumentnim modulom/pogonom (engl. engine). OrientDB može biti pokrenut u distribuiranom načinu
rada, podržava SQL, ACID transakcije, indeksiranje teksta (engl. full-text indexing), reaktivne upite (engl.
reactive queries) i ima mali memorijski otisak (engl. memory footprint).
6.1. NoSQL
Kada su relacijske baze postale dovoljno velike te kada su ih tvrtke pokušale skalirati, prema [42], kupile
su noviji i snažniji hardver, pokušale pojednostaviti shemu baze (engl. scheme), denormalizirati podatke,
olakšati referencijski integritet (engl. referential integrity), dodati priručne memorije (engl. cache),
odvojile replikacije koje samo čitaju podatke od onih koje samo pišu podatke, particionirale podatke
(engl. partitioning) i sl., ali je problem i dalje postojao.
Michael Stonebraker [43] navodi da su praktički svi aplikativni programi koji ovise o brzini rada (engl.
performance sensitive) napravljeni pomoću spremljenih procedura (engl. stored procedures) koji
obrađuju podatke direktno na bazi podataka izbjegavajući tako „prazni hod“ u komunikaciji između
aplikativnog programa i baze podataka. Michael Stonebraker [43] navodi i alternativu da je moguće
pokrenuti sustav za upravljanje bazom podataka u istom adresnom prostoru gdje je i aplikativni program
te se time odreći sigurnosti i sustava upravljanja različitim korisničkim ulogama.
U radu „Tipovi NoSQL baza podataka i njihova usporedba s relacijskim bazama podataka“ (engl. Type of
NOSQL Databases and its Comparison with Relational Databases) [44] navedeno je 5 tipova NoSQL
baza podataka: ključ-vrijednost baze (engl. key-value), stupac baze (engl. column-oriented), dokument
baze (engl. document store), graf baze (engl. graph databases) i objektno orijentirane baze (engl. object-
oriented databases). Tablica 1 prikazuje tipove baza podataka. Neke je baze teže kategorizirati jer su od
samog početka ili novijim inačicama postale hibridi između tipova. Jedan od primjera je Apache
Cassandra koja je hibrid [45] između ključ-vrijednost i stupac baze ili OrientDB koja je multi-modelna
baza tj. može se ponašati kao ključ-vrijednost, kao dokument i kao graf baza. Svaki od navedenih sustava
ima svoje prednosti, nedostatke i mjesta gdje briljiraju.
18
Tablica 1 - primjer NoSQL baza podataka
Tip Primjer
Ključ-vrijednost baze Redis [46], Riak [47], Voldemort [48]
Stupac baze Cassandra [49], HBase [50]
Dokument baze MongoDB [51], CouchDB [52], RavenDB [53]
Graf baze Neo4j [54], OrientDB [55], InfoGrid [56]
6.2. Problemi s relacijskim modelom
Postoji nekoliko ključnih problema u relacijskom modelu. Prema [57], jedan od najvećih problema
relacijskog modela je spajanje dvije ili više tablica (engl. join). Ako se u upitu spajaju 4 tablice po milijun
redova, jednostavno je izračunati minimalan broj pristupa tablici. Jedno od rješenja je korištenje indeksa
(engl. index), ali to smanjuje problem samo logaritamski [58] i zauzima više prostora te usporava
dodavanje i brisanje elemenata [59]. Upravo otežano spajanje nekoliko velikih tablica (koje se mogu
nalaziti na različitim dijelovima svijeta) povlači za sobom sve druge probleme.
6.3. OrientDB graf baza i rješavanje problema spajanja nekoliko tablica
Prema [60], OrientDB interno sprema podatke kao dokumente koji sadrže ključ-vrijednosti gdje se do
vrijednosti dolazi preko ključa. Izvor navodi i da dokumenti ne moraju imati shemu kao u relacijskim
bazama podataka.
OrientDB uvodi koncept poveznice (engl. link) koji predstavlja vezu između dokumenata gdje je moguće
birati između direktnog ugrađivanja (engl. embedding) dokumenta unutar dokumenta ili povezivanja.
Razlika između OrientDB-a i drugih dokument baza podataka je upravo u načinu rješavanja načina
povezanosti gdje se u sustavima poput MongoDB-a ili CouchDB-a, programeri sami moraju brinuti oko
veza između dokumenata [60]. Tablica 2 prikazuje usporedbu relacijskog modela, dokument modela i
dokument modela u OrientDB bazi podataka, preuzeta iz [61].
Tablica 2 - Usporedba relacijskog modela, dokument modela i dokument modela u OrientDB bazi podataka
Relacijski model Dokument model OrientDB dokument model
Tablica Kolekcija Skup (engl. cluster), klasa
Red Dokument Dokument
Stupac Ključ-vrijednost par Polje dokumenta (engl. field)
Veza - Poveznica
19
Na dokument model se oslanja graf model. Prema [62], graf model se sastoji od rubova i vrhova. Vrh se
sastoji od jedinstvenog broja, skupa ključ-vrijednost parova, skupa ulaznih i skupa izlaznih bridova. Rub
se sastoji od jedinstvenog broja, ulaznog vrha, izlaznog vrha, naziva (engl. label) te skupa ključ-
vrijednosti koje opisuju vezu između dva vrha.
Izvor [62] opisuje i skup (engl. cluster) kao kolekciju elemenata (engl. records). Ako će se u programu
nalaziti samo korisnici iz Hrvatske i Kine, idealno bi bilo razdvojiti te korisnike u dva skupa iz nekoliko
razloga:
1. moguće je fizički postaviti poslužitelja bliže zemlji u kojoj se korisnici nalaze
2. ako jedan poslužitelj nije dostupan, korisnici na drugom poslužitelju raditi će neometano
Svaki zapis u OrientDB sustavu dobije svoj jednoznačni broj kojim se može dohvatiti. Taj broj (engl.
record id, identifier) sastoji se od broja skupa i broja fizičkog zapisa [63] čime je garantirano pristupanje
određenom zapisu približnom brzinom O(1). Slika 12 prikazuje kako se graf model oslanja na dokument
model, ali i da aplikativni softver može izravno komunicirati s dokument modelom ili čak i objektnim
modelom.
Slika 12 - graf model se oslanja na dokument model
Tablica 3 prikazuje usporedbu relacijskog modela, graf modela te graf modela u OrientDB bazi. Tablica
je preuzeta iz [62]. U tablici se spominju klase V i E koje su nadklasa vrhu (engl. Vertex) i rubu (engl.
Edge).
20
Tablica 3 - usporedba relacijskog modela, graf modela i graf modela u OrientDB bazi
Relacijski model Graf model OrientDB graf model
Tablica Vrh i rub klasa Klasa koja nasljeđuje klasu „V“
i „E“
Red Vrh Vrh
Stupac Vrh i rub polje Vrh i rub polje
Veza Rub Rub
6.4. Pokretanje OrientDB baze
Za pokretanje OrientDB baze, potrebno je koristiti Java virtualni stroj (engl. Java Virtual Machine) te je
preporučljivo koristiti verziju 8 [64]. OrientDB sustav moguće je preuzeti sa službene stranice [55] i
pokrenuti u dva načina rada: normalni i distribuirani. Obadva načina pokretanja se nalaze unutar bin
direktorija. Na UNIXoidnim operacijskim sustavima normalni se način rada pokreće na sljedeći način:
$ cd bin
$ ./server.sh
Isječak 5 - pokretanje OrientDB baze u normalnom načinu rada
Nakon pokretanja sustava, terminal bi trebao pokazati poruke uspješne inicijalizacije (Slika 13). Poruke
unutar terminala pokazuju i da su se moduli (engl. plugins) poput OrientStudia pokrenuli uspješno.
OrientStudio je za OrientDB ono što je PHPMyAdmin za MySQL sustav tj. grafičko sučelje kojim je
moguće upravljati samim sustavom.
21
Slika 13 - prikaz uspješno inicijaliziranog OrientDB sustava u normalnom načinu rada
Iz poruka koje OrientDB prikazuje prilikom pokretanja, vidljivo je da OrientDB čita konfiguracijske
parametre iz datoteke config/orientdb-server-config.xml. Vidljivo je i da se baze nalaze u databases
direktoriju te da poslužitelj „sluša“ binarne veze na priključku (engl. port) 2424 te HTTP veze na
priključku 2480. Nakon inicijalizacije baze, sustav otpakira dodatke (engl. extract plugins) poput agents i
studio.
6.5.Korištenje OrientStudia
Nakon što je sustav pokrenut, OrientStudio „sluša“ na priključku 2480. OrientStudio se otvara preko
preglednika (engl. browser) na stranici: http://localhost:2480. Slika 14 prikazuje tzv. stranicu
dobrodošlice (engl. welcome screen) na kojoj se korisnici prijavljuju sa svojim korisničkim imenom i
lozinkom. Lozinka se postavlja u trenutku prvog pokretanja OrientDB sustava i čuva u konfiguracijskoj
datoteci [65].
22
Slika 14 - OrientStudio prijava
Moguće je i preuzimanje već postojećih baza. Nakon uspješne prijave u bazu, sustav će prikazati različite
module kojima se može upravljati bazom (Slika 15).
Slika 15 - različiti moduli za upravljanje OrientDB bazom podataka
Modul za pregled (engl. browse) najčešće služi za slanje upita prema sustavu. Shema (engl. schema)
modul služi kao grafičko sučelje za upravljanje shemom baze (klasama, skupovima). Nedostatak modula
Shema je što nije moguć hijerarhijski prikaz klasa unutar sustava. Sigurnosni modul (engl. security) služi
za dodjeljivanje prava pojedinim korisnicima u bazi. Trenutne uloge (engl. roles) su administrator, pisač i
čitač (engl. admin, writer, reader).
Graf (engl. Graph) modul služi za prikaz podataka u obliku grafa. Slika 16 prikazuje rezultat
jednostavnog upita koji uzima 5 vrhova (vrhovi su dokumenti ili klase V ili naslijeđeni iz klase V (engl.
Vertex)). Veze „followed_by“ (praćen od) su direktni pokazivači od jednog vrha do drugog ili dokumenti
koji su klase E ili naslijeđeni iz klase E.
23
Slika 16 - primjer jednostavnog SQL upita
Takvi direktni pokazivači i korištenje identifikatora (engl. ID) koji direktno pokazuju u memoriji gdje se
vrh nalazi, čini dohvaćanje takvih dokumenata operacijom približnom O(1). Ne povećavanje
kompleksnosti pretraživanja prilikom dodavanja novih količina podataka jedan je od najsnažnijih
argumenata za korištenje OrientDB baze podataka. Izvor [66] u svom sustavu za razmjenu poruka (engl.
chat) prikazuje i da je samo straničenje (engl. pagination) operacija O(1) čak i na milijun poruka te
navodi upit:
select from ItalianRestaurant order by @rid desc skip 50 limit 50
Isječak 6 - jednostavno straničenje
Modul Funkcije (engl. Functions) omogućuje unos funkcija u sustav OrientDB. Sličan koncept u
relacijskim bazama podataka su spremljene procedure (engl. stored procedures). Funkcije se mogu
pozvati iz SQL-a, HTTP-a i Jave [66].
6.6. SQL
OrientDB podržava i SQL dijalekt s nekim manjim razlikama [67]. Isječak 7 prikazuje osnovne SQL
SELECT naredbe:
SELECT * FROM V
SELECT FROM V // može se izbjeći znak * ako se dohvaćaju svi elementi
SELECT DISTINCT(ime) FROM Korisnik
Isječak 7 - osnovne SELECT naredbe
24
I dodavanje vrhova je jednostavno sa SQL INSERT naredbama:
INSERT INTO V (ime, prezime) VALUES ("Davor", "Lozić")
INSERT INTO V SET ime = "Aleksander", prezime = "Radovan"
Isječak 8 - SQL INSERT naredba
Naredba DELETE briše dokumente (u ovom slučaju vrhove):
DELETE FROM V WHERE ime.toLowerCase() = 'davor'
Isječak 9 - SQL DELETE naredba
6.7. Klase
Prema [68], zapis (engl. record) je najmanji element kojeg baza podataka može spremiti. Izvor također
navodi da postoji 4 tipa zapisa: dokument, zapis u bajtovima (engl. RecordBytes), vrh i rub. OrientDB
podržava koncept klase iz paradigme objektno-orijentiranog programiranja. Dokument kao skup ključ-
vrijednosti, može biti određene klase koja osigurava konzistentnu shemu sličnoj shemi u relacijskim
bazama podataka. Trenutno ne postoji nikakvo pravilo što sve mora jedan vrh sadržavati te time se ne
osigurava niti točnost niti konzistentnost podataka. Klase mogu biti bez sheme (engl. schema-less), sa
shemom (engl. shema-full) ili miješane (engl. mixed) [69]. SQL naredbama je moguće napraviti klasu i
dodati joj svojstva (engl. properties):
CREATE CLASS Osoba
CREATE PROPERTY Osoba.ime STRING
CREATE PROPERTY Osoba.prezime STRING
CREATE PROPERTY Osoba.oib STRING
CREATE PROPERTY Osoba.email STRING
ALTER PROPERTY Osoba.ime MANDATORY TRUE
ALTER PROPERTY Osoba.prezime MANDATORY TRUE
ALTER PROPERTY Osoba.oib MANDATORY TRUE
ALTER PROPERTY Osoba.oib MIN 11
ALTER PROPERTY Osoba.oib MAX 11
Isječak 10 - izrada klase Osoba
Nakon postavljenih pravila, nije moguće unijeti korisnika bez imena, prezimena i OIB-a, a email je
neobavezan. Isječak 11 prikazuje kako ispravno unijeti osobu u sustav. OIB naravno nije valjan jer OIB u
RH koristi standard ISO7064, MOD 11,10 [70], ali je moguća i takva provjera prije unosa.
INSERT INTO Osoba (email, ime, oib, prezime) VALUES
("[email protected]", "Davor", "11111111111", "Lozić")
Isječak 11 - dodavanje nove osobe
25
Pokuša li se dodati Osoba koja nema jedan od obveznih elemenata (OIB, Isječak 12), sustav će javiti
pogrešku prilikom unosa (Slika 17).
INSERT INTO Osoba (email, ime, prezime) VALUES
("[email protected]", "Davor", "Lozić")
Isječak 12 - unos korisnika bez OIB-a, upit koji se neće uspješno izvršiti
Na ovaj se način može definirati integritet podataka u samoj bazi. Shema može imati različita pravila za
različite tipove podataka.
Slika 17 - ispis pogreške prilikom dodavanja korisnika bez OIB-a
26
7. MovieLens baza unutar OrientDB sustava
Java 8 i OrientDB omogućuju jednostavan unos podataka iz CSV datoteke. MovieLens baza podataka
dolazi u tom obliku te ju je potrebno unijeti u OrientDB sustav. Slika 18 prikazuje popis datoteka u kojoj
se nalaze poveznice (engl. links), filmovi (engl. movies), ocjene (engl. ratings) i oznake (engl. tags).
Slika 18 - MovieLens popis datoteka
7.1. Spajanje Jave i OrientDB baze podataka
Prvo je potrebno spojiti Javu i OrientDB bazu podataka. Jednostavan način za spajanje s bazom je
korištenje klase OrientGraphFactory [71]. Izvor navodi i da je moguće koristiti OrientDB na transakcijski
i netransakcijski način. Isječak 13 prikazuje spajanje Jave i OrientDB baze te se veza prema bazi nalazi u
graf varijabli. Config klasa u ovom kontekstu sadrži pristupne podatke.
OrientGraphFactory f =
new OrientGraphFactory(
Config.DB_URL, Config.DB_USERNAME, Config.DB_PASSWORD)
.setupPool(Config.DB_POOL_MIN, Config.DB_POOL_MAX);
OrientGraph graf = f.getTx(); // transakcijski način
Isječak 13 - spajanje Jave i OrientDB baze
Sustav koristi Java 8 lambda izraze prilikom prijenosa podataka. Isječak 14 prikazuje način dodavanja
korisnika iz CSV datoteke u OrientDB. CSV datoteka se prvo otvara, obrađuje te potom dodaje u HashSet
(jedna od implementacija skupa u programskom jeziku Java). Teorija skupova sama po sebi ne dopušta
duplicirane elemente pa tako i implementacija u obliku HashSet klase.
Stream<String> podaci = Files.lines(
Paths.get(Config.MOVIELENS_PATH + "ratings.csv"));
Set<Integer> korisnici = new HashSet<>();
podaci.skip(1).forEach(red -> {
String[] tokeni = red.split(",");
podaci.add(Integer.parseInt(red[0]));
});
Isječak 14 - unos MovieLens korisnika u OrientDB sustav
27
Prije unosa samih podataka, potrebno je napraviti klasu Korisnik koja će predstavljati korisnike sustava.
graf.executeOutsideTx(arg -> {
OrientVertexType klasa = graf.createVertexType("Korisnik");
klasa.createProperty("korisnikId", OType.INTEGER);
klasa.createIndex("Korisnik.korisnikId", OClass.INDEX_TYPE.UNIQUE,
"korisnikId");
return null;
});
Isječak 15 - izrada klase Korisnik
Isječak 15 prikazuje izradu klase Korisnik te joj dodaje korisnikId koji služi kao identifikator korisnika.
podaci.stream().forEach(id -> {
try {
graph.addVertex("class:Korisnik", "korisnikId", id);
if (Worker.randInt(1, 20) == 5) { graf.commit(); }
} catch (Exception e) {
graf.rollback();
}
});
graf.commit();
Isječak 16 - unos korisnika iz CSV-a u OrientDB
Isječak 16 - prikazuje konkretan unos korisnika iz CSV-a u OrientDB sustav. Obzirom da taj broj
korisnika može biti poprilično velik i da se unosi u transakcijskom načinu rada, potrebno je povremeno
pozvati potvrdu za spremanjem podataka (engl. commit) tako da bi se podaci trajno spremili.
Cijeli projekt unosa ostalih CSV datoteka objavljen je kao projekt otvorenog koda te je dostupan ovdje
[72]. Unutar projekta unose se još žanrovi, filmovi, ocjene te oznake.
7.2. Sustav za preporuku novih filmova
Nakon što se podaci nalaze u OrientDB bazi, algoritam za preporuku filmova može se nalaziti na jednom
od slojeva: aplikacijskom sloju ili na bazi kao procedura/funkcija. Izvori [73] [74] [75] [76] bave se o
dobrim i lošim stranama poslovne logike u aplikacijskom i/ili podatkovnom sloju. Konkretno u ovom
sustavu, sustav za predlaganje nalazi se u podatkovnom sloju koji se izvršava direktno na OrientDB bazi,
a koju poziva Rails aplikacija te prosljeđuje joj potrebne parametre.
Slika 19 prikazuje arhitekturu sustava. Korisnički preglednik napravi upit prema poslužitelju na kojem
Rails sustav čeka zahtjeve. Rails prihvati zahtjev, otvori poveznicu prema OrientDB bazi i pozove
funkciju unutar OrientDB sustava. Pozivanje OrientDB funkcija može se odviti na dva načina: ili
binarnim protokolom ili REST API-em. U ovom slučaju Rails komunicira s OrientDB-om pomoću
28
binarnog protokola. Nakon što OrientDB obradi zahtjev i vrati listu filmova Rails sustavu, Rails sustav
vraća HTTP odgovor korisničkom pregledniku.
Slika 19 - arhitektura sustava
Algoritam za prijedlog novih filmova implementiran je pomoću Pearsonovog korelacijskog koeficijenta.
U sljedećem opisu algoritma, osoba A će biti osoba za koju se traži preporuka, a osoba B će biti osoba s
kojom se trenutno uspoređuje osoba A da bi se dohvatili novi filmovi. Algoritam se sastoji od sljedećih
koraka:
1. dohvaćanje korisnika A i njegove ocjene filmova
2. dohvaćanje korisnika B iz liste svih korisnika sustava (B je striktno različita osoba od A)
3. dohvaćanje ocjena korisnika B
4. izračun Pearsonovog korelacijskog koeficijenta između korisnika A i korisnika B
5. usporedba trenutno najboljeg koeficijenta s novim
6. postavljanjem novog koeficijenta ako je bolji od prethodnog
7. preuzimanje liste filmova korisnika B
8. filtriranje samo onih filmova koje je korisnik B ocijenio kao dobrim (>= 4)
9. vraćanje liste filmova kao rezultat
var gdb = orient.getGraph();
return gdb.command('sql', ' \
select @rid, movieId, name from (\
select expand(out("Rate")) \
from User where userId = ?);', [ userId ] );
Isječak 17 - dohvaćanje liste filmova koje je korisnik ocijenio
Isječak 17 prikazuje funkciju unutar OrientDB sustava koja prvo dohvati korisnika preko njegovog
identifikatora pa kao rezultat vrati filmove povezane s tim korisnikom, preko ocjena koje je korisnik
dodijelio. Funkcija expand [66] kao parametar prima poveznicu (u ovom slučaju ocjenu), a kao rezultat
vraća dokument (u ovom slučaju filmove). Funkcija out [66] dohvaća izlaznu poveznicu (ocjenu).
29
function findByMovieId(ratings, movieId) {
var found = false;
for(var i = 0; ratings.length; ++i) {
var r = ratings[i];
if(parseInt(r.getProperty('movieId'))
=== parseInt(movieId)) {
found = r;
break;
}
}
return found;
}
function movieIntersection(movies1, movies2) {
var common = [];
for(var i = 0; i < movies1.length; ++i) {
var m1 = movies1[i];
var name = m1.getProperty('name');
for(var j = 0; j < movies2.length; ++j) {
var m2 = movies2[j];
if(name === m2.getProperty('name')) {
common.push(m1);
}
}
}
return common;
}
Isječak 18 - pomoćne funkcije za obradu liste filmova
Isječak 18 prikazuje pomoćne funkcije koje obrađuju listu filmova. Prva funkcija findByMovieId kao
parametre prima listu filmova i identifikator filma kojeg se želi vratiti iz liste. Funkcija pronalazi film iz
liste kompleksnošću O(n) što znači da je brzina pronalaska filma linearno ovisi o broju filmova.
Pretvorbom liste u HashMap moguće je kompleksnost smanjiti na O(1).
Druga funkcija movieIntersection kao parametre prima dvije liste filmova, a vraća novu listu koja u sebi
sadrži isključivo zajedničke filmove. Kompleksnost ovog algoritma je O(m x n) gdje su m i n broj
filmova u listama. Implementacijom HashMape bi se kompleksnost i ovog algoritma smanjila.
function pearson(ratings1, ratings2) {
var len = ratings1.length;
if(len === 0) { return 0; }
var sum1 = 0, sum2 = 0,
sum1sq = 0, sum2sq = 0,
tSum = 0;
for(var i = 0; i < ratings1.length; ++i) {
var r1 = ratings1[i];
30
var r2 = findByMovieId(ratings2,
r1.getProperty('movieId')); var v1 = r1.getProperty('value');
var v2 = r2.getProperty('value');
sum1 += v1;
sum2 += v2;
sum1sq += Math.pow(v1, 2);
sum2sq += Math.pow(v2, 2);
tSum += v1 * v2;
}
var num = tSum - ((sum1 * sum2) / len);
var den = Math.sqrt(
(sum1sq - Math.pow(sum1, 2) / len) *
(sum2sq - Math.pow(sum2, 2) / len)
);
if (den == 0) return 0;
return num / den;
}
Isječak 19 - implementacija Pearsonovog korelacijskog koeficijenta
Isječak 19 prikazuje implementaciju Pearsonovog korelacijskog koeficijenta. Funkcija je implementirana
programskim jezikom JavaScript koji je, uz SQL, podržan u OrientDB sustavu. Ruby, Scala, Java i drugi
programski jezici također će biti podržani u budućnosti [77]. Implementirana funkcija prima kao
parametre dvije liste ocjena korisnika iz kojih se izračuna sam koeficijent. Funkcija također koristi
funkciju izračuna korijena i kvadrata broja iz biblioteke Math u JavaScriptu (Math.pow i Math.sqrt).
// svi filmovi korisnika
var userMovies = getUserMovies(userId);
// svi korisnici
var allUsers = gdb.command('sql', 'select from User;');
// definiranje trenutno najvećeg koeficijenta
var highestP = -1, highestPUserId;
// pretraživanje svih korisnika i izračun koeficijenta
userId = parseInt(userId);
for(var i = 0; i < allUsers.length; ++i) {
// korisnik s kojim se uspoređuje
var user = allUsers[i];
var otherUserId = parseInt(user.getProperty('userId'));
// ne uspoređuj samog sebe if(otherUserId === userId) { continue; }
31
// dohvati sve filmove korisnika
var compareMovies = getUserMovies(otherUserId);
// filtriraj samo zajedničke filmove
var commonMovies = movieIntersection(userMovies, compareMovies);
// pretvorba liste u bolji format za OrientDB var movieIds = '[' + commonMovies.map(function(el) {
return el.getProperty('movieId'); }).join() + ']';
// ocjene
var otherRatings = getUserMoviesWithRatings(otherUserId, movieIds);
var myRatings = getUserMoviesWithRatings(userId, movieIds);
// izračun Pearsonovog koeficijenta var p = pearson(myRatings, otherRatings);
// ako je koeficijent veći, spremi ga
if(p > highestP) {
highestP = p;
highestPUserId = otherUserId;
}
}
// highestP => najveći koeficijent
// highestPUserId => identifikator korisnika s najvećim koeficijentom
var otherUserMovies = getUserMovies(highestPUserId);
// dohvaćanje disjunkcije između dvije liste filmova
var disjunction = movieDisjunction(userMovies, otherUserMovies);
disjunction = '[' + disjunction.map(function(el) {
return el; }).join() + ']';
disjunction = getUserMoviesWithRatings(otherUserId, disjunction);
// samo filmovi čija je ocjena >= 4
var rateBound = 4;
var movieIds = [], recommendations = [];
// izrada liste s prijedlozima
for(var i = 0; i < disjunction.length; ++i) {
var d = disjunction[i];
var rate = d.getProperty('value');
var movie = {
movieId: d.getProperty('movieId'),
name: d.getProperty('name')
};
if(rate >= rateBound) { recommendations.push(movie); }
}
return recommendations;
Isječak 20 - funkcija koja poziva izračun koeficijenta i odabire nove filmove
32
Isječak 20 prikazuje funkciju koja prihvaća identifikator korisnika za kojeg se traže novi filmovi, poziva
funkciju za izračun Pearsonovog korelacijskog koeficijenta, održava informaciju o trenutno najboljem
koeficijentu te vraća listu prijedloga novih filmova.
Na samom vrhu funkcije dohvaćaju se svi filmovi korisnika A te svi drugi korisnici s kojima će se
računati koeficijent. Nakon toga se za svakog od tih korisnika dohvaćaju njegovi filmovi, filtriraju samo
zajednički te se računa koeficijent. Nakon što je pronađen najbolji koeficijent i najsličniji korisnik,
filtriraju se filmovi koje je korisnik A već gledao/ocijenio. Obzirom da je potrebno predložiti samo one
filmove za koje je korisnik B rekao da su dobri (ocjena veća od 3), varijabla rateBound sadrži broj 4 koji
govori da se u obzir uzmu samo oni filmovi koji imaju ocjenu 4 ili 5. Lista s novim filmovima tako se
vraća pozivatelju funkcije tj. Ruby on Rails aplikaciji i nakon toga korisničkom pregledniku. OrientDB
kao rezultat vraća JSON objekt.
33
8. Ruby i Rails
Ruby [78] kao programski jezik i Rails [79] kao programski okvir, kada se radi o razvijanju internetskih
aplikacija, zauzimaju nemalen dio tržišta [80]. Izvor [81] navodi da je Ruby „dinamičan, reflektivan,
objektno-orijentirani programski jezik opće namjene koji kombinira sintaksu inspiriranu programskim
jezikom Perl, konceptualnu eleganciju programskog jezika Smalltalk te Pythonovu jednostavnost.“
Da bi opisao Rails, autor Daniel Kehoe [82] koristi šest različitih perspektiva:
1. preglednik - za korisnički preglednik, Rails je običan generator HTML koda
2. programer - kolekcija datoteka sa specifičnom strukturom koja je jednaka za svaku Rails
aplikaciju što omogućuje jednostavnu kolaboraciju među Rails programerima
3. softverski arhitekt - Rails daje razinu apstrakcije gdje arhitekt može grupirati elemente i
jednostavnije razmišljati o njihovim odnosima
4. gem lovac - Rails je popularan i zbog biblioteka funkcija koje mogu znatno ubrzati programiranje
5. putovanje kroz vrijeme - veliki broj Rails programera koristi Git i Github
6. testiranje - testiranje softvera dio je Rails kulture
OrientDB i Rails povezani su preko biblioteke orientdb4r. Isječak 21 prikazuje naredbu za instalaciju
orientdb4r biblioteke koju je potrebno uključiti unutar Rails aplikacije.
gem install orientdb4r
Isječak 21 - instalacija orientdb4r biblioteke
Iz perspektive Rails aplikacije, korisnički se zahtjev obradi i pozove se funkcija unutar kontrolera. Isječak
22 prikazuje kontroler koji zove funkciju unutar OrientDB baze. Funkcija initialize služi kao konstruktor
u kojem se inicijalizira veza prema OrientDB sustavu.
class HomeController < ApplicationController
def initialize
require 'orientdb4r'
@client = Orientdb4r.client
db = 'movies'
@client.connect :database => db, :user => 'root', :password =>
'root'
end
def index
@test = @client.query("SELECT getRecommendations(1);")
logger.debug @test
destructor
end
34
private
def destructor
@client.disconnect
end
end
Isječak 22 - Rails kontroler
Funkcija destructor služi kao destruktor u ovom kontroleru, koji nakon zahtjeva gasi vezu prema
OrientDB sustavu. Nedostatak ovakvog pristupa je otvaranje i zatvaranje veze prema OrientDB sustavu
svakim korisničkim zahtjevom te u ovom dijelu postoji prostor za promjene zbog skalabilnosti sustava.
Jedna od alternativa je korištenje skupa otvorenih veza (engl. connection pool) koji se neće zatvarati nego
će čekati sljedeći upit te se time neće gubiti procesorsko vrijeme na otvaranje i zatvaranje veze.
Funkcija index ostvaruje upit prema OrientDBu i prosljeđuje identifikator korisnika za kojeg želi
preporuke filmova. U ovom slučaju je naveden identifikator 1, ali Rails može proslijediti podatke i iz
HTTP GET parametara ili identifikator iz sjednice (engl. session) [83] prijavljenog korisnika.
35
9. Zaključak
Kolektivna inteligencija kao sposobnost grupe da riješi probleme bolje nego njeni pojedini članovi, otvara
vrata novim algoritmima, dokazima i mogućnostima. U radu se nalazi koncept gdje se poznati zadatak
kolektivne inteligencije kao što je prijedlog novih filmova, može riješiti jednostavnim pojmom grafa.
Koncepti poput šetnji, ciklusa, puteva, eigenvektora i sl. samo su pomoćni pojmovi koji mogu dodatno
olakšati dokaze, a koncepti poput analize socijalnih mreža mogu dodati veliki broj dodatnih informacija.
Iz rada je jasno vidljivo kada treba koristiti koju mjeru sličnosti te na koji način analizirati socijalnu
mrežu sustava kako bi se znalo ne samo koji film korisnik voli ili ne, nego i razloge zašto.
U radu je korišten Pearsonov korelacijski koeficijent koji se pokazao kao fantastična mjera sličnosti te
OrientDB baza koja izuzetno prirodno implementira već poznati SQL, u svijet teorije grafova.
OrientDB kao relativno nova tehnologija pokazala se poprilično jednostavnom za korištenje. Istražujući
ga uvidio sam i nekoliko nedostataka od kojih je najveći razlika između inačica u smislu stabilnosti. Kroz
Github sustav, vidljivo je koliko brzina unosa može degradirati u različitim inačicama što je očiti primjer
„mladog“ softvera. Sustav je spreman za produkcijsku upotrebu, ali kroz izuzetno dobro napisane testove
potrebno je testirati svaku novu inačicu jer razlike mogu biti enormne.
Ruby kao programski jezik i Rails kao programski okvir omogućuju izuzetno brz razvoj internetskih
aplikacija što je danas, uz jednostavnost i cijenu, jedan od nekoliko najbitniji čimbenika pri odabiru
tehnologije.
Programski kod pisan je kao koncept te kao takav nije spreman za produkcijsku upotrebu.
__________________________________________________
36
10. Literatura
[1] T. Segaran, »Programming Collective Intelligence«.
[2] F. Heylighen, Collective Intelligence and its Implementation on the Web: Algorithms to Develop a
Collective Mental Map, 1999.
[3] T. W. Malone, What Is Collective Intelligence, and What Will We Do About It?, 2006.
[4] P. Levy, Collective Intelligence: Mankind’s Emerging World in Cyberspace.
[5] F. Stremtan, Some consideration regarding collective intelligence., 2008.
[6] P. Resnick i H. R. Varian, Recommender systems.
[7] S. Alag, Collective Intelligence in Action, Manning, 2009.
[8] N. Prize, http://www.netflixprize.com.
[9] J. Bennett i S. Lanning, The Netflix Prize.
[10] N. P. Leaderboard, http://www.netflixprize.com/leaderboard.
[11] M. About, https://movielens.org/info/pages/about/.
[12] G. Datasets, http://grouplens.org/datasets/movielens/.
[13] H. Shimodaira, »Similarity and recommender systems,« 2015.
[14] P. Barrett, »Euclidean Distance: raw, normalized, and double‐scaled coefficients«.
[15] F. Smarandache, »Alternatives To Pearson’s and Spearman’s Correlation Coefficients«.
[16] S. Niwattanakul, J. Singthongchai, E. Naenudorn i S. Wanapu, Using of Jaccard Coefficient for
Keywords Similarity.
[17] P. Gyarmati, »Some words about networks,« 2011.
37
[18] B. Miklos, A walk through Combinatorics - An introduction to Enumeration and Graph Theory.
[19] G. Alexanderson, »Euler and Konigsberg's bridges: A historical view«.
[20] L. Euler, »Solutio Problematis ad Geometriam Situs Pertinentis«.
[21] A. Nakić i M. O. Pavčević, Uvod u teoriju grafova, Zagreb, 2015.
[22] K. Ruohonen, Graph Theory, 2013.
[23] C. Griffin, Graph Theory: Penn State Math 485 Lecture Notes.
[24] T. Harju, Lecture Notes on GRAPH THEORY.
[25] B. Chen, Introduction to Graph Theory.
[26] P. Van Dooren, Graph Theory and Applications.
[27] R. Zadeh, Discrete Mathematics and Algorithms.
[28] M. Aldridge, Topics in Discrete Mathematics.
[29] L. Trevisan, Stanford University - CS261: Optimization.
[30] K. Rosen, Discrete Mathematics and its Applications.
[31] V. Adamchik, Graph Theory.
[32] A. Aglić-Aljinović, EKSTREMALNA KOMBINATORIKA.
[33] S. Sawant, Collaborative Filtering using Weighted BiPartite Graph Projection - A Recommendation
System for Yelp.
[34] A. Bohn, I. Feinerer, K. Hornik i P. Mair, Content-Based Social Network Analysis of Mailing Lists.
[35] C. Butts, Social Network Analysis with sna.
[36] D. Bader, S. Kintali, K. Madduri i M. Mihail, Approximating Betweenness Centrality.
38
[37] D. Bader, R. McColl i O. Green, A Fast Algorithm for Streaming Betweenness Centrality.
[38] P. Hoff, Centrality 567 Statistical analysis of social networks.
[39] M. H. Bhuiyan i S. Arifuzzaman, CENTRALITY MEASURES.
[40] C. A. R. Pinheiro, Social Network Analysis in Telecommunications.
[41] https://github.com/orientechnologies/orientdb.
[42] G. Burd, NoSQL.
[43] M. Stonebraker, SQL Databases v. NoSQL Databases, CACM.
[44] A. Nayak, A. Poriya i D. Poojary, Type of NOSQL Databases and its Comparison with Relational
Databases.
[45] S. Hall, Cassandra An introduction to data modeling techniques - an evolution of enterprise
architecture.
[46] http://redis.io.
[47] http://basho.com.
[48] http://www.project-voldemort.com.
[49] http://cassandra.apache.org.
[50] https://hbase.apache.org.
[51] https://www.mongodb.org.
[52] http://couchdb.apache.org.
[53] https://ravendb.net.
[54] http://neo4j.com.
[55] http://orientdb.com.
39
[56] http://infogrid.org.
[57] L. Dell’Aquila, http://orientdb.com/orientdb-more-than-sql/.
[58] T. Green, Introduction to Database Systems.
[59] Silberschatz, Korth i Sudarshan, Database System Concepts.
[60] http://orientdb.com/docs/last/Tutorial-Document-and-graph-model.html.
[61] TutorialsPoint, http://www.tutorialspoint.com/orientdb/orientdb_tutorial.pdf.
[62] A. Bilal i M. Khalid, GRAPH DATABASES AND ORIENTDB.
[63] http://orientdb.com/docs/2.0/orientdb.wiki/Tutorial-Record-ID.html.
[64] https://github.com/orientechnologies/orientdb/issues/5386.
[65] https://groups.google.com/forum/#!topic/orient-database/gxNRbPqwi-0.
[66] http://orientdb.com/docs.
[67] http://orientdb.com/docs/last/SQL.html#orientdb-sql-dialect.
[68] http://orientdb.com/docs/last/Concepts.html#record.
[69] http://orientdb.com/docs/last/Tutorial-Classes.html.
[70] http://domagoj.eu/oib/.
[71] http://orientdb.com/new-orientdb-graph-factory/.
[72] https://github.com/warriorkitty/orientlens.
[73] http://programmers.stackexchange.com/questions/65742/stored-procedures-a-bad-practice-at-one-of-
worlds-largest-it-software-consulting.
[74] https://blog.codinghorror.com/who-needs-stored-procedures-anyways/.
40
[75] http://ptgmedia.pearsoncmg.com/images/0789725843/updates/cfwack.c30.cd.pdf.
[76] http://c2.com/cgi/wiki?StoredProceduresAreEvil.
[77] http://orientdb.com/docs/2.0/orientdb.wiki/Functions.html#functions.
[78] https://www.ruby-lang.org/.
[79] http://rubyonrails.org/.
[80] http://trends.builtwith.com/framework.
[81] V. Dwarampudi, S. S. Dhillon, S. Jivitesh, N. J. Sebastian i N. S. Kanigicharla, Comparative study of
the Pros and Cons of Programming languages Java, Scala, C++, Haskell, VB .NET, AspectJ, Perl,
Ruby, PHP & Scheme.
[82] D. Kehoe, Learn Ruby on Rails.
[83] J. Weiss, How Rails Sessions Work (http://www.justinweiss.com/articles/how-rails-sessions-work/).