SVEUČILIŠTE U ZAGREBU FAKULTET ELEKTROTEHNIKE I RAČUNARSTVA DIPLOMSKI RAD br. 1114 Dinamičko prepoznavanje dijelova web stranica Tomislav Tenodi Zagreb, lipanj 2015.
SVEUČILIŠTE U ZAGREBU
FAKULTET ELEKTROTEHNIKE I RAČUNARSTVA
DIPLOMSKI RAD br. 1114
Dinamičko prepoznavanje dijelova
web stranica
Tomislav Tenodi
Zagreb, lipanj 2015.
Sadržaj
1. Uvod ......................................................................................................................... 1
2. Web .......................................................................................................................... 3
2.1. Semantički web .................................................................................................. 3
2.2. HTML5 ............................................................................................................... 6
2.3. Konvencije programera ...................................................................................... 8
3. Dinamički model temeljen na strojnom učenju ....................................................... 11
3.1. Označavanje podataka .................................................................................... 12
3.1.1 Google Chrome ekstenzija za označavanje stranica ................................. 12
3.2. Ekstrakcija značajki .......................................................................................... 25
3.2.1 Priprema podataka .................................................................................... 26
3.2.2 Ekstrakcija značajki za kategorije navigacije ............................................. 34
3.2.3 Ekstrakcija značajki za kategorije stavki .................................................... 41
3.2.4 Ekstrakcija značajki za kategoriju formi ..................................................... 46
3.2.5 Ekstrakcija značajki za kategoriju općenitih podataka ............................... 50
3.3. Odabir i treniranje modela ................................................................................ 52
3.3.1 Odabir stroja potpornih vektora ................................................................. 53
3.3.2 O stroju potpornih vektora ......................................................................... 54
3.3.3 Odabir modela ........................................................................................... 56
3.3.4 Treniranje modela ...................................................................................... 58
4. Poslužitelj Oculi ...................................................................................................... 60
4.1. Implementacija poslužitelja i sučelja ................................................................ 61
4.2. Prezistencija modela i pripadni API .................................................................. 63
4.3. Sustav validacije označivača............................................................................ 67
4.4. Prezentacija cjelokupnog koncepta .................................................................. 71
5. Zaključak ................................................................................................................ 74
6. Literatura ................................................................................................................ 76
7. Sažetak .................................................................................................................. 78
8. Summary ................................................................................................................ 79
1
1. Uvod
Danas, na svijetu postoji gotovo milijardu web stranica [1]. Te stranice sadrže poprilično
veliku bazu informacija, koje svojom prezentacijom traže iskustvo, stečeno učestalim
pregledavanjem i istraživanjem (tzv. surfanjem) stranica, za njihovo tumačenje. Naime,
osjet vida i iskustvo surfanja postaju sve važniji zbog bogatstva dinamike koje web
stranice često pružaju. Mnoge tvrtke fokusiraju se na izradu isključivo snažnih web
aplikacija, kako bi se smanjilo razvojno vrijeme, a novi bogati radni okviri (eng.
framework), među kojima je i nezaobilazni Bootstrap1, najpopularniji radni okvir za čelni
razvoj (eng. front-end), omogućuju sve jednostavniju prilagodbu web aplikacija svim
veličina ekrana te svim uređajima.
U takvom globalno povezanom sustavu, javlja se potreba za pretraživanjem i
izvlačenjem novih informacija bez ljudskog utjecaja. Jedna od upečatljivijih primjena
tako stečenih informacija nalazi se kod osoba s oštećenjem vida. Ova potreba nije
nova, te svakim danom jača, zbog sve veće važnosti weba. Da bi slijepa osoba mogla
pretražiti stranicu za potrebnim informacijama, ona se mora dobro upoznati sa
strukturom stranice. To se upoznavanje odvija prolaženjem prsta preko zaslona na
dodir (eng. touchscreen), na čiji događaj, stroj govorne sinteze (eng. speech-to-text
machine) daje povratnu informaciju o poziciji. Opisani postupak traje nekoliko minuta,
što ima velike posljedice na konkurentnost slijepih i slabovidnih osoba na tržištu rada.
Takvim je korisnicima potrebno efikasno, intuitivno i fleksibilno surfanje.
Postoji više načina kako riješiti problem potrebe ljudskog iskustva za tumačenje
struktura pri prikazivanju informacija, među kojima su semantički web, rješenje
temeljeno na konvenciji programera i strojno učenje.
Razvojem jačine računala, moguće je velikim bazama podataka omogućiti učenje
računala temeljeno na proučavanju njihovih struktura i obrazaca (eng. pattern). Takav
postupak naziva se strojno učenje (eng. machine learning). Potrebno je podatke o
stranicama i njihovim semantičkim dijelovima prikupiti u repozitorij označenih podataka.
Jednom kada repozitorij bude prikladne veličine i stupnja raznovrsnosti, web stranice se
1 http://getbootstrap.com/
2
iz repozitorija mogu koristiti za treniranje modela. Atribut raznovrsnosti teško je postići u
svijetu s približno milijardu stranica, tako da je potrebno napraviti alat koji će omogućiti
suradnju više označivača koji će pomoći pri izgradnji prikladnog repozitorija. Jednom
naučeni model, može se koristiti za dinamičko prepoznavanje dijelova stranica.
Naučenim modelom, slijepa osoba se više ne bi trebala upoznavati sa strukturom
stranice, već bi npr. glasovnom naredbom mogla zatražiti pojedini dio stranice, kao što
je najnovija vijesti, koji bi joj se na zahtjev pročitao. Također postoje i mnogi drugi
primjeri korištenja ovog modela, kao što je za svrhu tražilica i povezivanja podataka pri
pretraživanju stranica.
3
2. Web
Često se pojam WWW (World Wide Web), popularno web (hrv. mreža), zamjenjuje
pojmom Interneta. Za Internet se često kaže da je "mreža svih mreža", a predstavlja
infrastrukturu koja se koristi da bi se računala diljem svijeta povezala. S druge strane,
WWW je samo jedna od mnogih usluga Interneta koja koristi HTTP (Hypertext Transfer
Protocol) kao protokol za razmjenu hipertekstualnih dokumenata.
Davne 1989., Tim Berners-Lee izumio je WWW [2]. Ubrzo potom, broj stranica počeo je
rasti eksponencijalno. Web programeri tražili su kreativna rješenja kako bi što bolje
oblikovali svoje stranice i tako dobili što veću publiku. Godine 1994. na globalnu scenu
došla je prva verzija CSS-a (Cascading Style Sheet) te omogućila lakše definiranje
izgleda stranice. Danas, stranice su vrlo raznolike i sofisticirane uključujući mnoge
dinamičke elemente pri čemu je za njihovo korištenje potrebno prethodno iskustvo
stečeno učestalim surfanjem weba.
2.1. Semantički web
Već u samom početku, programeri su počeli zloupotrebljavati HTML (HyperText Markup
Language) oznake u svrhu definiranja izgleda pojedinih stranica, primjer oznaka <h1>,
ili druge svrhe, kao što je SEO (Search Engine Optimisation), primjer oznaka <title>.
Semantika oznake <h1> je definiranje najvažnijeg zaglavlja, a često se koristi samo u
svrhu povećanja teksta. Time web klijenti ne mogu tumačiti oznake <h1> kao naslove. S
druge strane, oznaka <title> često se puni beskrajnim ključnim riječima, kako bi
programi korišteni za indeksiranje web stranica (eng. web crawlers), postavili stranicu
među prvim rezultatima pretrage. Tu metodu web crawleri danas više ne koriste upravo
zbog takve zloupotrebe.
Web stranice postajale su sve manje konzistentne. To stanje bilo je poduprto glavnim
web preglednicima koji niti HTML dokument s velikim pogreškama nisu odbacivali
prikazati. Pozitivna posljedica bila je sveopće prihvaćenje HTML-a kao označnog jezika
te velika ekspanzija weba, dok je s negativne strane web postajao sve zamršenijim
4
prostorom. Web stranice bile su namijenjene isključivo ljudima. Kao otpor tome, pojavio
se semantički web kao proširenje weba. Semantički web je vizija: ideja o mogućnosti
da podaci na webu budu definirani i povezani na način na koji bi se, osim za sami prikaz
i automatizaciju, mogli koristiti za integraciju i ponovnu iskoristivost u različitim
aplikacijama [3]. Korištenjem umjetne inteligencije, računala bez intervencije korisnika
donose zaključke. Postupak se oslanja na više tehnologija (URI, XML, RDF, RDFS,
OWL, RIF, RDFa i SPARQL) koje služe kako bi se podaci mogli označiti na principu
subjekt - predikat - objekt što računalima omogućuje zaključivanje i povezivanje
struktura podataka, koji su do sada bili samo ljudski zadaci. Poznat je stog semantičkog
weba prikazan na slici 2.2.
U semantičkom webu, svaki resurs, apstraktan ili opipljiv ima svoj jedinstveni URI
(Uniform Resource Identifier) [4]. Kao format zapisa podataka tog resursa, koristi se
XML (Extensible Markup Language). Sve tehnologije semantičkog weba zasnivaju se
na XML-u, pri čemu je semantika podataka pohranjenih XML-om sačuvana na višim
slojevima. RDF (Resource Description Framework) je standardan model za izmjenu
podataka na webu [5]. RDF olakšava spajanje podataka različitih shema, a namijenjen
je za spremanje "podataka o podacima", odnosno za spremanje metapodataka. Temelji
se na konceptu trojki: subjekt - predikat - objekt, pri čemu neki subjekt ima određeno
svojstvo, predikat, čija je vrijednost objekt. Vrijednost objekta može biti neki drugi resurs
ili obična podatkovna vrijednost. Sljedeća slika prikazuje jedan RDF model, nakon čega
slijedi XML isječak za taj model.
Slika 2.1 RDF model
5
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns"
xmlns:foaf="http://xmlns.com/foaf/0.1/" >
<rdf:Description rdf:about="http://www.twitter.com/TomislavTenodi">
<foaf:knows rdf:resource="http://www.twitter.com/hrvix"/>
<foaf:firstName>Tomislav</foaf:firstName>
</rdf:Description>
</rdf:RDF>
RDF opisuje resurse s klasama, svojstvima i vrijednostima, a te klase, odnose među
klasama te svojstva i odnose među svojstvima treba nekako opisati. To radimo jednom
razinom iznad, odnosno opisujemo sam RDF rječnik. Tome služi RDFS (RDF Schema
ili RDF Vocabulary Description Language). RDFS-om se predstavlja znanje o
podacima.
Očekivanja su bila velika: "Semantički web omogućit će strojevima RAZUMIJEVANJE
semantičkih dokumenata i podataka", "Ispravno dizajniran, semantički web može
pomoći evoluciji sveukupnog ljudskog znanja" [6].
Zbog nezrelosti i eksponencijalnog rasta same web zajednice, spomenuti standardi nisu
globalno prihvaćeni. Pet godina nakon objave članka punog nade o semantičkom webu,
Tim Berners-Lee daje poznatu izjavu "Ova jednostavna ideja ostaje, ipak, uvelike
nerealizirana" [7]. No, te iste godine Tim Berners-Lee najavljuje SPARQL (SPARQL
Protocol and RDF Query Language), upitni jezik za RDF s izjavom: "SPARQL će učiniti
veliku razliku" [8].
Dakle, SPARQL je:
upitni jezik za RDF,
protokol koji definira upotrebu SPARQL upitnog jezika preko HTTP-a te
specifikacija XML formata za ispis rezultata SPARQL upita.
Verzija 1.0 izdana je 2008. godine, a godine 2013. dolazi nadogradnja na verziju 1.1.
Od tehnologija za semantički web postoje još ontologije i bogatiji vokabulari. Ontologija
je model podataka koji predstavlja skup pojmova unutar neke domene i veze između tih
pojmova. OWL (Web Ontology Language) je jezik semantičkog weba koji je stvoren da
omogući predstavljanje kompleksnijeg znanja o entitetima.
6
Slika 2.2 Stog semantičkog weba
Osim ontologije, postoje i vokabulari koji su njen podskup. RDFS ponekad nije dovoljan,
pa se tada koristi OWL i RIF (Rule Interchange Format) koji služi za definiranje
kompleksnijih pravila među podacima.
Kako bi se semantički web uspio ugraditi u "normalan" web, potrebno je omogućiti
ugradnju RDF izjava u HTML, odnosno XHTML (Extensible HTML), jer sve tehnologije
u semantičkom webu ovise o XML-u. RDFa (Resource Description Framework in
Attributes) upravo tome služi pri čemu koristi proširenja XHTML-a, odnosno atribute
kako bi ugradio RDF izjave.
Iako konceptualno jednostavna ideja semantičkog weba, za sobom povlači mnoge
tehnologije koje treba savladati prije nego što se krene u proširenju svojeg weba k
semantičkom.
2.2. HTML5
HTML je standardni označni jezik koji se koristi za definiranje strukture i sadržaja web
stranica. Današnja verzija, HTML5 ima namjeru poboljšati jezik podrškom za najnovije
7
oblike multimedije, održavajući jezik čitljivim ljudima i razumljivim računalima i uređajima
[9]. Ta verzija, objavljena u listopadu 2014. godine, nastavak je na HTML 4, XHTML 1
(Extensible HTML) i DOM Level 2 HTML (Document Object Model). HTML5 dodaje
neke oznake, kao što su <video>, <audio>, <canvas> i <object> koje olakšavaju
rukovanje multimedijskim i grafičkim sadržajem bez potrebe korištenja dodatnih utikača
(eng. plugin). Također, nadodani su novi elementi koji obogaćuju semantičku stranu
sadržaja i upravo će oni biti važni pri dinamičkom prepoznavanju semantičkih dijelova
web stranica. Sljedeća tablica sadrži listu tih elemenata, njihov opis i primjer korištenja
unutar cijelog HTML dokumenta.
Tablica 1 Nove semantičke oznake
<article> Definira članak stranice. Treba imati svoje značenje kada ga se
gleda neovisno na ostatak stranice. Tipičan primjer je članak na
nekom portalu.
<aside> Definira sadržaj "po strani" elementa unutar kojeg je definiran s
kojim treba biti povezan. Primjer je izbornik neke stranice.
<figure> Definira zaseban sadržaj, kao što su ilustracije, dijagrami, slike, itd.
Predstavlja manji zaseban sadržaj naspram dijela definiranog
<article> oznakom.
<footer> Definira donje zaglavlje dokumenta ili nekog dijela dokumenta.
Sadrži informacije o autoru, licencama, kontakt informacije itd.
<header> Definira zaglavlje dokumenta ili nekog dijela dokumenta. Uglavnom
su to naslovi, logo slike ili informacije o autorima.
<main> Definira glavni sadržaj čitavog dokumenta. Sadržaj unutar <main>
oznake mora biti jedinstven unutar cijelog dokumenta i <main> ne
smije biti potomak <article>, <aside>, <footer>, <header> ili <nav>
oznaka.
<nav> Definira nakupinu navigacijskih poveznica. Tipično je to izbornik.
8
<section> Definira sekciju u dokumentu. To su uglavnom poglavlja, zaglavlja ili
neke druge sekcije unutar dokumenta.
Ovim elementima će biti puno lakše otkriti neki semantički dio stranice, nego što je to
bilo prije HTML5 verzije označnog jezika stranica. No, kao što su i prije postojale
oznake koje su na neki način označavale semantiku dijelova, kao što su <h1> i <title>,
treba biti oprezan sa zaključivanjem semantičkih dijelova stranica temeljem samo
oznaka.
2.3. Konvencije programera
Problem semantičkih dijelova stranica vrlo bi se brzo riješio kada bi svi poštovali
unaprijed dogovorena pravila. Dugotrajan je proces globalnog prihvaćanja pravila, ako
korist samog prihvaćanja nije ogromna. Najviše koristi od strogog pridržavanja pravila
imale bi internet tražilice, a ta bi se korist manje propagirala na same programere
stranica koji bi imali koristi od prikaza stranice u rezultatima pretrage tražilica. Upravo
su zato najveće Internet tražilice, kao što su Bing, Google i Yahoo, pokrenule
zajedničku inicijativu 2011. godine pod nazivom Schema.org. Njihova namjera bilo je
kreiranje ontologije i Microdata2 u HTML5 kako bi se omogućilo označavanje web
stranica s metapodacima [12]. Postupak je dosta sličan semantičkom webu, ali je sve
već unaprijed definirano samim standardom, tako da programeri moraju samo unijeti
dodatne metapodatke unutar već definiranih oznaka kako bi dali semantički značaj
sadržaju u dokumentu. Schema.org3 definira veliki rječnik metapodataka, odnosno
ontologiju tipova koje se koriste pri davanju značenja sadržaju. Tip najšireg pojma je
Thing (hrv. stvar) koja ima 4 svojstva: name, description, url i image. Specifičniji tipovi
dijele svojstva širih tipova, baš kao nasljeđivanje u objektno orijentiranoj paradigmi.
Tako je Movie (hrv. film) specifičniji tip CreativeWorka, što je pak specifični tip Thinga i
dodaje neka svoja specifična svojstva, kao što su actor, director, duration i druga.
2 Microdata je WHATWG (Web Hypertext Application Technology Working Group) specifikacija koja
omogućuje gnježđenje podataka o podacima unutar sadržaja na web stranicama [11]. 3 http://schema.org/
9
Sljedeći primjer pokazuje kako se na lak način može napraviti transformacija postojećih
podataka u podatke koji daju svoju semantičku vrijednost.
Podaci prije transformacije:
<div>
<h1>Avatar</h1>
<span>Director: James Cameron (born August 16, 1954)</span>
<span>Science fiction</span>
<a href="../movies/avatar-theatrical-trailer.html">Trailer</a>
</div>
Podaci poslije transformacije
<div itemscope itemtype ="http://schema.org/Movie">
<h1 itemprop="name"&g;Avatar</h1>
<div itemprop="director" itemscope
itemtype="http://schema.org/Person">
Director: <span itemprop="name">James Cameron</span> (born <span
itemprop="birthDate">August 16, 1954)</span>
</div>
<span itemprop="genre">Science fiction</span>
<a href="../movies/avatar-theatrical-trailer.html"
itemprop="trailer">Trailer</a>
</div>
Kao što sam već napomenuo, da bi se programeri pridržavali neke konvencije, oni
moraju imati vrijednu korist od toga. Pridržavajući se konvencija pisanja programskog
kôda, kôd postaje što čitljiviji, te je puno razumljivije pročitati neki novi kôd koji je
napisan pridržavajući se konvencije. Korist u korištenju ove konvencije ne tiče se
prioritetno programera, već tražilica koje bi svojim pretraživanjem mogle što više
zaključiti o podacima i tako svojim korisnicima omogućili što bogatije iskustvo svojim
korisnicima prikazujući najbolje rezultate. Velik je broj slučajeva u kojima programerima
stranica to ne ide u korist jer nemaju sve potrebne informacije koje bi korisnici tražili
preko stranica, odnosno to najviše ide u korist ogromnim web stranicama koje imaju
informacije i usluge zanimljive velikoj populaciji korisnika koje će o stranici saznati
koristeći tražilice. Smatram da će ostali programeri, koji još ne koriste Schema.org, a
žele napraviti kvalitetnu stranicu, biti primoran učiniti svoju stranicu kompatibilnom sa
Schema.org konvencijom, jer velik broj korisnika češće nalazi nove web stranice putem
tražilice, nego putem poveznica s ostalih stranicama. No, ovu konvenciju vežu sljedeći
10
problemi koji upućuju na to da se ona neće moći sama koristiti pri dinamičkom
segmentiranju dijelova stranica:
Veći broj stranica ne koristi konvenciju propisanu ontologijom Schema.org.
Korištenje te ontologije je sklono pogreškama (eng. error prone) i vrlo lako može
biti meta zloupotrebe Microdata podataka.
Cijelo korištenje ovisi o programerima stranica, te će programeri uvijek moći
napraviti stranicu bez potrebe definiranja dodatnih metapodataka, čime cijela
konvencija ovisi o samom iskustvu i upućenosti programera.
Upravo će se zato Schema.org koristiti kao komponenta pri dinamičkom segmentiranju
onih stranica koje podržavaju tu konvenciju. Na djelomičnoj i maloj listi4 tih stranica
može se vidjeti kako već velike web aplikacije podržavaju konvenciju Schema.org.
4 http://getschema.org/index.php/List_of_websites_using_Schema.org
11
3. Dinamički model temeljen na strojnom učenju
U prethodnom poglavlju pokazano je kako niti jedan od predloženih načina rješavanja
trenutno ne može obuhvatiti čitav web. Kao rješenje, nameće se korištenje algoritama
strojnog učenja. Strojno učenje je, kao što samo ime kaže, učenje računalnih modela
temeljem iskustva iz već viđenih podataka.
Razvojem područja strojnog učenja, javlja se mogućnost za otkrivanjem skrivenih
struktura unutar velike količine podataka, odnosno mogućnost za optimizacijom
kriterijske funkcije temeljem skupa primjera ili iskustva [13]. Za neke zadatke, kao što je
raspoznavanje semantičkih dijelova web stranica, nemamo algoritam, te ćemo taj
nedostatak znanja nadoknaditi količinom podataka. Analiziranjem web stranica želimo
uočiti učestale obrasce koji definiraju strukturu semantičkih dijelova stranica kao što su
navigacija, stavke raznih kategorija (postovi, oglasi, članci, ...), forme raznih kategorija
(prijava/registracija, komentar, tražilica, filtriranje, ...) te općenite informacije. Pomoću
ove klasifikacije strojnog učenja, nastao je dinamički model transformiranja web
stranica. Model će za stranice koje koriste konvenciju Schema.org koristiti značajke
temeljene na dodanim semantičkim značenjima pomoću metapodataka, no korištenje te
konvencije neće biti potrebno, te će se sve stranice moći dinamički segregirati. Tako se
uklanja statičnost definiranja pojedinih metapodataka.
Tipični koraci u strojnom učenju su:
1. označavanje podataka,
2. ekstrakcija značajki,
3. redukcija dimenzionalnosti,
4. odabir modela,
5. treniranje modela te
6. evaluacija [14].
U prvom koraku, potrebno je označiti podatke kako bi ih se moglo proučavati. Jednom
kada repozitorij bude prikladne veličine i stupnja raznovrsnosti, web stranice se iz
repozitorija mogu koristiti za treniranje modela. Atribut raznovrsnosti teško je postići u
12
svijetu s približno milijardu stranica. Stoga je potrebno mehanizam označavanja stranica
provesti što preciznije i jednostavnije.
"Grupiranje se često koristi za istraživanje podataka (eng. data exploration), s ciljem
pronalaženja skrivene strukture u podacima. Jednom kada se primjeri grupiraju,
dobivene grupe mogu se ručno označiti, središta grupa mogu se tumačiti kao prototipni
predstavnici grupa, a za svaku se grupu mogu utvrditi tipični rasponi vrijednosti
značajki. To omogućava da se podaci opišu na jednostavniji način, da se uoče
pravilnosti i sličnosti u podatcima te da se otkriju odnosi između grupa." [15]
Kako bi se određivanje semantičkih dijelova stranica odvijalo potpuno automatski, korak
označavanja podataka treba se odvijati u sljedećim potkoracima:
1. napraviti algoritam koji će putovati po popularnim web stranicama te će ih skupiti
u inicijalni repozitorij,
2. grupirati podatke iz tog repozitorija,
3. ručno označiti stranice Google Chrome ekstenzijom te
4. počistiti podatke i pretvoriti ih u repozitorij spreman za treniranje modela.
Ovaj sam razvoj započeo sa zadnja dva potkoraka, jer bi se oni mogli izvesti i u izolaciji,
bez prethodno definiranih grupa.
3.1. Označavanje podataka
Označavanjem podataka potrebno je sakupiti veći repozitorij stranica s naznačenim
elementima pojedinih kategorija. Kako bi se kreirao što kvalitetniji i raznovrsniji
repozitorij, potrebno je označiti što više stranica, pri čemu je poželjno imati više
označivača. Iz tog razloga sam za označavanje napravio Google Chrome ekstenziju.
3.1.1 Google Chrome ekstenzija za označavanje stranica
Ekstenzije određenog preglednika modificiraju njegovo ponašanje otvorenog sučelja,
API-ja (Application Programming Interface). Razlog zašto sam se odlučio za Google
Chrome je njegova popularnost. Također, velik dio Google Chromea je otvoreni kôd
13
razvijan pod projektom naziva Chromium5. Time su mnoge funkcionalnosti, kao što su
ekstenzije dostupne i na vrlo malim uređajima, koji inače ne bi mogli pokrenuti sam
Google Chrome, kao što je Raspberry Pi.
Preglednik Google Chrome nastao je 2008. godine, a već godinu dana kasnije
omogućena je izgradnja ekstenzija za preglednik. Dugogodišnjim razvijanjem i
unaprjeđivanjem funkcionalnosti, Chrome ekstenzije imaju mogućnosti:
kreiranja, organiziranja i rukovanja knjižnim oznakama (eng. bookmarks),
korištenja naredbi za kreiranje prečaca i događaja pri pritisku određenih tipki,
modificiranja sadržaja stranica,
korištenja stroja tekst-u-govor (eng. text-to-speech, skraćeno TTS),
upravljanja komponentama preglednika Chrome te mnoge druge [16].
Ekstenzija je zapravo paket datoteka - HTML, CSS, Javascript, slika i ostalih potrebnih
podataka - komprimiranih u ZIP datoteku [17]. Mnoge ekstenzije postavljaju vlastiti GUI
(Graphical User Interface) na preglednik Chrome u jedne od dvije moguće forme:
browser action ili page action. Browser action se koristi kada je ekstenzija namijenjena
većem broju stranica, dok se page action koristi kada je ekstenzija potrebna samo za
neke stranice (npr. stranice koje sadržavaju slike, kako bi ekstenzija mogla generirati
galeriju slika sa stranice). Kod označavanja stranica, apsolutno svaka stranica je
relevantna za označavanje i može ući u izbor za ručno označavanje, tako da ekstenzija
za označavanje stranica spada pod browser action ekstenzije, a njen dodan GUI na
pregledniku Chrome prikazuje sljedeća slika.
Slika 3.1 GUI ekstenzije za označavanje stranica
Prije nego što sam počeo s razradom ekstenzije, bilo je potrebno odrediti semantičke
dijelove stranica koji će biti od značenja te stupanj granularnosti. Odlučio sam se za 4
5 https://www.chromium.org/
14
kategorije semantičkih dijelova stranica koje sam već spomenuo na početku poglavlja o
dinamičkom modelu:
navigacija,
stavke,
forme i
općenite informacije.
Stavke su općenit izraz za glavne dijelove koji su specifični za pojedinu stranicu: na
portalima su to vijesti, članci, lista komentara i ponekad neki oglasi, na forumu to su liste
tema, postovi i komentari, na oglašivačkim portalima, to su oglasi itd. Kako označivač
ne bi morao označiti svaku vijest ili svaki komentar posebno, mora se pružiti mogućnost
da se odjednom označi više stavki kao kolekcija. S druge strane, navigacija, forme i
općenite informacije su dijelovi koji se pojavljuju na svim stranicama te njihova
semantika nije specifična, već je opisana samim nazivom kategorije. Sve navedene
kategorije i njihove potkategorije su pokazane na sljedećoj slici.
Slika 3.2 Izbornik i transparentni blok ekstenzije za označavanje stranica
15
Kategorije se razlikuju u boji transparentnog bloka koji se ubrizga u stranicu, a njihove
potkategorije se razlikuju u teksturi pozadine transparentnog bloka. Sljedeća slika
prikazuje sve vrste teksture na crvenom transparentnom bloku.
Slika 3.3 Sve vrste tekstura potkategorija
Dostupne su 4 vrste tekstura:
bez teksture,
dijagonalne pruge,
vertikalne pruge te
dijagonalne i okomite pruge,
koje omogućuju predstavljanju svih potkategorija unutar pojedine kategorije. Treba
napomenuti da trenutno odabrane kategorije nisu konačne, te da će se promijeniti, ako
se pokaže potreba za boljom organizacijom ili granulacijom semantičkih dijelova
stranica.
16
Na samom početku označavanja neke stranice, potrebno je kliknuti na GUI ekstenzije
za označavanje stranica pri čemu se pojavljuje pop-up (hrv. skočni) prozor nudeći
početak označavanja trenutne stranice.
Slika 3.4 Pop-up prozor ekstenzija za označavanje stranica
Nakon što pokrenemo označavanje trenutne stranice, u DOM stranice se ugrađuju
elementi ekstenzije za označavanje stranica - transparentni blok, izbornik koji je skriven
za odabir kategorije semantičkog dijela stranice i rukovatelji događaja (eng. event
handlers) za prelaženje mišem preko elemenata stranica. Okidanjem događaja
prelaženja miša po elementima stranice, ažurira se pozicija transparentnog bloka na
poziciju trenutnog elementa. Tako označivač zna na kojem se elementu nalazi te u
slučaju semantičkog dijela može kliknuti na transparentni blok. Klikom na transparentni
blok, prikazuje se izbornik za određivanje kategorije elementa. Na slici 3.2. se, u sloju
ispod izbornika, može vidjeti transparentni blok.
HTML dijelovi i rukovatelji događaja se na stranicu ubrizgaju putem JavaScript datoteka
nazvanih content scripts (hrv. skripte sadržaja). Content skripte mogu upravljati DOM-
om stranice, ali mogu i pristupati jednom dijelu Chrome API-ja, kao što je API za
komunikaciju s ekstenzijom, što će biti objašnjeno kasnije. Izvršavanje content skripti
odvija se u posebnoj okolini nazvanoj isolated world (hrv. izoliran svijet) [18]. Skripte
imaju pristup DOM-u stranice u koju su ubrizgane, ali ne i JavaScript varijablama ili
funkcijama stranice. Svaka skripta dobiva svoj izolirani svijet u kojem se izvršava, što
stvara prednost od izvršavanja funkcionalnosti skripte s korištenjem biblioteka različitih
verzija naspram onih koje se koriste u drugim content skriptama ili na stranici, bez brige
17
da bi se mogao stvoriti konflikt među tim skriptama. Sljedeća slika ilustrira koncept
izoliranih svjetova.
Slika 3.5 Izolirani svjetovi
No, HTML elementi koji su ubrizgani na stranicu dijele CSS sa stranicom i rukovatelje
događaja vezane uz te elemente. Neke su stranice onemogućavale ispravan rad
definiranih rukovatelja događaja na ubrizganim elementima, dok su neke stranice
globalno mijenjale stil pojedinih HTML elemenata, tako da su ubrizgani elementi pokupili
taj stil. Sljedeća slika pokazuje taj problem na jednoj od stranica, gdje izbornik izgleda
deformirano zbog nasljeđenog CSS sa stranice u koju je ubrizgan.
Slika 3.6 Deformiran izbornik
18
Zbog tih razloga, odlučio sam se koristiti HTML element <iframe>. Taj se HTML element
koristi kako bi, unutar trenutnog HTML dokumenta (web stranice), ugradio sadržaj
drugog HTML dokumenta. Taj ugrađeni sadržaj ignorira CSS stranice u koju je ugrađen,
već samo <iframe> element dijeli CSS sa tom stranicom, što se jednostavno može
očistiti (mogli su se i HTML elementi ugrađenog izbornika očistiti, ali njih je bilo puno
više te bi sam postupak oduzimao dosta vremena prilikom ponovnog ažuriranja
izbornika). Korištenjem <iframe> elementa, svi su problemi nestali. Sada ostaje riješiti
samo komunikaciju izbornika i content skripte, jer sada izbornik, koji je ugrađen unutar
<iframe> elementa, ne može direktno komunicirati sa content skriptom koja je ugrađena
u stranicu. Za to je iskorištena mogućnost komunikacije content skripta sa samom
ekstenzijom. Budući da se content skripte izvršavaju u kontekstu web stranica, a ne
ekstenzija, postoji način na koji ta dva entiteta komuniciraju. Komunikacija je
omogućena korištenjem message passinga (hrv. prolaženje poruka). Content skripta
može slati poruke ekstenziji korištenjem chrome.runtime.sendMessage i
chrome.runtime.onMessage mehanizama. Sljedeći isječak kôda prikazuje slanje poruke
s content skripte koja se nalazi u <iframe> elementu prema ekstenziji.
chrome.runtime.sendMessage({source: "iframe"}, function(response) {
console.log(response.msg); // povratna poruka
});
Ekstenzija na drugom kraju prima poruku i prosljeđuje ju content skripti koja se nalazi
unutar originalne stranice.
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.source == "iframe")
// slanje poruke
chrome.tabs.query({active: true, currentWindow: true},
function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, request,
function(response) {
console.log(response.msg);
});
});
}
);
19
Cijeli postupak ilustriran je sljedećim dijagramom slijeda.
3.7 Dijagram slijeda prolaženja poruka
Kada content skripta unutar originalne stranice zaprimi prosljjeđenu poruku od
ekstenzije, događaju se sljedeći koraci:
1. Transparentnom bloku, koji je korišten za prikaz trenutno aktivnog elementa,
ažurira se boja granice (eng. border), pozadinska boja i tekstura.
2. Taj se transparentni blok i označeni element spajaju jedinstvenim ključem koji se
u oba elementa uvrštava preko atributa data-oculi-extension-element-id6.
3. Označenom elementu se dodaje kategorija preko atributa data-oculi-extension-
type.
4. Sakriva se iframe.
5. Ubacuje se novi transparentni blok za označavanje elemenata.
Atribut data-oculi-extension-type može poprimiti posebnu vrijednosti za svaku od
kategorija koje se označavaju na stranici. Tako je za potkategoriju glavne navigacije
(eng. main navigation) kategorije navigacije vrijednost jednaka navigation-main, a za
potkategoriju kolekciju stavki (eng. item collection) kategorije stavki vrijednost jednaka
item-collection. Svaki gumb na izborniku ima svoju jedinstvenu vrijednost, čiji je sufiks
6 data-* atributi su novost u HTML5 i koriste za pohranu privatnih podataka stranice ili aplikacije.
20
upravo jedna od mogućih vrijednosti atributa data-oculi-extension-type. Taj se sufiks
prosljeđuje iz content skripte iframea do content skripte originalne stranice.
Odabir semantičkih elemenata se nastavlja sve dok se ne označi čitava stranica. Nakon
što je označena čitava stranica, potrebno je kliknuti na ikonicu same ekstenzije, gdje se
skočni prozor primijenio. Skočni prozor mijenja se na temelju stanja ekstenzije i stanja
preglednika. Na početku, ekstenzija se nalazi u pripravnom stanju i, neovisno o stanju
preglednika, skočni prozor izgleda kao na slici 3.4. Kada se počne označavati,
ekstenzija se nalazi u radnom stanju. Skočni prozor sada ovisi o stanju preglednika.
Ako je aktivna kartica (eng. tab) jednaka kartici na kojoj je ekstenzija počela označavati,
tada je skočni prozor jednak lijevoj strani sljedeće slike, a inače desnoj.
Slika 3.8 Skočni prozori različitog stanja preglednika
Jedno od stanja u kojem ste ekstenzija može naći je i onemogućeno stanje koje je
prikazano na sljedećoj slici.
Slika 3.9 Onemogućeno stanje ekstenzije
21
Onemogućeno stanje ne dozvoljava početak označavanja stranice, jer se korisnik ne
nalazi ni na jednoj učitanoj stranici. To je često slučaj kada korisnik tek otvori novu
karticu ili kada se nalazi na konfiguracijskim dijelovima svog preglednika, kao u
postavkama (eng. settings) što je i prikazano na prethodnoj slici.
Jednom kada je označavanje gotovo, stranica može izgleda kao što je prikazano na
sljedećoj slici.
Slika 3.10 Označena stranica
22
Odabirom slanja, njen se DOM potpuno šalje na stranicu Oculi7 poslužitelja. Uz slanje
DOM-a stranice poslužitelju, šalje se i .mhtml (MIME HTML) format stranice kako bi se
označavanje u potpunosti moglo što lakše rekonstruirati. Kvalitetno označene stranice
su preduvjet za smanjenje vjerojatnosti pojave šuma među podacima i točan rad
naučenog modela. Zbog toga se šalje .mhtml format stranice za koji je razvijen poseban
sustav provjere označivača. Označivač s dostatnim brojem označenih stranice se
ocjenjuje, te ako zadovoljava kriterij valjanosti označivača, njegove označene stranice
prelaze u repozitorij.
Zajednička veličina DOM stranice i .mhtml formata može biti i do 11 MB veličine, za što
je potrebno neko vrijeme da se prenese na poslužitelj. Zbog toga je napravljen dodatan
<iframe> element koji se ubacuje na stranicu i sadrži traku napretka (eng. progress
bar). Taj <iframe> element, jednako kao i već opisani, komunicira s ekstenzijom koja ga
izvješćuje o napretku prijenosa, nakon čega JavaScript unutar <iframe> elementa
ažurira stanje trake napretka. Na sljedećoj se slici može vidjeti jedan takav napredak
slanja podataka poslužitelju.
Slika 3.11 Progress bar slanja podataka
Kako bi se novi korisnici znali koristiti ekstenzijom, napravio sam stranicu opcija (eng.
options page) na kojoj se nalaze koraci koji se moraju provesti za označavanje i slanje
stranice na poslužitelj. Stranica opcija prikazana je na sljedećoj slici.
7 www.oculi.info, Oculi je podsustav za surfanje webom, bit će detaljnije objašnjen kasnije.
23
Slika 3.12 Stranica opcija
Cijeli kôd projekta ekstenzije je vrlo dokumentiran i sadrži puno razmaka. Te stvari
dobro je počistiti prije puštanja ekstenzije u produkciju, kako bi se datoteke što brže
učitavale, pogotovo kod slanja Ajax (Asynchronous JavaScript and XML) zahtjeva za
dohvaćanjem GUI elemenata koji se ugrađuju u stranicu. Za optimizaciju, iskorišten je
Grunt8, izvođač JavaScript zadataka, koji iz datoteke src (skraćeno za source, hrv.
izvor) moraju:
1. očistiti build (hrv. građa) datoteku, gdje se nalazi optimizirani programski kôd,
2. počistiti sve JavaScript datoteke: maknuti komentare, izbrisati praznine (eng.
whitespace), preimenovati lokalne varijable,
3. počistiti sve HTML datoteke na sličan način,
4. počistiti sve CSS datoteke na sličan način te
5. prekopirati JSON datoteke i slike u build datoteku.
Svi ovi zadaci i njihov redoslijed su zapisani u tzv. Gruntfile datoteci koja služi kao
konfiguracijska početna točka izvođenju zadataka. Skraćena Gruntfile datoteka s
detaljnom konfiguracijom zadataka čišćenja JavaScript datoteka nalazi se u sljedećem
programskom isječku.
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
8 http://gruntjs.com/
24
clean: {
//
},
uglify: {
options: {
mangle: true
},
build: {
files: [{
expand: true,
cwd: 'src/',
src: ['**/*.js', '!archive/**/*.js'],
dest: 'build/'
}]
}
},
htmlmin: {
//
},
cssmin: {
//
},
copy: {
//
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-htmlmin');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('default', ['clean', 'uglify', 'htmlmin',
'cssmin', 'copy']);
};
Izvođenje ovih zadataka pokreće se izvođenjem naredbe grunt unutar komandnog-
linijskog sučelja, CLI (eng. Command-Line Interface).
25
Dakle, ekstenzija za označavanje stranica rješava sve probleme pri izgradnji repozitorija
dovoljnog stupnja raznovrsnosti označenih podataka. Svaki ju korisnik Google Chrome
preglednika može skinuti na Chrome Web Storeu9.
3.2. Ekstrakcija značajki
Značajka (eng. feature) predstavlja obilježje promatranih podataka, a ekstrakcije
značajki označava proces pri kojem iz podataka izdvajamo obilježja koja će ih
razlikovati od ostalih. Važno je što potpunije obuhvatiti sva obilježja po kojima možemo
razlikovati podatke neke klase (ili neke vrijednosti) u odnosu na druge, jer je upravo
šum često razlog nepotpunosti skupa značajki, odnosno postojanja skrivenih značajki
(tzv. latentnih varijabli). Proces ekstrakcije značajki je najlakše započeti jednom kada
imamo podatke i kada ih možemo predočiti.
U strojnom učenju postoje 3 pristupa problemu učenja (skupine algoritama):
Nadzirano učenje (eng. supervised learning),
Nenadzirano učenje (eng. unsupervised learning) i
Podržano učenje (eng. reinforcement learning).
Nadzirano učenje označava skupinu algoritama koje primjenjujemo kada podaci, koje
imamo na raspolaganju za treniranje modela, imaju poznatu izlaznu (ciljnu) varijablu.
Postupcima nadziranog učenja mogu se rješavati dvije vrste problema: klasifikacija i
regresija [15]. Kod klasifikacije primjeru pridružujemo klasu (razred) kojoj taj primjer
pripada. Kod regresije primjeru pridružujemo neku kontinuiranu vrijednost. Razlika je
dakle u tome je li ciljna varijabla diskretna ili nominalna (klasifikacija) ili je kontinuirana
(regresija). Kod nadziranog učenja se čini kao da imamo nadzornika (eng. supervisor)
koji dodjeljuje klasu ili neku vrijednost ciljnoj varijabli, pa odatle i naziv nadziranom
učenju.
9 https://chrome.google.com/webstore/detail/oculi-semantic-extension/jlfhnffeknpcmjngplpomknpipdoccfp
26
Kod nenadzirano učenja, s druge strane, podaci nemaju izlaznu vrijednost. Iz tog
razloga, cilj je pokušati pronaći pravilnosti, odnosno strukturalne obrasce unutar
podataka.
U nekim primjenama, izlaz koje sustav daje je slijed akcija. U takvom slučaju, pojedina
akcija nije važna: važan je slijed točnih akcija koje daju rezultat. Ne postoji "najbolja
akcija" u danom međustanju. Akcija je dobra ako je dio dobrog slijeda. U takvim
situacijama, cilj je ocijeniti ispravnost slijeda akcija i učiti iz prošlih dobrih sljedova [13].
Kako ekstenzija za označavanje podataka dodjeljuje kategorije, odnosno klase
podacima unutar DOM-a stranice, dinamičko prepoznavanje dijelova stranica koristit će
algoritme nadziranog učenja. Klase koje će se označavati su unaprijed određene, ali se
prilikom treniranja podataka i korištenja ostavlja sloboda dodavanja određenih klasa.
3.2.1 Priprema podataka
Prije treniranja modela, podatke je potrebno očistiti. Čišćenje DOM-a stranica odvija se i
prije slanja DOM-a poslužitelju. Ekstenzija za označavanje prije slanja izbacuje sve
transparentne blokove koji nisu spojeni (ne dijele identifikacijski ključ preko atributa
data-oculi-extension-element-id) i izbacuje izbornik, odnosno <iframe> element koji ga
sadrži. Sve što stranice sadrže kada se šalju u javni repozitorij su transparentni blokovi
koji su s označenim elementom povezani atributom data-oculi-extension-element-id i
dodan atribut na označeni element koji označuje kategoriju.
Jednom dospjele stranice u repozitoriju dalje idu na čišćenje za spremanje na treniranje
modela. Daljnja razrada stranica i treniranje napravljeno je u IPython10 bilježnici (eng.
notebook) što predstavlja interaktivnu web računalnu okolinu gdje se pomoću Pythona i
LaTeXa11, visoko kvalitetnog sustava za slaganje slogova namijenjenog tehničkoj i
znanstvenoj dokumentaciji, mogu stvarati vrhunski dokumenti koji spajaju
dokumentaciju i programski kôd te omogućuju izvođenje kôda u sinergiji s
dokumentacijom. Cijeli programski paket IPython je uključen unutar Anaconde12,
10
http://ipython.org/ 11
http://www.latex-project.org/ 12
https://store.continuum.io/cshop/anaconda/
27
znanstvene distribucije Python programskog jezika. Anaconda uz IPython sadrži i
mnoge pakete za strojno učenje, kao što je i vrlo važan scikit learn13. Sljedeća slika
prikazuje isječak IPython bilježnice korištene za pripremu podataka.
Slika 3.13 Isječak i sučelje IPython bilježnice
Na slici se može vidjeti kako IPython bilježnicu nisam koristio kao izvor glavnog dijela
programskog kôda, već kao ljepilo Python modula i cjevovod podataka. IPython
bilježnice moraju biti dobro organizirane i sažete kako bi navigacija njima bila što
razumljivija.
Priprema podataka sastoji se od sljedećih koraka:
1. dohvaćanja stranica iz repozitorija i izdvajanja ih iz JSON (JavaScript Object
Notation) polja,
2. popravljanja HTML dokumenata,
3. čišćenja HTML dokumenata od nepotrebnih oznaka,
4. čišćenja HTML dokumenata od nepotrebnih elemenata iz označne ekstenzije,
5. čišćenja HTML dokumenata od nepotrebne strukture i
6. spremanja podataka u očišćeni repozitorij.
Popravljanje HTML dokumenata nužan je korak kako bi se prije stvarnog čišćenja
popravila struktura HTML dokumenata. Naime, HTML dokument je nerijetko loš
13
http://scikit-learn.org/
28
nepoštivanjem pravila strukturiranja, što je poduprto najvećim komercijalnim
preglednicima, koji će pokušati pokazati sve kako je programer zamislio. Tipičan primjer
lošeg HTML dokumenta nalazi se u sljedećem programskom isječku.
<html>
<head>
<title>Ovo je primjer lošeg HTML-a</title>
<body>
<h1>Loš HTML
<p>Paragraf
</body>
Mnoge biblioteke i moduli ne mogu obraditi loš HTML kôd. Zato je potrebno prethodno
popraviti HTML dokument. BeautifulSoup14 služi upravo tomu. BeautifulSoup je omotač
oko konkretnih parsera omogućujući tako korištenje više različitih parsera HTML
dokumenata, kao što su lxml, html5lib i html.parser. Zadnje navedeni parser je
Pythonov ugrađeni HTML parser koji sam ja koristio.
Jednom popravljeni HTML dokument može se koristiti za čišćenje. Prvo čišćenje miče
nepotrebne oznake unutar dokumenta. Za to čišćenje sam koristio paket lxml15 koja se
sastoji od mnogih modula za jednostavno procesuiranja XML i HTML dokumenata. lxml
također uključuje i druge poznate pakete kao što je ElementTree16 koji uključuje jedan
od najprihvaćenijih API-ja za pristup elementima unutar stabla.
Unutar lxml.html paketa nalazi se modul clean koji sadrži alate potrebne za očistiti
HTML dokument. Ovdje možemo pronaći Cleaner (hrv. čistač) klasu čijim je svojstvima
izloženo sučelje za prilagodbu čišćenja dokumenata. Tako možemo birati želimo li
izbrisati ubrizgan JavaScript kôd, komentare, CSS stilove, forme i koje oznake želimo
obrisati. Moj čistač naiješten je tako da se sve skripte, JavaScript elementi, komentari i
CSS stilovi brišu. Na početku sam brisao i oznake (ali ne i njihov sadržaj) koje služe
samo za formatiranje teksta, kao što su <b>, <big>, <em> i <i> kako bi oslobodio tekst,
ali to je pogrešno. Potrebno je što vjernije sačuvati čitavu stranicu i izbrisati samo one
oznake koje se kasnije neće koristiti u određivanju vrijednosti pojedinih značajki. Zbog
14
http://www.crummy.com/software/BeautifulSoup/ 15
http://lxml.de/ 16
http://effbot.org/zone/element-index.htm
29
toga će se te oznake ostaviti, a kada će se utvrditi klasa pojedinog atributa, onda će se
on naknadno moći počistiti od nepotrebnih oznaka kako bi se oslobodio tekst.
Sljedeće čišćenje koje slijedi je čišćenje HTML dokumenata od nepotrebnih elemenata
iz označne ekstenzije. Taj dio prikazan je slikom 3.11. iz IPython bilježnice. Iz dobivenih
stranica u tom dijelu cjevovoda, potrebno je počistiti transparentni blok kojeg
pronalazimo tako da ima data-oculi-extension-element-id atribut, a nema data-oculi-
extension-type atribut. Potrebno je obuhvatiti oba uvjeta, jer atribut data-oculi-extension-
element-id imaju i označeni elementi koji se ne smiju obrisati. Sve transparentne
blokove dohvaćamo XPathom17 (XML Path). ElementTree API dozvoljava da na
svakom elementu vršimo XPath izraze. Sljedeći programski isječak pokazuje kako prvo
dohvaćamo sve blokove, a zatim ih brišemo u odnosu na njihov roditelj, što je tipični
način brisanja u ElementTree API-ju.
for root in sites:
extensionBlocks = root.xpath('//*[@data-oculi-extension-
element-id][not(@data-oculi-extension-type)]')
for block in extensionBlocks:
block.getparent().remove(block)
Nakon toga, potrebno je počistiti i atribut data-oculi-extension-element-id s označenih
elemenata. Te elemente je sada lakše obuhvatiti, jer znamo da jedino oni imaju taj
atribut, no kako bi ta dva koraka bila neovisna o redoslijedu, u uvjet obuhvaćamo i
atribut data-oculi-extension-type, za što je prikazan sljedeći programski kôd.
for root in sites:
clickedElements = root.xpath('//*[@data-oculi-extension-element-
id][@data-oculi-extension-type]')
for element in clickedElements:
element.attrib.pop('data-oculi-extension-element-id')
Strukturalno čišćenje, kao i čišćenje nepotrebnih elemenata iz označne ekstenzije
odvija se u dva koraka:
1. čišćenja praznih elemenata i
2. čišćenja nepotrebne strukture.
17
XPath je upitni jezik za odabir čvorova unutar XML dokumenta.
30
Čišćenje praznih elemenata odvija se tako da se prvo selektiraju svi listovi koji su
prazni, a zatim se iteracijski napreduje prema gore, sve dok se dođe do roditelja koje ne
nastaje prazno nakon brisanja praznog djeteta. XPath za odabir svih praznih listova je
sljedeći:
leaves = self.root_element.xpath('//*[not(*)]')
Čišćenje nepotrebne strukture je ipak malo složenije. Oznake <div> i <span> su samo
strukturalne oznake HTML-a bez značajnijeg semantičkog značenja. To su tzv. grupne
oznake koje definiraju samo sekcije unutar dokumenta pri čemu je <div> zastupnik
block-level elemenata (hrv. elemenata blokovske razine), a <span> je zastupnik inline
elemenata (hrv. elemenata u liniji). Block-level elementi zauzimaju cijeli prostor svog
roditelja pri čemu kreiraju blok [19], dok inline elementi zauzimaju onoliko koliko trebaju.
Moja prva razmišljanja kretala su se u smjeru kako bi što više nepotrebne strukture
trebalo odmah očistiti iz stranica repozitorija, što će u učenju uključivati manje
nepotrebnih podataka. Strukturalne elemente bi mogli čistiti bilo kako, znajući iz
označenih podataka po preostalom atributu data-oculi-extension-type koji se elementi
ne smiju očistiti. No, to se ne smije dozvoliti! Razlog tome je što pri korištenju svih
algoritama strojnog učenja mora vrijediti sljedeća pretpostavka: svi primjeri iz prostora
primjera moraju biti uzorkovani nezavisno i iz iste zajedničke distribucije. Ta se
pretpostavka skraćeno piše iid. Upravo zbog te pretpostavke, bilo bi pogrešno pri
čišćenju strukturalno jako promijeniti dokument mičući nepotrebnu strukturu, znajući
koje strukturalne oznake <div> i <span> moraju ostati zbog atributa data-oculi-
extension-type. No, pri klasifikaciji novih stranica, mi nećemo znati koje strukturalne
elemente ne smijemo micati, te bismo ih ovih načinom izbacili iz DOM-a stranice što bi
značilo da podaci ne potječu iz iste zajedničke distribucije.
Zbog toga sam se odlučio na jednostavnije čišćenje nepotrebne strukture sadržanog u
čišćenju onih strukturalni elemenata koji imaju jednaku oznaku kao i roditelj i čiji roditelj
ima samo njih kao element dijete. Sljedeći programski isječak pokazuje upravu tu
funkcionalnost.
from copy import deepcopy
31
def remove_parent_single_child(self, tag):
div_parents = self.root_element.xpath('//{0}[{0}]'.format(tag))
for outer_e in reversed(div_parents):
if len(outer_e.getchildren()) == 1:
inner_e = outer_e[0]
if 'data-oculi-extension-type' in inner_e.keys():
if 'data-oculi-extension-type' in outer_e.keys():
raise NameError('Wrongly labeled site!')
else:
outer_e.set('data-oculi-extension-type',
inner_e.get('data-oculi-extension-type'))
for e in inner_e:
outer_e.append(deepcopy(e))
outer_e.text = outer_e.text + inner_e.text + inner_e.tail
outer_e.remove(inner_e)
U programskom se isječku se prvo može vidjeti da listi, koju dobijemo evaluacijom
XPath izraza, trebamo obrnuti redoslijed kako bismo kretali prvo odozdo prema gore.
Na taj se način neće moći dogoditi da se prvo obriše neko dijete koje je i samo roditelj
jednom djetetu jednake oznake. To se dijete nalazi također u listi roditelja s jednim
djetetom, ali bi se obrisalo, te bi došlo do problema kada bi se iteracijski došlo na
njegovo mjesto. Druga stvar koju valja napomenuti je da se ne dozvoljava gniježđenje
kategorija. Odnosno, klase su zasada definirane disjunktno, te se navigacija ne može
pronaći unutar stavke. Teoretski je moguće da će se unutar neke stavke, npr. članka,
nađe neka navigacijska lista, ali će se ona protumačiti upravo kao lista unutar te stavke,
a ne kao nezavisna navigacijska lista za koju postoji predodređena klasa. Time se
uvelike olakšava proces organiziranog označavanja stranica.
Ovim čišćenjem završava proces sveukupnog popravljanja i čišćenja stranica koji se
ponavlja po svim stranicama. Može se vidjeti kako je samo čišćenje dosta zamršeno i
kako je potrebno osigurati da taj proces bude izveden ispravno. Upravo sam se zato
prilikom svih koraka čišćenja vodio testovima upravljanim razvojem (eng. Test Driven
Development, TDD). Testovima upravljan razvoj je razvojni proces koji se zasniva na
ponavljanju kratko razvojnog ciklusa:
1. Napiši test koji ne prolazi.
32
2. Napiši minimalni programski isječak koji će omogućiti zadovoljavanje testa.
3. Refaktoriraj programski isječak.
Ovaj razvojni proces odgovara na pitanja kada i kako testirati, a kao odgovor na pitanje
što testirati, koristio sam testiranje cjelina (eng. unit testing) pomoću unittest modula u
Pythonu18. Svaka klasa, odnosno svaki čistač ima svoju testnu cjelinu, pri čemu testna
cjelina ima više ispitnih slučajeva (eng test case). Za svaki ispitni slučaj sam kreirao i po
2 HTML dokumenta: neočišćeni i očekivano očišćeni.
Za brisanje praznih elemenata, neočišćeni HTML dokument ima sljedeći izgled.
<html>
<head></head>
<body>
<div id="container">
<div id="title">Bok</div>
<div class="container">nesto</div>
<div class="footer">
<div class="tags"></div>
<div class="links">
</div>
</div>
<div class="contact">
<div class="city">Zagreb</div>
<div class="address"></div>
Address
</div>
<div class="findus">
<div class="social"></div>
</div>
</div>
</body>
</html>
Ovim neočišćenim HTML dokumentom pokrivamo 5 brisanja:
1. praznog elementa; atribut class vrijednosti tags,
2. elementa samo s prazninama; atribut class vrijednosti links,
3. elementa koji postaje prazan nakon što mu se obrišu prazna djeca; atribut class
vrijednosti footer,
18
https://docs.python.org/2/library/unittest.html
33
4. elementa koji ima tekst u svojstvu tailu19 (hrv. rep) i prebacivanje tog taila
prethodnom dijetetu; atribut class vrijednosti address te
5. elementa koji ima tekst u svojstvu tailu i prebacivanje tog taila u roditeljevo
svojstvo text20; atribut class vrijednosti social.
Konačan rezultat je sljedeći:
<html>
<head></head>
<body>
<div id="container">
<div id="title">Bok</div>
<div class="container">nesto</div>
<div class="contact">
<div class="city">Zagreb</div>
Address
</div>
<div class="findus">
</div>
</div>
</body>
</html>
Prije same ekstrakcije značajki, važno je imati pripremljen repozitorij označenih
podataka, jer se značajke puno lakše mogu iščitati analizirajući označene podatke. Za
tu svrhu sam samostalno generirao repozitorij pomoću 10 označenih WordPress21, kako
bi prije javnog reklamiranja ekstenzije za označavanje dokazao da cijeli koncept uistinu
radi. Odlučio sam se označiti popularne WordPress stranice (one koje su mi bile
predložene kao popularne i najčitanije), jer WordPressov CMS alat kreira stranice slične
strukture bez obzira na temu koja se koristi. Također, primarni fokus razrade ovog
modela je semantička segmentacija stranica čime se implicira na statičke stranice
čiji su semantički dijelovi vidljivi iz njihovog prvotnog DOM-a. Semantika
dinamičkog ponašanja stranice i upravljanja DOM-a je izvan dosega semantičke
segmentacije ovog modela, tako da su WordPress stranice, kao pretežno statične
nakupine članaka, izvrsni izvor prikladnih stranica za treniranje.
19
Tail je svojstvo elementa iz ElementTree API-ja koji predstavlja tekst direktno iza zatvarajuće oznake. 20
Text je svojstvo elementa iz ElementTree API-ja koji predstavlja tekst unutar oznake do prvog djeteta. 21
WordPress, https://wordpress.org/, je CMS (Content Management System) alat s namjerom pojednostavljenja pisanja bloga.
34
3.2.2 Ekstrakcija značajki za kategorije navigacije
Jednom očišćen i pripremljen repozitorij koristi se za treniranje modela klasifikacije
semantičkih kategorija dijelova stranica. Tri su kategorije za navigaciju koje se razlikuju
po vrijednosti atributa data-oculi-extension-type na označenim podacima:
glavna navigacija s vrijednošću navigation-main,
sporedna navigacija s vrijednošću navigation-sub i
lokalna navigacija s vrijednošću navigation-local.
Glavna navigacija predstavlja glavnu polaznu točku navigacije na nekoj stranici
definiranoj domenom. Ona tipično sadrži elemente kao što su "Početna stranica", "O
nama", "Kontakt" i ostale specifične navigacijske elemente. Ta navigacija mora
sadržavati poveznice koje pokazuju na stranicu iste domene. Sporedna navigacija
također sadržava poveznice koje pokazuju na stranicu iste domene, ali po sadržaju ne
predstavlja glavnu polaznu točku navigacije. Tipični primjeri sporedne navigacije mogu
se pronaći na blogovima gdje se prikazuju liste članaka po određenim mjesecima,
najpopularniji članci ili pretraživanje po određenim kategorijama, odnosno oznakama
(eng. tag) na raznim portalima. Lokalna navigacija najviše se razlikuje od dosad
predstavljenih navigacija. Ona ne sadrži poveznice koje pokazuju na druge HTML
dokumente unutar stranice definirane domenom, već poveznice koje pokazuju na
pojedini fragment unutar samog HTML dokumenta. One se tipično pojavljuju na raznim
dokumentacijskim statičnim stranicama koje objašnjavaju korištenje gledanog alata,
API-ja, programa ili bilo čega drugog.
Ekstrakcija značajki je obilježena dvama procesima:
uočiti zajedničku i specifičnu strukturno - sadržajnu komponentu među podacima
nad kojima se radi ekstrakcija (podatke pojedine klase) te
uočiti zajedničku strukturno - sadržajnu komponentu koja razlikuje podatke
pojedine klase i ostale podatke.
Za jednu od popularnih stranica uzeo sam i stranicu Sci-Fi Interfaces22 čiji se glavni
izbornik prikazan na sljedećoj slici, označen označnom ekstenzijom.
22
https://scifiinterfaces.wordpress.com/
35
Slika 3.14 Prikaz glavnog izbornika stranice Sci-Fi Interfaces
DOM reprezentacija stabla glavnog izbornika djelomično je prikazana sljedećim
programskim isječkom.
<aside class="widget widget_pages" id="pages-3">
<h1 class="widget-title">GET THE BOOK</h1>
<ul>
<li class="page_item page-item-383">
<a href="https://scifiinterfaces.wordpress.com/how-to-pre-order/">
How to Order
</a>
</li>
<li class="page_item page-item-285">
<a href="https://scifiinterfaces.wordpress.com/book/">
About the book
</a>
</li>
<li class="page_item page-item-2">
...
</li>
...
</ul>
</aside>
36
DOM reprezentacija je ključna za ekstrakciju značajki. Analizirajući DOM reprezentacija
stabala glavnih izbornika označenih WordPress stranica, ekstrakcijom sam dobio
sljedeće značajke:
Značajka pojavljivanje poveznice: provjerava pojavljivanje oznake <a> u
navigacijskom stablu; vrijednosti iz skupa {0, 1}. Cilj značajke je da se
jednostavno odvoje stabala elemenata koji nisu navigacijski, jer svi tipovi
navigacije moraju sadržavati oznaku poveznice.
Značajka omjer oznaka poveznica: računa omjer koliko se puta pojavljuje oznaka
<a> naspram svih oznaka; vrijednosti iz intervala [0,1]. Cilj značajke je da se
odvoje stabla elemenata koji sadržavaju mnogo strukturalnih elemenata naspram
poveznica, jer su navigacijska stabla češće jezgrovitija.
Značajka potpunost izbornika: provjerava sadrži li izbornik <li> oznake te je li
svaka od tih oznaka obuhvaćena <ul> oznakom koja se nalazi u istom
navigacijskom stablu; vrijednosti iz skupa {0, 1, 2}: 0 - izbornik ne sadrži <li>
oznake; 1 - izbornik sadrži <li> oznake, ali neke od tih oznaka ne sadrže <ul>
oznaku unutar gledanog stabla, odnosno stablo je nepotpuni izbornik; 2 - izbornik
je potpun. Navigacijska stabla češće sadrže strukturalne konstrukte kao što su
oznake <ul> i <li> te u tom slučaju izbornik mora biti potpun. Ova značajka na
jednostavan način odvaja djecu pravog navigacijskog stabla koji bi bez ove
značajke mogli biti proglašeni kao valjano navigacijsko stablo.
Značajka omjer oznaka izbornika: računa omjer koliko se puta pojavljuju oznake
izbornika naspram svih oznaka; vrijednosti iz intervala [0, 1]. Oznake izbornika
predstavljaju HTML oznake koje neupitno ukazuju na navigacijsko stablo. Osim
već spomenutih <ul>, <li> i <a> oznaka, tu se nalaze i HTML5 oznake veće
semantičke vrijednosti kao što su <nav>, <aside>, <menu>, <menuitem>,
<option> i <optgroup>. U slučaju korištenja HTML 5 oznaka, biti će lakše
razaznati navigacijsko stablo.
Značajka prosječna duljina pojedinačnih tekstova: računa prosječnu duljinu svih
tekstova koji se pojavljuju u već spomenutim text i tail svojstvima ElementTree
API-ja gdje računa njihovu duljinu; vrijednosti iz intervala [0, ∞>. Pojedini članci
mogu sadržavati različita stabala lista s dugim tekstovima i poveznicama na
37
druge stranice čime bi oni bili proglašeni. Upravo da bi se takvi elementi
razdvojili, služi ova značajka, jer su navigacijski pojedinačni tekstovi puno
jezgrovitiji.
Značajka postotak pojave oznake stabla izbornika unutar cijele stranice: računa
postotak određen pozicijom pojave oznake stabla, odnosno DOM-a
navigacijskog stabla unutar DOM-a cijele stranice; vrijednosti iz intervala [0, 1].
Navigacijska stabla se uglavnom nalaze na samom početku stranice ili na
samom kraju stranice, tako da se ovime eliminiraju elementi na drugim
pozicijama.
Značajka postotak odlaznih poveznica: računa postotak poveznica koje ne vode
na neki fragment unutar stranice ili koje ne vode na neki resurs koji se nalazi na
stranice iste domene; vrijednosti iz intervala [0, 1]. Ova značajka odvaja liste s
poveznicama na druge stranice od svih tipova navigacijskih stabala.
Predstavljene značajke su zajedničke koji svi tipovi navigacija dijele. Kako bi se
pojedini tipovi mogli razlikovati, uvodimo dodatne značajke:
Značajka omjer poveznica koje vode na fragmente: računa omjer koliko
poveznica vodi na neki fragment unutar cijelog HTML dokumenta; vrijednosti iz
intervala [0, 1]. Ova značajka ima namjeru odvojiti lokalnu navigaciju od ostalih
dva tipa navigacije.
Značajka sadržajna analiza elementa: analizira tekstualni sadržaj elemenata koji
se gleda; vrijednosti iz intervala [0, 1]. Ako je tekstualni sadržaj sadrži riječi koje
su tipične za glavnu navigaciju, kao što su već navedeni dijelovi "Početna", "O
nama", "Kontakt", "Forum" itd., tada će rezultat ove značajke biti bliži vrijednosti
1. Treba biti oprezan s ovom značajkom, jer se sadržajno analiziranje mora
provoditi unutar domene jezika pojedine stranice, tako da se prije te značajke
definitivno mora otkriti jezik stranice. Zbog ove značajke treba biti oprezn s
čišćenjem pojedinih atributa i oznaka HTML dokumenta. Prema W3C preporuci
za definiranje jezika tekstualnog sadržaja HTML dokumenta [20], postoje dva
načina kako se može odrediti jezik tekstualnog sadržaja:
o postavljanjem lang atributa na html element, npr: <html lang="fr"> ili
38
o postavljanjem HTTP zaglavlja odgovora (eng. HTTP response header)
Content language koji može poprimiti listu zarezom odvojenih jezika.
Zbog ove značajke, ova će se dva načina morati uzeti u obzir pri čišćenju HTML
dokumenata i analiziranju HTTP zaglavlja odgovora stranice.
Također, kao značajka koja razlikuje sporednu navigaciju od ostalih navigacija, može se
uzeti i značajka postotak pojave oznake stabala izbornika unutar cijele stranice, koja je
definirana prije. Glavna i lokalna navigacija imaju tendenciju pojavljivanja na samom
početku HTML dokumenta, dok se sporedna navigacija uglavnom nalazi negdje u
sredini HTML dokumenta, između pojedinih stavaka. Ako se ustanovi da strukturalno
element odgovara navigaciji, a sadržajno sporednoj navigaciji, ta bi značajka igrala
ključnu igru u klasifikaciji same navigacije.
Mnoge značajke diktiraju pripremu i čišćenje HTML dokumenata prije klasifikacije.
Značajka sadržajna analiza elemenata samo je jedna od njih zbog koje sam morao
naknadno prilagoditi čišćenje HTML dokumenata, kako bi se te značajke mogle
iskoristiti.
Pri gradnji modela, odnosno ekstrakciji značajki, za svaku sam kategoriju gradio
posebnu klasu instance i klasu procjenitelja značajki (eng. feature evaluator). Takav
pristup jednostavniji je na početku, nego sve značajke natrpati zajedno i omogućava
samostalniju provjeru kvalitete značajki. Tako klasa instance za glavnu navigaciju sadrži
svojstva za sve značajke, a procjenitelj značajki računa vrijednost svake od tih značajki
temeljem DOM-a elemenata. Sljedeći programski isječak prikazuje klasu instance.
class Instance:
def __init__(self, eTag, eWebsiteRoot):
self.eTag = eTag
self.eWebsiteRoot = eWebsiteRoot
# Vrijednosti značajki
self.fMenuTotality = None
# ... ostale značajke
Sljedeći programski isječak prikazuje izračun značajke potpunosti izbornika unutar
procjenitelja značajki.
class FeatureEvaluator:
def __init__(self, menu_tags):
39
self.MENU_TAGS = menu_tags
self.instance = None
# ... izračun ostalih značajki
def calcMenuTotality(self):
eNavigation = self.instance.eTag
eLIs = eNavigation.xpath('.//li')
eULs = eNavigation.xpath('.//ul')
if (eNavigation.tag == 'li'):
eLIs.insert(0, eNavigation)
elif (eNavigation.tag == 'ul'):
eULs.insert(0, eNavigation)
if len(eLIs) == 0:
return 0 # Izbornik bez <li> elemenata
else:
for eLI in eLIs:
currE = eLI.getparent()
while (currE is not None and currE.tag != 'ul'):
currE = currE.getparent()
# Ako roditelj <ul> nije unutar gledanog stabla
if (currE is None) or not (currE in eULs):
return 1 # Nepotpuni izbornik
return 2 # Potpun izbornik
Rezultati koje sam dobio za glavnu navigaciju definiranu na slici 3.12 su sljedeći:
Značajka pojavljivanje poveznice: 1
Značajka omjer oznaka poveznica: 0.40909
Značajka potpunosti izbornika: 2
Značajka omjer oznaka izbornika: 0.9545
Značajka prosječna duljina pojedinačnih tekstova: 10.72727
Značajka postotak pojave oznake stabla izbornika unutar cijele stranice: 0.01232
Značajka postotak odlaznih poveznica: 0
Ovi rezultati su dosta tipični za ovakve tipove stabala glavnih navigacija. Dobivene
instance s izračunatim vrijednostima značajka predstavljaju pozitivne klase, jer ćemo pri
prvoj klasifikaciji klasificirati sve elemente pokušavajući utvrditi je li pojedini element
stablo glavne navigacije. Kako bi klasifikacija bila uspješna, potrebno je imati i primjere
negativnih klasa. Svi ostali elementi koji nisu klasificirani kao elementi glavne navigacije
40
i oni koji se nalaze unutar stabla glavne navigacije predstavljaju primjere negativnih
klasa. Zbog toga sam ja izvukao primjere negativnih klasa iz postojećih označenih
stranica definirajući postotak njihove pozicije unutar HTML dokumenta, a zatim sam ih
ručno ispisao i izbacio one koji su suviše nalik glavnoj navigaciji. Razlog zašto sam
ručno izbacivao loše primjere negativnih klasa, iako sam automatski mogao izdvojiti sve
negativne klase znajući točno koji elementi u označenim stranicama predstavljaju
glavne navigacije, jest taj da nisam želio da primjeri negativnih klasa budu previše slični,
jer bi time model postao prenaučen trenutnim podacima. Također, ponekad nije
pogrešno označiti i dio oko same liste poveznica u navigaciji. U HTML-u primjera sa
slike 3.12. može se vidjeti kako je označena cijela <aside> oznaka. U njoj se nalazi i
naslov same navigacijske liste "GET THE BOOK". U ovom slučaju, ispravnije je
obuhvatiti i taj naslov, jer bi u slučaju da se dinamički model koristi za aplikaciju za
surfanje slijepim i slabovidnim osobama, bilo poželjno pročitati i naslov navigacijske liste
kako bi tu navigacijsku listu stavili u kontekst stranice. No, kada bi se prije navigacije
nalazio naziv stranice, bilo bi pogrešno uključiti i njega. Upravo zbog tih subjektivnih
granica, bolje je isključiti previše slične elemente navigacijskim listama, jer bi moglo
nastati previše šuma u podacima za učenje.
Uzimao sam po 7 primjera negativnih klasa iz svake označene stranice kako ne bi
negativnih klasa bilo previše. Sljedeći programski isječak prikazuje način izdvajanja
negativnih klasa iz označenih stranica.
tagPercentages = [0, 15, 30, 45, 67, 80, 95];
eNegativeTagsPerPage = []
for eRoot in eWebsiteRoots:
eAllTags = eRoot.xpath('//*');
nTags = len(eAllTags)
websiteNegativeClasses = []
for percent in tagPercentages:
index = int(round(percent / float(100) * nTags));
websiteNegativeClasses.append(eAllTags[index])
eNegativeTagsPerPage.append(websiteNegativeClasses)
# Brisanje sličnih elemenata glavnim navigacijama
del eNegativeTagsPerPage[1][6]
41
del eNegativeTagsPerPage[4][6]
Tipični rezultati čitave stranice, što predstavlja prvi primjer kod svake označene stranice
postotkom 0 ima sljedeće rezultate:
Značajka pojavljivanje poveznice: 1
Značajka omjer oznaka poveznica: 0.207
Značajka potpunosti izbornika: 2
Značajka omjer oznaka izbornika: 0.337
Značajka prosječna duljina pojedinačnih tekstova: 153.748
Značajka postotak pojave oznake stabla izbornika unutar cijele stranice: 0
Značajka postotak odlaznih poveznica: 0.1063
Može se primijetiti kako neke bi gledajući samo neke značajke mogli zaključiti da se radi
o izborniku (npr. značajka potpunosti izbornika i značajka pojavljivanje poveznice), no te
će značajke odigrati važnu ulogu pri klasifikaciji kod drugih scenarija.
3.2.3 Ekstrakcija značajki za kategorije stavki
Kao što je već navedeno prije, stavke predstavljaju općenit element koji je specifičan za
pojedinu stranicu: na blogovima to su npr. članci. Tri su kategorije koje označivač može
označiti koristeći ekstenziju za označavanje:
pojedina stavka s vrijednošću item-singular,
kolekcija stavki s vrijednošću item-collection i
stavka dodaci s vrijednošću item-extras.
Iz ove tri kategorije koje se označavaju, jedino item-singular i item-extras služe kao
stvarne klase koje će poslužiti pri klasifikaciji. Kolekcija značajki zamišljena je kao
kategorija koja pomaže programerima da označe više stavki s jednakom strukturom.
Tipično su to kolekcije članaka na blogovima i portalima koji se nalaze jedan do drugih.
Sljedeća slika prikazuje jednu takvu kolekciju stavki.
42
Slika 3.15 Kolekcija stavki s portala
Prvotno sam krenuo bez kategorije kolekcije stavki u označnoj ekstenziji jer sam mislio
da su mi ti podaci nepotrebni i da nije potrebno više puta označavati stavke u pojedinoj
kolekciji, nego da je potrebno samo označiti po jednu stavku iz pojedine kolekcije. Time
sam mislio da se izbjegava nepotrebno ponavljanje istih struktura stavki i nametanje tih
struktura kao točnijih i poželjnijih unutar klasifikacijskog modela. No, iako strukturalno
iste, stavke u kolekciji se razlikuju pozicijom i sadržajem. Te će razlike imati pravi značaj
kada se u klasifikacijski model uključi sve značajke koje su se koristile za binarnu
klasifikaciju po pojedinih klasifikacijama. Upravo sam to tada i shvatio, jer kada nisam
radio s kolekcijama stavki, tada su za članke blogova pozicije stavki bile vrlo blizu
početka HTML dokumenta i klasifikacija nije dobro radila.
Problem koji se stvara uvođenjem kolekcija stavki jest izdvajanje stavki iz kolekcija. Za
tu sam svrhu izgradio povezivanje Python modul koji uspoređuje strukturalnu
podudarnost pojedinih stabala do određene razine. Strukturalna podudarnost
uspoređuje se analiziranjem pojava i redoslijeda oznaka pojedine razine i njihovih klasa
(HTML atribut class koji ukazuje na njihovu CSS povezanost). Sljedeći programski
isječak pokazuje kako se uspoređuje strukturalna podudarnost do druge razine, koja
obuhvaća trenutno gledani element, njihovu djecu i djecu njihove djece.
def level_one_matching(e1, e2, needToHaveChildren = True):
CLASS_MATCH_RATIO_THRESHOLD = 0.8
# Nepodudarnost, ako oznake promatranih elemenata nisu jednake
if e1.tag != e2.tag
return 0
# Sada analiziramo djecu
children1 = e1.getchildren()
children2 = e2.getchildren()
43
# Za svako dijete provjeri sadrzavaju li iste oznake
# i izračunaj podudarnost klasa
if classMatchRatio >= CLASS_MATCH_RATIO_THRESHOLD:
return 1
else:
return 0
def level_two_matching(e1, e2):
if level_one_matching(e1, e2) == 1:
# Ako se elementi podudaraju u prvoj razini, provjeri podudaraju
# li se i u drugoj razini. Ako se sva djeca podudaraju u prvoj
# razini, vrati 1, inače vrati 0.
else:
return 0
def class_matching_ratio(e1, e2):
classValue1 = e1.get('class')
classValue2 = e2.get('class')
# Razdvoji vrijednosti unutar class atributa
classUnion = classSet1.union(classSet2)
# + zaglađivanje
return (len(set.intersection(*[classSet1, classSet2])) + 1) /
float(len(classUnion) + 1)
Konstanta podudarnosti klasa CLASS_MATCH_RATION_THRESHOLD koja iznosi 0.8
određena je heuristički pregledom segmentiranja kolekcije stavki. Ponekad neke stavke
nemaju drugu razinu i zbog toga služi argument u funkciji needToHaveChildren koji se
pri ispitivanju druge razine postavlja na False. Definiranjem ovakvog algoritma provjere
strukturalne podudarnosti omogućava korištenje kolekcije stavki kao kategorije pri
označavanju i garantira točnije i potpunije podatke za učenje.
Nakon što sam uspio segmentirati kolekciju stavki, krenuo sam s ekstrakcijom
zajedničkih značajki za pojedinu stavke i stavke dodatke. Prije ekstrakcije značajki
potrebno je analizirati podatke koje je potrebno dobiti ekstrakcijom. Sljedeći programski
isječak prikazuje strukturu i približni sadržaj stavke prikazane na slici 3.14.
<article id="post-7847" class="post-7847 post type-post status-
publish format-standard hentry category-site-news">
<header class="entry-header">
<h1 class="entry-title"><a href="..." rel="bookmark">Social stuff
44
</a></h1>
<div class="entry-meta"><!-- Podaci o datumu i autoru: 26 May
2015 BY Christopher Noessel -->
</div>
<p class="comments-link"><a href="..."><span class="no-
reply">0</span></a></p>
</header><!-- .entry-header -->
<div class="entry-content">
<p>Four quick things to note.</p>
<p>A reader pointed out that I had buried <strong>social media
links</strong>. So now find links to <!-- ostali sadržaj --></p>
</div><!-- .entry-content -->
<footer class="entry-meta">
<span class="cat-links">Posted in <a href="..." rel="category
tag">~ Site news</a>. </span>
</footer><!-- #entry-meta -->
</article>
Slika 3.16 Stavka
Zajedničke značajke koje sam uspio izdvojiti su sljedeće:
Značajka oznaka stavke: provjerava je li oznaka promatranog elementa oznaka
stavke; vrijednosti iz skupa {0, 1}. Pri ekstrakciji značajki za stavke analizirao
45
sam sve moguće HTML oznake23 i tako zaključio da jedino nove semantičke
oznake <article> i <section> jedinstveno i sigurno označavaju stavku.
Značajka omjer duljine teksta: računa omjer duljine teksta naspram duljine teksta
u cijelom HTML dokumentu; vrijednosti iz intervala [0, 1]. Cilj ove značajke je
odvojiti prekratke i samostalne oznake od mogućeg klasificiranja u stavke.
Značajka omjer oznaka koji naznačuju stavku: računa omjer oznaka koje se
uglavnom pojavljuju unutar stavke, a ne kod drugih klasa; vrijednost iz intervala
[0, 1]. Ovime, iako se oznake <li> i <ul> pojavljuju unutar stavki, one se ne
računaju, jer se ne pojavljuju samo unutar stavki. Te su oznake sadržane u
sljedećem programskom isječku.
PROBABLY_CONTAINS_TAGS = ['abbr', 'area', 'audio', 'bdi', 'bdo',
'blockquote', 'br', 'canvas', 'caption', 'cite', 'code', 'col',
'colgroup', 'dd', 'del' 'details', 'dfn', 'dl', 'dt', 'em', 'embed',
'figcaption', 'figure', 'footer', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
'header', 'i', 'img', 'ins', 'kbd', 'map', 'mark', 'meter', 'object',
'ol', 'p', 'param', 'pre', 'q', 's', 'samp', 'small', 'source',
'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th',
'thead', 'tr', 'track', 'u', 'var', 'video', 'wbr']
Značajka oznaka koja nije stavka: provjerava je li oznaka promatranog elementa
oznaka koja zasigurno nije stavka; vrijednosti iz skupa {0, 1}. Oznake koje
sigurno nisu stavke su sljedeće: <title>, <meta>, <html>, <head>, <base>,
<link>, <script>, <style>. Ako je vrijednost 1, onda sa sigurnošću možemo znati
da promatrani element sigurno nije stavka. S obzirom na to da je sigurno da
prikazane oznake sigurno ne predstavljaju stavke, moguće je i ovu značajku
ukloniti i ne klasificirati one elemente koji sadržavaju tu oznaku. No, pošto će se
sve značajke zajedno koristiti pri višeklasnoj klasifikaciji, potrebno je uzeti ovu
značajku unutra, jer će elementi s tim oznakama možda biti klasificirani kao
primjeri drugih klasa.
Značajka broj podudaranja do 1. razine: provjerava koliko se elemenata unutar
HTML dokumenta podudara s promatranim elementom u strukturi do 1. razine
(krećući od 0.) uključujući class atribute; vrijednosti iz intervala [0, ∞>. Ova
značajka služi kraćim stavkama, čime će one dobiti neku ne preveliku vrijednost.
23
http://www.w3schools.com/tags/
46
Značajka broj podudaranja do 2. razine: provjerava koliko se elementa unutar
HTML dokumenta podudara s promatranim elementom u strukturi do 2. razine
uključujući class atribute; vrijednosti iz intervala [0, ∞>. Ova značajka služi
bogatijim stavkama u strukturi, te će bilo koja vrijednost različita od nule
poprilično sigurno opisivati stavku.
Značajka oznaka koja vjerojatno nije stavka: provjerava je li vjerojatno da oznaka
promatranog elementa gotovo sigurno nije stavka; vrijednosti iz skupa {0, 1}. Ova
značajka omogućuje odvajanje značajke oznaka koja nije stavka koja izdvaja one
oznake za koje smo potpuno sigurni da ne mogu biti stavke i onih oznaka za koje
je vrlo mala vjerojatnost da predstavljaju stavku. U tu svrhu, oznakama koje su
vrlo vjerojatno sadržane unutar stavki, koje su pokrivene značajkom omjer
oznaka koje naznačuju stavku, nadodali smo i ostale oznake koje su specifične
za druge klase. Tako smo došli do skupa sljedećih oznaka:
PROBABLY_NOT_ITEM_TAGS = PROBABLY_CONTAINS_TAGS +
['a', 'aside', 'button', 'datalist', 'fieldlist', 'form', 'hr',
'input', 'keygen', 'label', 'legend', 'li', 'menu', 'menuitem',
'nav', 'optgroup', 'option', 'output', 'select', 'summary',
'textarea'];
Predstavljene značajke su zajedničke koje odjeljuju potklase pojedine stavke i stavke
dodatke od ostalih potklasa. Kako bi se te dvije klase stavki mogle razdvojiti, potrebno
je napraviti dodatne značajke. No, klasifikacija ovih potklasa nije jednostavna kao što je
to bilo kod potklasa navigacija. Pojedinačne stavke vezane su za glavni sadržaj
stranice. Da bi se dvije potklase razdvojile, prvo se mora ustanoviti glavni sadržaj
stranice, odnosno kategorija sadržaja. Tek je onda moguće koristiti značajku koja će na
temelju sadržaja teksta unutar podstabla gledane instance odlučiti radi li se o potklasi
pojedinačne stavke ili stavke dodatka.
3.2.4 Ekstrakcija značajki za kategoriju formi
Forme predstavljaju elemente koji dozvoljavaju korisnicima unašanje podataka koji će
se poslati web poslužitelju na daljnje procesuiranje. Kao što je već prije napomenuto, cilj
semantičkog segmentiranja stranica je omogućiti dinamičko prepoznavanje dijelova
47
statičkih stranica, odnosno onih dijelova koji su vidljivi statičkim prikazivanjem stranice.
Razlog tomu je nemogućnost ekstrakcije semantičkog značenja dinamičkog ponašanja
na stranicama. Zbog toga, kao elementi kroz koje korisnici mogu unositi podatke i na
koje će se Oculi agenti, tj. oni programi koji koriste dinamički model prepoznavanja
stranica, moći osloniti su forme.
Generiran repozitorij WordPress stranica nema reprezentativne forme, tako da sam za
ekstrakcije značajki kategorije formi generirao novi repozitorij samo s podacima
ključnima za ekstrakciju značajki. Tipična forma koja mora moći biti dinamički
segmentirana je prikazana na sljedećoj slici.
Slika 3.17 Tipična instanca kategorije forme24
Prikazana forma opisana je sljedećim programskim isječkom, pri čemu su pojedini
elementi izbrisani kako bi njena struktura bila što jasnija.
<div class="search-wrap">
<div class="search-form">
<div class="form-header">
<span><img src="..." alt=""></span>
<h4>Vozni red</h4>
24
Ova je forma dohvaćena sa stranice www.hzpp.hr dana 8.6.2015.
48
<div class="indicator"></div>
</div>
<form class="form-body">
<div class="form-group">
<label for="tt_FromLabel">Od</label>
<input class="form-control" placeholder="Polazište" ...>
</div>
<!-- ostale kontrole -->
<label class="radio-inline">
<input name="tt_Direction" id="Radio1" value="1" type="radio"
checked="checked" onchange="tt_showHideDateReturn()">
<span>Jedan Smjer</span>
</label>
<!-- ... -->
<div class="form-group">
<input type="button" class="btn submit btn-default blue"
id="tt_btnSearch" value="Pretraži">
</div>
</form>
</div>
</div>
Na ovoj, naizgled jednostavnoj, formi već se može vidjeti koliko dinamike ona pruža
akcijama prikazivanja kalendara i dodavanjem datuma povratka koji se događa na
odabir "Povratno" radio button form kontrole. Ta dinamika je danas često neizbježna
čak i na stranicama koje su pretežito statičke, kao što je i stranica s koje je analizirana
forma. To dovodi do zaključka da dinamički model prepoznavanja stranica u konačnici
ne može u potpunosti zanemariti dinamiku, već će biti potrebno korisnicima dati
povratnu informaciju o ovako jednostavnim akcijama koje se događaju na pretežno
statičkim stranicama. Dodatan problem na ovoj stranici je i korištenje samodovršetka
(eng. autocomplete) jednom kada se odabere jedan od polja za unos teksta polazišta ili
odredišta, no ono nije neophodno kako bi se formom moglo upravljati.
Postoji mogućnost postavljanja alternativnog puta prikazivanja HTML kôda u slučaju da
JavaScript nije omogućen putem <noscript> oznake. No, većina web aplikacija ne
definira potpuno svoju funkcionalnost u slučaju da JavaScript nije omogućen, kao što ne
definira ni stranica s koje je analizirana forma, iako ona predstavlja glavno sjedište za
provjeru voznog reda vlakova u Republici Hrvatskoj. To dovodi do zaključka da se ne
49
može osloniti na <noscript> oznaku, već da će Oculi agenti doista morati uključiti
svojevrstan model prepoznavanja i davanja povratnih informacija korisniku o rezultatima
dinamičkih akcija.
Ekstrakcija elemenata formi dosta je jednoznačna pri čemu je potrebno pronaći oznaku
<form> i obuhvatiti sve što je unutra pohranjeno. No, ekstrakcija elemenata formi nije
dovoljna pri dohvaćanju cijele semantičke forme, jer je za semantičku formu potrebno
dohvatiti i naziv forme, što je u slučaju analizirane forme Vozni red. Isto tako, važno je
otkriti kategoriju klasificirane forme, kako bi se uspjela dobiti povratna informacija o
značenju akcije koja će biti sprovedena potvrđivanjem, odnosno slanjem podataka
putem forme. Značajke koje sam izdvojio su sljedeće:
Značajka form oznaka u podstablu: provjerava nalazi se točno jedna <form>
oznaka u podstablu; vrijednosti iz skupa {0, 1}. Ova značajka omogućava
odvajanje onih elemenata koji ne mogu biti klasificirani kao forme, jer ili ne
sadrže ni jednu formu ili sadrže više formi, što znači da u podstablu postoji više
elemenata forme.
Značajka broj pojavljivanja tekstualnih čvorova izvan form oznake: provjerava
koliko se puta pojavljuju tekstualni čvorovi izvan <form> oznake; vrijednosti iz
intervala [0, ∞>. Tipično se naslov nalazi u jednom tekstualnom čvoru, tako da je
očekivana vrijednost oko jedinice.
Značajka duljina teksta izvan form oznake: računa sumu duljine tekstova svih
tekstualnih čvorova u DOM-u koji se nalaze izvan form oznake; vrijednosti iz
intervala [0, ∞>. Ne očekuje se prevelika suma duljine tekstova, jer bi u
suprotnom drugi dijelovi mogli biti proglašeni kao stavke.
Značajka razina form oznake: računa razinu na kojoj se nalazi <form> oznaka
unutar podstabla gledanog elementa; vrijednosti iz intervala [0, ∞>. Ova značajka
pokušava onemogućiti da se obuhvati veći dio stranice i naslov pojedinog
zaglavlja pod formu, nego da se pod formu uzme samo onaj minimalni dio
povezan s nazivom.
Predstavljene značajke zajedničke su za sve potkategorije form kategorije. Kako bi se
odredilo o kojoj se potkategoriji radi, potrebno je analizirati sljedeće elemente:
50
dinamiku koja je obuhvaćena formom,
semantiku tekstualnog sadržaja forme,
HTML kontrole sadržane u formi (npr. textarea se češće pojavljuje kod
komentara) i
akciju koja se pokreće potvrđivanjem, odnosno slanjem podataka putem forme
(često sadržana u action i method HTML atributima <form> oznake).
Dodatne značajke koje će se izgraditi temeljem ovih komponenta analiziranja, upućuju
na nužnost očuvanja jezične oznake i utječu na izgradnju algoritma čišćenja, na kojeg
su utjecale i već napravljene ekstrakcije značajki ostalih značajki, tako da su ova dva
dijela povezana.
3.2.5 Ekstrakcija značajki za kategoriju općenitih podataka
Općeniti podaci predstavljaju one informacije na stranici koje govore nešto o stranici, a
nisu direktno povezani sa sadržajem na stranici. To su:
naziv i jezik stranice,
naziv poslovnog objekta,
lokacija poslovnog objekta,
radno vrijeme poslovnog objekta,
kontakt brojevi,
proizvođači stranica itd.
Te su informacije ponekad ugrađene u početnu stranicu te ih je potrebno moći izdvojiti,
a ponekad su izdvojene u posebne stranice, kao što su "Lokacija", "O nama", "Kontakt" i
ostalo. Ako se općeniti podaci nalaze na posebnim stranicama, oni se više ne smiju
tretirati kao općeniti podaci, jer su u tom slučaju direktno povezani sa sadržajem na
stranici, odnosno tada oni definiraju specifični sadržaj na stranici i u tom će se slučaju
oni morati klasificirati kao stavke.
Primjer ove podvojenosti lokacije općenitih podataka i klasifikacije predstavlja sljedeća
slika.
51
Slika 3.18 Podvojenost lokacije općenitih podataka25
Na slici su plavim pravokutnicima označeni podaci koji su prebačeni na posebne
stranice, a koji bi se inače tretirali kao općenite informacije da su se nalazile na
globalnoj stranici. S druge strane, crvenim pravokutnicima su označeni općeniti podaci
koji moraju biti klasificirani kao općeniti podaci.
Značajka koja je vrlo važna za određivanje instanci kategorije općenitih podataka je
značajka postotak pojave oznake stabla izbornika unutar cijele stranice koja je već
definirana kod ekstrakcije značajki za navigaciju. Kod ekstrakcije značajki za kategoriju
općenitih podataka bi promijenila samo ime, a zadržala funkcionalnost. Razlog važnosti
ove značajke leži u činjenici da se općeniti podaci uglavnom pojavljuju u gornjem ili
donjem zaglavlju web stranica, pri čemu je analizirani dio izvučen iz samog dna
stranice.
Iz slike se može vidjeti kako je dodatni problem pronalaska općenitih podataka u tome
što se pojedine općenite informacije integriraju unutar slika, kao što je logo poduzeća. U
takvim će slučajevima biti potrebno prepoznati slike koje bi mogle sadržavati općenite
informacije i poslati ih na raspoznavanje slika (eng. image recognition). Logo slike bi se
mogle prepoznati značajkom koja provjerava je li slika ujedno umotana u poveznicu i
vodi li na početnu stranicu, što je čest slučaj kod loga.
Ekstrakcijom značajki, došao sam do sljedećih rezultata:
Značajka omjer sadržavanja općenitih oznaka: provjerava koliki je omjer onih
oznaka koje upućuju na općenite podatke naspram ostalih oznaka; vrijednosti iz
intervala [0, 1]. Oznake koje upućuju na općenite podatke su sljedeće:
<address>, <time> i <title>. Oprezan treba biti s oznakom <time> i <address> jer
25
Ovaj segment je donje zaglavlje uzeto sa stranice http://www.konzum.hr/ dana 9.6.2015.
52
one ne označuju jednoznačno općenite informacije već se mogu naći i u
stavkama.
Značajka sveukupna veličina podstabla općenitih podataka: provjerava koliko
čvorova ima trenutno gledano podstablo mogućih općenitih podataka; vrijednosti
iz intervala [1, ∞>. Očekuje se malen broj veličine podstabla općenitih podataka.
Značajka sveukupna veličina teksta unutar tekstualnih čvorova: računa
sveukupnu veličinu teksta u znakovima; vrijednosti iz intervala [0, ∞>. Očekuje se
ne prevelika veličina teksta za instancu općenitih podataka, otprilike do 50
znakova.
Postoji, doduše, još jedna oznaka koja bi mogla označavati općenite podatke: <meta>
oznaka. Ona definira sadržaj koji nije vidljiv korisnicima kada pregledavaju stranicu, već
definira sadržaj koji je često vidljiv samo na rezultatima tražilice i služi kako bi tražilice
što bolje klasificirale tekst. S <meta> oznakom treba biti oprezan, jer neke vrijednosti
HTML atributa name oznake <meta> nisu namijenjeni običnom korisniku (kao što su
generator i keywords (hrv. ključne riječi), dok bi neke vrijednosti (kao što su application-
name (hrv. ime aplikacije), author (hrv. autor) i description (hrv. opis) mogle biti
zanimljive. No, to se procesuiranje treba postaviti prije same klasifikacije i isključiti meta
oznake iz klasifikacije, a zatim uključiti te podatke u rezultate.
Kao i kod kategorije stavaka i kategorije formi, biti će potrebno uključiti i semantičko
procesuiranje tekstualnog sadržaja, kako bi se što preciznije mogli odrediti općenite
informacije, što predstavlja još jedan razlog zašto je vrlo potrebno očuvati jezičnu
oznaku.
3.3. Odabir i treniranje modela
Dinamičko prepoznavanje semantičkih dijelova stranica spada pod klasifikacijske
algoritme, jer primjerima pridružujemo klasu, pa za ciljnu varijablu kažemo da je
diskretna, odnosno nominalna. Primjer predstavlja vektor značajki i označimo ga
s x, a skup primjera za učenje koji se sastoje od parova primjera i pripadnih
oznaka označimo s D. Zadaća klasifikacijskog algoritma je naučiti hipotezu h,
53
koja određuje pripadnost nekog primjera x nekoj klasi C. Učenje te hipoteze
predstavlja loše definiran problem (eng ill-posed problem), jer primjeri iz skupa za
učenje D nisu sami po sebi dovoljni da bi se na temelju njih jednoznačno
inducirala hipoteza h [15]. Skup mogućih hipoteza unutar kojeg tražimo poželjnu
hipotezu nazivamo modelom i označavamo s H. Osnovna podjela klasifikacijskih
postupaka jest na generativne i diskriminativne modele. Dok generativni modeli
pretpostavljaju da je vjerojatnost da primjer x pripada klasi Cj proporcionalna
zajedničkoj vjerojatnosti primjera x i klase Cj, diskriminativni modeli izravno modeliraju
pripadnost primjera x klasi Cj. Za hipotezu, vrlo je važno svojstvo generalizacije
čime ona može odrediti klasifikaciju još neviđenih primjera. Kako bi hipoteza
mogla generalizirati, potrebno je uvesti dodatan skup naših pretpostavki što
nazivamo induktivna pristranost (eng inductive bias) pri čemu razlikujemo dvije
vrste induktivne pristranosti:
1. pristranost ograničenjem ili pristranost jezika (eng. restriction bias,
language bias), kojom ograničavamo skup hipoteza birajući model H te
2. pristranost preferencijom ili pristranost pretraživanja (eng. preference bias,
search bias) kojom definiramo put pretraživanja hipoteza unutar skupa
hipoteza i tako dajemo prednost jednim hipotezama u odnosu na druge.
3.3.1 Odabir stroja potpornih vektora
Često je vrlo teško skupiti dobar skup za učenje D. Upravo to je bio razlog zašto
sam razvio ekstenziju za označavanje web stranica, kako bi se što više
označivača moglo priključiti u projekt na što jednostavniji način. Odabir modela
trebao bi se temeljiti na analizi i evaluaciji podataka na različitim modelima, no
pošto će se kvalitetan skup za učenje tek razviti, ja sam svojim podacima trenirao
diskriminativan model pod nazivom stroj potpornih vektora (eng. support vector
machine, SVM) zbog moguće uporabe jezgrenih funkcija čija prava snaga dolazi
do izražaja kada su ulazi strukturirani objekti, kao stabla čija se sličnost treba
otkriti. Iako sam inicijalno mislio da ću uspoređivati strukture stabla pri čemu sam
54
razvio nekoliko algoritma za strukturalno čišćenje podstabla elemenata kako bi
se očistili nepotrebni podaci i redundancija, previše je bilo višeznačnosti među
strukturama, tako da sam se ipak odlučio koristiti značajke unutar SVM modela.
Također, glavna prednost diskriminantnih modela nad generativnim modelima
jest složenost modeliranja, pri čemu je složenost kod diskriminativnih modela
puno manja što je velika prednost, budući da će se klasifikacija odvijati nad
velikim skupom elemenata.
3.3.2 O stroju potpornih vektora
Definiranjem kriterija maksimalne margine (eng. maximum margin), SVM uvodi
induktivnu pristranost preferencije. Pretpostavka od koje SVM kreće leži u intuitivnoj tezi
da granica između pozitivnih i negativnih primjera mora biti što veća, kako bi model
bolje generalizirao. Nakon izvoda izraza, za kriterij maksimalne margine dobivamo:
argmin
𝒘,𝑤0
1
2||w||2
(3.1)
gdje w i w0 predstavljaju težine značajki uz ograničenje:
𝑦(𝑖)(𝐰T𝜑(𝑥(𝑖)) + 𝑤0) ≥ 1, 𝑛 = 1, . . . , 𝑁 . (3.2)
U ograničenju, 𝜑 predstavlja funkciju preslikavanja u prostor značajki. Nalaženje
maksimalne margine prikazano je problemom konveksne optimizacije uz ograničenja
što se rješava metodom Lagrangeovih multiplikatora. Treniranje modela svodi se na
rješavanje problema kvadratnog programiranja dobivenog deriviranjem primarnog
problema s Lagrangeovim multiplikatorima uvrštenog u dualni problem, a rezultat
treniranja je N-dimenzijski vektor parametra α. S naučenim modelom, novi primjer 𝐱 se
klasificira tako da se izračuna vrijednost funkcije 𝑠𝑔𝑛(ℎ(𝐱)) pri čemu je ℎ jednak:
ℎ(𝐱) = 𝐰T𝜑(𝐱) + 𝑤0 = ∑ 𝛼𝑖𝑦(𝑖)𝜑(𝐱)T𝜑(𝐱(𝑖)) + 𝑤0.
𝑁
𝑖=1
(3.3)
Rješavanje problema konveksne optimizacije uz ograničenja zadovoljava Karush-Kuhn
Tuckerove uvjete:
𝛼𝑖 ≥ 0
55
𝑦(𝑖)ℎ(𝐱(𝑖)) − 1 ≥ 0
𝛼𝑖(𝑦(𝑖)ℎ(𝐱(𝑖)) − 1) = 0
Prvo ograničenje dolazi od toga što su 𝛼𝑖 Lagrangeovi multiplikatori. Drugo ograničenje
vrijedi zbog ograničenja (3.2). Iz posljednjeg uvjeta slijeda da za svaki primjer 𝐱(𝑖) iz
skupa za učenje D vrijedi 𝛼𝑖 = 0 ili 𝑦(𝑖)ℎ(𝐱(𝑖)) = 1. To pak znači da će se u zbroju u (3.3)
pojavljivati samo vektori 𝐱(𝑖) za koje vrijedi 𝑦(𝑖)ℎ(𝐱(𝑖)) = 1, a to su upravo oni vektori koji
leže na ravninama maksimalne margine. Te vektore nazivamo potpornim vektorima
(eng. support vectors) [15]. Svi ostali vektori za koje je 𝛼𝑖 = 0, uopće ne utječu na izlaz
modela i možemo ih posve zanemariti. Dosad konstatirane jednakosti imale su za
pretpostavku linearnu odvojivost klasa. No, sukladno Coverovom teoremu, puno je
vjerojatnije da će problem biti linearno neodvojiv te je stoga potrebno uvesti formulaciju
problema meke margine što predstavlja proširenje prethodnog modela tako da on
dozvoljava da neki primjeri ipak budu pogrešno klasificirani. Primjere ćemo kažnjavati to
više što se oni nalaze dublje na pogrešnoj strani granice, što ostvarujemo uvođenjem
rezervnih varijabli. Sada nam je cilj maksimizirati marginu, ali i kazniti primjere koji nisu
na pravoj strani margine, tako da želimo minimizirati:
argmin
𝒘,𝑤0{1
2||w||2 + 𝐶 ∑ 𝜉𝑖
𝑁
𝑖=1
} , (3.4)
pri čemu parametar 𝐶 određuje veličinu kazne pogrešne klasifikacije, a 𝜉𝑖 rezervne
varijable koje pokazuju koliko se duboko primjer nalazi na pogrešnoj strani.
SVM je u linearan model, a većina problema je nelinearna. Model možemo
transformirati i učiniti ga nelinearnim, ali je bolje rješenje transformirati problem tako da
iz ulaznog prostora preslikavamo primjere u prostor značajki koristeći funkciju
preslikavanja φ. Umjesto da odabiremo preslikavanje za koje ne znamo je li unaprijed
dobro (tj. hoće li rezultirati linearno odvojivim problemom u prostoru značajki), mi ćemo
iskoristiti tzv. jezgreni trik (eng. kernel trick) pri čemu ćemo umnožak dvaju primjera 𝐱 i
𝐱′ u prostoru značajki zamijeniti funkcijom
𝜅(𝐱, 𝐱′) = 𝜑(𝐱)T𝜑(𝐱′)
56
koju nazivamo jezgrenom funkcijom (eng. kernel function). Moramo uvijek koristiti
Mercerove jezgre ili pozitivno definitne jezgre koje je, prema Mercerovom teoremu,
uvijek moguće rastaviti na skalarni produkt. Postoji niz standardnih funkcija koje su
Mercerove jezgre, kao što su linearna jezgra, polinomijalna jezgra i radijalne bazne
funkcije.
3.3.3 Odabir modela
Kod treniranja modela koristio sam radijalne bazne funkcije (eng. radial basis functions,
RBF) ili homogene jezgre 𝜅(𝐱, 𝐱′) = 𝜅(||𝐱 − 𝐱′||), koje samo ovise o udaljenosti između
primjera. Poseban slučaj radijalne bazne funkcije jest Gaussova jezgra:
𝜅(𝐱, 𝐱′) = exp {− ||𝐱 − 𝐱′ ||2
2σ2 } = exp {−γ||𝐱 − 𝐱′||2}
gdje parametar 𝛾 = 1/2𝜎2 nazivamo preciznost (inverz varijance). Skalarnim produktom
izražava se sličnost između dvaju primjera koja se kod Gaussove jezgre mjeri temeljem
udaljenosti tih primjera u ulaznom prostoru. Slični primjeri će biti blizu u prostoru
značajki, za koje Gaussova jezgra teži jedinici. Različiti primjeri su ortogonalni u
prostoru značajki, jer vrijedi 𝜅(𝐱, 𝐱′) → 0. Parametar 𝛾 određuje kojom brzinom
Gaussova jezgra 𝜅(𝐱, 𝐱′) teži k nuli u ovisnosti o odaljenosti. On je tzv. hiperparametar
kojim optimiziramo odabir modela. Sam odabir SVM-a kao modela predstavlja već
određenu induktivnu pristranost ograničenja, a optimizaciju hiperparametara također
nekog fiksnog modela nazivamo odabir modela (eng. model selection). Hiperparametre
treba optimizirati tako da model ne bude niti prenaučen niti podnaučen. Prenaučenost
(eng. overfitting) modela realizira previše složenim modelom koji daje hipoteze koje
pretpostavljaju više nego što postoji u stvarnim podacima. Hipoteze će vrlo varirati u
ovisnosti u skupu primjera za učenje, pa kažemo da složeni modeli imaju visoku
varijancu. Podnaučenost (eng. underfitting) modela znači da će model biti
prejednostavan, što će kao posljedicu dati hipotezu koja se ne može dovoljno prilagoditi
podacima. U jednostavan model je ugrađeno više pretpostavki, stoga kažemo da
jednostavan model ima veću pristranost (u statističkom smislu). Unakrsna provjera
(eng. cross validation) predstavlja jedan od načina kako kvantitativno ocijeniti je li model
prenaučen ili podnaučen. Kod unakrsne provjere kojom utvrđujemo i konačnu pogrešku
57
već odabranog modela, skupove podataka razdvajamo na tri međusobno disjunktna
skupa podataka: skup za učenje (eng. training set), skup za provjeru (eng. validation
set) i ispitni skup (eng. test set). Model učimo na skupu za učenje, a njegovu
generalizacijsku sposobnost provjeravamo na skupu za provjeru. Jednom kada smo
tako optimizirali hiperparametre, model treniramo na uniji skupova za treniranje i
provjeru, a grešku provjeravamo na ispitnom skupu. Vjerojatnost prenaučenosti modela
može se smanjiti i regularizacijom kojom se u samo treniranje, odnosno unutar
optimizacijskog postupka, ugrađuje kazna kojom se kažnjavaju suviše složeni modeli.
Uz preciznost, ne smije se zaboraviti na parametar 𝐶 u (3.4) koji će također biti
potrebno optimizirati. Hiperparametre obično optimiziramo unakrsnom provjerom. Oba
parametara su međusobno povezana tako da ako odaberemo visoku vrijednost za 𝛾,
dobit ćemo složeniji model, pa će trebati pojačati regularizaciju odabirom manje
vrijednosti za 𝐶. U ovom slučaju unakrsnom provjerom optimiramo dva parametra
istovremeno, što radimo iscrpnim pretraživanjem u unaprijed definiranom rasponu, tzv.
pretraživanjem po rešetci (eng. grid search). Sljedeći programski isječak prikazuje
postupak odabira modela SVM-a.
# pretrazivanje po resetci, vraca optimalne parametre C i gamma
def grid_search(XLearn, XValidate, yLearn, yValidate, (c1, c2), (g1,
g2)):
Cs = range(c1, c2 + 1)
Gs = range(g1, g2 + 1)
e_errors = np.empty([c2 - c1 + 1, g2 - g1 + 1])
g_errors = np.empty([c2 - c1 + 1, g2 - g1 + 1])
for i in range(len(Cs)):
for j in range(len(Gs)):
# eksponent
C = 2 ** Cs[i]; G = 2 ** Gs[j]
svc = SVC(kernel='rbf', C=C, gamma=G)
svc.fit(XLearn, yLearn)
e_errors[i][j] = zero_one_loss(yLearn, svc.predict(XLearn))
g_errors[i][j] = zero_one_loss(yValidate,
svc.predict(XValidate))
(Ci, Gi) = np.unravel_index(g_errors.argmin(), g_errors.shape);
58
return 2 ** Cs[Ci], 2 ** Gs[Gi]
# podjela na zajednicki skup za treniranje i na ispitni skup
XTrain, XTest, yTrain, yTest = train_test_split(X, y, train_size=0.9)
# zajednicki skup se zatim dijeli na validate i learn skup
XLearn, XValidate, yLearn, yValidate = train_test_split(XTrain,
yTrain, train_size=0.7)
c_range = (-5, 15)
g_range = (-15, 3)
Copt, Gopt = grid_search(XLearn, XValidate, yLearn, yValidate,
c_range, g_range)
print 'Optimalne vrijednosti parametara dobivene pretrazivanjem po
resetci su C = {0}, Gamma = {1}'.format(Copt, Gopt);
Programski isječak je rezultirao ispisom:
Optimalne vrijednosti parmaetara dobivene pretrazivanjem po resetci
su C = 0.5 i Gamma = 0.0625
U programskom isječku, prvo smo definirali funkciju koja radi pretraživanje po rešetci za
određene intervale oba parametara tako da ih stavlja kao eksponente na dvojku. Nakon
što smo izračunali Nula-jedan empirijske i generalizacijske gubitke (eng. zero-one
loss)26, računamo koji indeksi u intervalima parametara daju najmanju generalizacijsku
pogrešku tako da iz indeksa jednodimenzionalnog polja dobivamo indekse
dvodimenzionalnog polja putem funkcije unravel_index. Prije pozivanja funkcije, skup
podataka smo podijelili na tri međusobno disjunktna skupa sa sufiksima Learn (skup
podataka za učenje), Validate (skup podataka za provjeru) i Test (skup podataka za
ispitivanje). Podaci u skupu sa sufiksom Train predstavljaju uniju skupova Learn i
Validate te će se koristiti kod treniranja, zajedno s Test skupom.
3.3.4 Treniranje modela
Nakon odabira modela, slijedi treniranje modela koje je sada vrlo jednostavno provesti i
prikazano je sljedećim programskim isječkom.
# treniranje modela
svm = SVC(kernel = 'rbf')
svm.fit(XTrain, yTrain)
26
Zero-one loss računa koliki je broj primjera drugačije klasificiran nego što je trebao biti.
59
empiricalError = 1 - accuracy_score(yTrain, svm.predict(XTrain))
generalisationError = 1 - accuracy_score(yTest, svm.predict(XTest))
print 'Empirijska greška: {0}'.format(empiricalError)
print 'Generalizacijska greška: {0}'.format(generalisationError)
# perzistencija modela
from sklearn.externals import joblib
joblib.dump(svm, 'model-persistence/model-navigation-main.pkl')
Za treniranje modela sada koristimo Train i Test skupove i putem accuracy_score
funkcije koja je definirana u scikit learn biblioteci dobivamo empirijske i generalizacijske
pogreške. Na kraju radimo perzistenciju modela o kojoj će više riječi biti kod poslužitelja
Oculi.
Programski isječak je rezultirao sljedećim ispisom:
Empirijska greška: 0.0
Generalizacijska greška: 0.125
što daje rezultat generalizacijske točnosti od 87.5%. No, ovaj rezultat nije vrlo kvalitetan
zbog variranja ponovljenim korištenjem funkcije train_test_split koja nasumično dijeli
primjere u skupove. Rezultat ne bi smio varirati zbog korištenja funkcije train_test_split.
Kako bi rezultat bio što kvalitetniji i što manje varirao, potrebno je imati veći skup
podataka što je sada jedini primarni fokus. Opisano treniranje modela je odrađeno na
navigation-main podacima.
60
4. Poslužitelj Oculi
Za potrebu pohrane označenih podataka, odnosno repozitorija, perzistenciju
dinamičkog modela segmentiranja stranica, API-ja za pozivanje tog modela te opisa i
dokumentacije cjelokupnog koncepta napravio sam poslužitelj Oculi koji je građen po
REST (Representational State Transfer) arhitekturi, čija se početna stranica može
vidjeti na sljedećoj slici.
Slika 4.1 Početna stranica www.oculi.info
61
4.1. Implementacija poslužitelja i sučelja
Pri implementaciji poslužitelja i sučelja slijedio sam standard definiran REST stilom
programske arhitekture. REST je stil programske arhitekture i predstavlja ograničenja
kako bi se izgradili skalabilni hipermedijski raspodijeljeni sustavi [21]. Ukratko,
ograničenja se odnose na 3 glavne skupine s daljnjom podjelom na manje koncepte:
mrežu:
o Klijent-server arhitektura omogućava raspodjelu sustava gdje klijenti
zahtijevaju i prikazuju dokumente korisnicima, a serveri pohranjuju i
poslužuju klijente s dokumentima.
o Slojeviti sustavi su izgrađeni od posrednici (Proxy i Gateway) između
klijenta i servera čime pospješuju sigurnost, skladištenje, balansiranje
opterećenja te pretvorbe protokola.
sadržaj:
o Adresiranje je spoj URI-ja (Uniform Resource Identifier), kao jedinstvenog
identifikatora resursa i samog resursa.
o Hipermedijski dokumenti su međusobno povezani.
te na interakciju između klijenta i servera:
o Jedinstveno sučelje omogućava klijentima pristup svakoj RESTful web
usluzi (hrv. web usluga koja poštuje REST ograničenja) na isti način,
koristeći mali skup pravila.
o Server ne čuva stanje u kojoj se pojedina aplikacija klijenta nalazi, te se
svaki HTTP zahtjev događa u potpunoj izolaciji.
o Posrednici pohranjuju neke zahtjeve kako bi se smanjio promet.
Uz REST su se razvile mnoge konvencije kako dizajnirati URI-je, kao što su:
URI putevi (eng. path) bi trebali sadržavati samo mala slova, jer pošto je URI
osjetljiv na velika i mala slova, osim kod dijela sheme i domaćina [22], razlika bi
trebala biti samo na slovima.
Za API se treba koristiti konzistentna poddomena, kao što je "api." [23].
62
Poslužitelj Oculi se u potpunosti pridržava ograničenja definiranih stilom programske
arhitekture REST pri izgradnji API-ja, koji je objašnjen u sljedećom poglavlju. Za
implementaciju stila REST sam se odlučio na Node.js27, višeplatformsko izvršno
okruženje otvorenog kôda (eng. open source, cross platform runtime environment) i
biblioteku za JavaScript [24]. Node.js koristi Googleov V8 stroj kako bi omogućio
izvršavanje JavaScripta na serverskoj strani. Iako razvijen tek 2009. godine, sveopća
prihvaćenost Node.js i potpornih paketa čini ga najprikladnijim za brz razvoj projekata.
Statistike npm-a (Node Package Manager)28, sa 140 tisuća paketa i 50 milijuna
preuzimanja dnevno, pokazuju veličinu zajednice koja se stvorila oko Node.js u tako
kratko vrijeme.
Stvaranje organizacije projekta u Node.js je vrlo proizvoljno. Kako ne postoji službeni
IDE, organizacija ponajviše ovisi o iskustvu programera i poznavanju konstrukcije
modularnih sustava. Postoje dobri članci iskusnih programera koji preporučuju
organizaciju projekata temeljem MVC (Model-View-Controller) obrasca [25] te također
postoje i razni generatori organizacije projekata, kao što je Kraken.js29.
Arhitektura baze podataka nije složena i sastoji se od svega dva entiteta: označivača i
njegovih označenih stranica. Po toj arhitekturi je potrebno dizajnirati bazu podataka
poslužitelja. Za bazu sam se odlučio koristiti MongoDB, NoSQL bazu podataka za
pohranjivanje JSON dokumenata [26]. Korištenje NoSQL baze podataka, kao što je
MongoDB uvelike pojednostavljuje i povećava brzinu razvoja samog projekta, jer se
promjene inicijalnog koncepta i arhitekture mogu brzo prepraviti u samoj bazi, što je, uz
vrlo dobru integraciju s Node.jsom, ključan razlog zašto sam se odlučio za MongoDB.
Baza podataka je sastavljena od kolekcija podataka koje sadrže dokumente pojedinog
tipa, odnosno modela. Ako su kolekcije popunjene nekim radnim podacima, a u
međuvremenu smo promijenili atribute, odnosno svojstva (eng. properties) nekog
modela, nove instance tog modela možemo pospremiti u postojeću kolekciju s
postojećim podacima bez ikakve promjene arhitekture baze podataka ili odbacivanja
prethodnih podataka. To uvelike ubrzava sam razvoj, pogotovo kod projekata koji su tek
27
https://nodejs.org/ 28
http://npmjs.com/ - Upravitelj paketa za Node.js 29
http://krakenjs.com/
63
u razvoju, kod kojih su promjene koncepata česte. Interakcija Node.js poslužitelja i
MongoDB baze odvija se preko Mongoosea30, posrednika za jednostavnije korištenje
MongoDB baze. Sljedeći programski isječak prikazuje implementaciju kolekcije
označenih stranica.
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
//Structure
var SitesScheme = new Schema({
// essential
url: { type: String },
siteDOM: { type: String },
user: { type: Schema.ObjectId, ref: 'users' },
mhtml: { type: Boolean, default: false }, // ima li MHTML
labeledCorrect: { type: Number}, // 0 - neocijenjeno, 1 - točno, 2
- netočno
// stats
date_labeled: {type: Date, default: Date.now }
});
// Exporting
module.exports = mongoose.model('labeledSites', SitesScheme);
U programskom isječku se može vidjeti atribut user koji poprima vrijednost reference na
kolekciju naziva users. Kolekcija za pohranjivanje označenih stranica naziva se
labeledSites što se može vidjeti u zadnjoj liniji kôda.
4.2. Prezistencija modela i pripadni API
Za semantičku segmentaciju stranice, potrebno je sprovesti klasifikaciju njenih
elemenata, pri čemu se koristi model dobiven treniranjem. Nakon treniranja, poželjno je
očuvati stanje naučenog modela kako se ne bi ponovno moralo trenirati, jer sam
postupak treniranja može trajati dulje ovisno o veličini podataka za treniranje. Potrebno
je provesti postupak očuvanja modela (eng. model persistence). Python paket scikit
30
http://mongoosejs.com/
64
learn omogućuje očuvanje modela na jednostavan način pohranjivanja u datoteke što je
prikazano sljedećim programskim isječkom.
from sklearn.externals import joblib
joblib.dump(svm, 'model-persistence/model.pkl')
Nakon toga, sve što je potrebno napraviti je učitati treniran model iz datoteke koji se
odmah može koristiti sa svim svojim atributima i metodama. Učitavanje je prikazano
sljedećim programskim isječkom.
svm = joblib.load('model-persistence/model.pkl')
Poslužitelj Oculi sadrži API pozive koji prosljeđuju zahtjev modelu. Glavni API poziv
čeka na POST HTTP zahtjev s URL-om (Uniform Resource Locator) stranice u tijelu
HTTP zahtjeva. Jednom kada se primi zahtjev, poslužitelj dohvaća Node.js paket naziva
request (hrv. zahtjev) koji šalje zahtjev prema stranici. Ako je zahtjev dobar, odnosno
ako se ne pojavi greška i HTTP status je 200, poslužitelj preko Node.js paketa naziva fs
sprema HTML dokument sadržan u tijelu zahtjeva u privremenu datoteku i pokreće
Python proces dijete preko child_process Node.js paketa koji čini samu jezgru
pokretanja klasifikacijskog modela. Novi Python proces čita HTML dokument pohranjen
u privremenoj datoteci, učitava očuvani model u datoteci i klasificira elemente stranice.
Jednom klasificirana stranica ispisuje se na standardni izlaz, stdout (eng. standard
output) koji, uz stdin i stderr, predstavlja jedan od tri komunikacijska kanala između kojih
proces i njegova okolina komuniciraju. Node.js proces poslužitelja je pri pokretanju
Python procesa djeteta postavio svoje rukovatelje događaja na komunikacijske kanale
za izlaz, stdout i pogrešku, stderr te sada čeka na povratak klasificirane stranice.
Jednom vraćena stranica ili pogreška vraća se kao odgovor na inicijalni zahtjev na API
poziv. Ovaj opis sadržan je u sljedećom programskom isječku.
router.post('/classify', function(req, res){
var websiteURL = req.body.url;
var errorMsg = 'An error occurred while requesting the website.';
var request = require('request');
request(websiteURL, function (error, response, body) {
if (!error && response.statusCode == 200) {
var fs = require('fs');
65
fs.writeFile("./ml-model/scripts/tmp", body, function(err) {
// Rukovanje pogreškom
// Pokrećemo Python process!
var spawn = require('child_process').spawn,
python = spawn('python', ['index.py'], {cwd: "./ml-
model/scripts"});
// Event handlers
python.stdout.on('data', function(data){ // Stranica će doći
console.log('stdout: ' + data);
res.send(data).end();
});
// Ostali rukovatelji
});
}
else {
res.send(errorMsg).end();
}
});
});
Iz programskog isječka može se vidjeti korištenje konstrukta router koji predstavlja
kontroler u MVC oblikovnom obrascu. Taj je konstrukt sadržan u Node.js paketu
express31 koji olakšava rukovanje i kreiranje web sustava putem Node.jsa. Router
očekuje post zahtjev na putu (eng. path) "classify" koji predstavlja API poziv za
klasificiranje stranice.
Naveden API poziv koristit će Oculi agenti koji omogućuju korisnicima jednostavnije
surfanje webom. Tipični slučaj korištenja (eng. use case) je pomoć pri surfanju slijepim i
slabovidnim osobama čiji je dijagram slijeda prikazan na sljedećoj slici.
31
http://expressjs.com/
66
Slika 4.2 Dijagram slijeda dohvaćanja stranice
Također, na stranici poslužitelju je moguće isprobati mogućnost korištenja modela pri
čemu je samo potrebno zadati URL stranice koja se želi klasificirati što je prikazano na
sljedećoj slici.
Slika 4.3 Klasifikacija na poslužitelju
67
4.3. Sustav validacije označivača
Sustav validacije označivača predstavlja važnu komponentu u postupku semantičkog
segmentiranja stranice. Šum je neželjena anomalija u podacima. Mogući uzroci šuma
su:
nepreciznost pri mjerenju značajki,
pogreške u označavanju (eng. teacher noise),
postojanje skrivenih značajki (latentnih varijabli) i
nejasne granice klasa[15].
Namjera sustava validacija označivača je odstraniti pojavu šuma kao pogreške u
označavanju. Kao što je to već opisano u poglavlju izrade ekstenzije za označavanje
stranica, uz DOM stranice šalje se i MHTML format. MHTML, što je kratko za MIME
HTML, je format za arhiviranje web stranica koji se koristi za pohranjivanje HTML kôda i
potpunih reprezentacija resursa koji se nalaze u HTML dokumentu, a koji bi inače bili
prezentirani vanjskim poveznicama, kao što su slike, animacije i ostalo. Pomoću
MHTML-a, vrlo je jednostavno u potpunosti rekonstruirati stranicu i pogledati kako se
ona označila.
Jednom prikupljen repozitorij na poslužitelju Oculi potrebno je procesuirati i validirati. Za
to je napravljen lokalni dio poslužitelja Oculi koji dohvaća MHTML datoteke na
poslužitelju Oculi i bazu koja je tamo stvorena. Lokalni dio poslužitelja aktivira se
učitavanjem lokalnog API-ja kada se poslužitelj pokreće lokalno, odnosno kada u okolini
poslužitelja ne postoji varijabla PORT koja je namještena na port (hrv. vrata) 80,
pretpostavljeni HTTP port. Pokretanje poslužitelja pokreće se naredbom npm start čime
se izvršava datoteka sljedeće strukture:
#!/usr/bin/env node
var app = require('../app');
// do: export PORT = 80 on global server before
app.set('port', process.env.PORT || 3000);
// Loading local routes
if (app.get('port') !== 80){
// Load local API for validation system and connect to local DB
68
// ...
}
else {
// Load API and connect do DB
// ...
}
Kako bi se označene stranice, odnosno označivači mogli evaluirati, potrebno je napraviti
sljedeće korake:
1. izvesti (eng. export) bazu podataka s poslužitelja Oculi,
2. prebaciti izvedenu bazu podataka s poslužitelja Oculi na lokalni dio poslužitelja,
3. prebaciti na lokalni poslužitelj MHTML datoteke s poslužitelja Oculi,
4. izbrisati izveden dio baze podataka s poslužitelja Oculi,
5. izbrisati prebačene MHTML datoteke s poslužitelja Oculi,
6. izbrisati bazu podataka na lokalnom poslužitelju ako postoji,
7. uvesti (eng. import) izvedenu bazu podataka na lokalni dio poslužitelja,
8. označiti ispravne MTHML preko sustava te
9. spojiti dosad generirani repozitorij s trenutno dobivenim repozitorijem.
Pošto će se ovi koraci morati učestalo ponavljati, napravio sam skriptu napisanu u Bash
komandnom jeziku koja je prikazana u sljedećem programskom isječku.
#!/bin/bash
current_dir=$(pwd)
repository_dir="$current_dir/../tmp-repository/"
database="oculi-tmp-repo"
# izvodimo bazu, odnosno njene dvije kolekcije
ssh -t -t [email protected] <<'ENDSSH'
~/oculiweb/scripts/stop-server
~/oculiweb/scripts/export-database
logout
ENDSSH
# skidamo kolekcije baze podataka i MHTML datoteke
scp [email protected]:~/labeledsites.json $repository_dir
scp [email protected]:~/users.json $repository_dir
scp -r [email protected]:~/oculiweb/mhtml $repository_dir
# brišemo prebačenu bazu podataka i MHTML datoteke
ssh -t -t [email protected] <<'ENDSSH'
69
~/oculiweb/scripts/delete-db-mhtml
~/oculiweb/scripts/start-server
logout
ENDSSH
# brišemo lokalnu bazu podataka
~/Databases/MongoDB/mongo $database --eval "db.dropDatabase()"
# uvodimo izvedenu bazu podataka, odnosno njene kolekcije
~/Databases/MongoDB/mongoimport --db $database --collection
labeledsites --file $repository_dir"labeledsites.json"
~/Databases/MongoDB/mongoimport --db $database --collection users --
file $repository_dir"users.json"
U programskom isječku se može vidjeti da se za spajanje na poslužitelj Oculi koriste
SSH (Secure Shell) kriptografski mrežni protokol čiji se ključevi koriste u naredbama
ssh, za spajanje na poslužitelj i scp, za prebacivanje datoteke i direktorija na lokalni
poslužitelj s poslužitelja Oculi. Također, prije izvađanja i prebacivanja baze podataka i
MTHML datoteka, poslužitelj Oculi se zaustavlja, a nakon tih procesa, poslužitelj
nastavlja s radom izvođenjem skripta na samom poslužitelju.
Jednom dohvaćena lokalna baza podataka i MHTML datoteke koriste se u sustavu za
validaciju označivača stranica. Taj sustav dostupan je iz sigurnosnih razloga samo na
lokalnom poslužitelju, a početna se stranica može vidjeti na sljedećoj slici.
Slika 4.4 Početna stranica sustava evaluacije označivača
Na početnoj stranici nalazi se tablica svih označivača koji su označivali stranice od
prošle validacije označivača. U tablici se nalazi statistika koja obuhvaća stupce:
identifikator označivača, broj označenih stranica, postotak stranica s MHTML-om, broj
ocijenjenih stranica i postotak točno označenih stranica. Kao što je već rečeno, MHTML
70
format je integracija HTML kôda i vanjskih resursa u jedinstvenom dokumentu. Upravo
su zato MHTML datoteke nerijetko dosta velike, pa sam zbog toga stavio ograničenje
na poslužitelju Oculi za veličinu MHTML datoteke koju je moguće prenijeti od 10MB-a
koje je namješteno i u označnoj ekstenziji. Iz toga proizlazi velika značajnost stupca
postotka stranica s MHTML-om, jer je poželjno da je označivač poslao što više MHTML-
a kako bi se mogao provjeriti. Postotak točno označenih stranica računa omjer
ocijenjenih označenih stranica kao točne koje imaju MHTML naspram svih stranica koje
su ocijenjene. Prag dobrog označivača je postavljen na 0.8, što će se uzeti u obzir pri
generiranju repozitorija.
Na vrhu početne stranice nalaze se dva gumba: generiraj repozitorij i generiraj čisti
repozitorij. Gumb generiraj repozitorij pokreće akciju generiranja repozitorija temeljenog
na svim označenim stranicama onih označivača koji su označeni kao dobri označivači.
S druge strane, gumb generiraj čisti repozitorij pokreće akciju generiranja repozitorija
koji će sadržavati samo one stranice koje su ocijenjene kao točne i tako sigurno neće
sadržavati šum koji je uzrok pogrešaka u označavanju.
Odabirom akcije ocijeni prikazuje se tablica sa svim označenim stranicama nekog
označivača koja je prikazana na sljedećoj slici.
Slika 4.5 Označene stranice pojedinog označivača
Akcije pregledaj, točno, netočno i resetiraj su dostupne samo za one stranice koje imaju
MHTML datoteku. Akcijom pregledaj prikazuje se MHTML datoteka. Nakon što
71
administrator pregleda kako je označena stranica, akcijama točno i netočno može
ocijeniti stranicu, čime će se promijeniti vrijednost stupca Ocjena kod retka zaduženog
za tu stranicu. Točno označena stranica mora biti u potpunosti označena i svaki
element mora biti dobro označen. Netočno označena stranica je ili nepotpuno označena
ili netočno označena. Akcijom resetiraj stanje ocjena stranice se vraća u Neocijenjeno
čime ona ne ulazi u izračun postotka točno označenih stranica kod označivača.
Nakon što je zadovoljavajuć broj označivača ocijenjen, administrator pokreće
generiranje repozitorija. Jednom generirani repozitorij integrira se s postojećim
repozitorijem i može se koristiti za treniranje.
4.4. Prezentacija cjelokupnog koncepta
Osim navedenih primjena poslužitelja, koristi se i za prezentaciju cjelokupnog koncepta.
Naime, dinamičko prepoznavanje web stranica dio je većeg sustava pod nazivom Oculi
(dolazi iz latinskog, hrv. oči). Oculi dinamički model daje semantičku notu web
stranicama koja omogućava agentima Oculi da prezentiraju tu stranicu svojim
korisnicima na intuitivan, fleksibilan i organiziran način. Oculi je, zapravo, podsustav
većeg sustava Videre (dolazi iz latinskog, hrv. vidjeti) te je konceptualni dijagram
čitavog sustava Videre prikazan na sljedećoj slici.
Slika 4.6 Konceptualni dijagram sustava Videre
72
Videre predstavlja potpuni obrazovno - tehnološki ekosustav za slijepe i slabovidne
osobe. Poslužitelj Oculi ima svrhu promicanja podsustava Oculi koji se sastoji od
agenata Oculi, kao što su mobilne aplikacije i ekstenzija Oculi koja se koristi na
računalima za brži i lakši pregled web stranica, te već opisane ekstenzije za
označavanje stranica. Za tu svrhu napravljena je i demonstracijska stranica za Oculi
ekstenziju na poslužitelju Oculi koja je prikazana na sljedećoj slici.
Slika 4.7 Stranica za ekstenziju
Na poslužitelju Oculi će se također čuvati i repozitorij označenih stranica koji će biti
javno dostupan. Sljedeća slika prikazuje stranicu za dohvaćanje repozitorija označenih
stranica, gdje je sadržan i dnevnik promjena repozitorija.
73
Slika 4.8 Stranica za repozitorij
74
5. Zaključak
Dinamički model prepoznavanja semantičkih dijelova stranica izložen u ovom radu
omogućuje raspoznavanje kategorija izbornika, specifičnih stavki za pojedinu stranicu,
raznih semantičkih formi i općenitih informacija. Poslužitelj, agenti i označna ekstenzija
čine sustav Oculi kojemu je primarna zadaća omogućiti raspoznavanje semantičkih
dijelova bez ikakve ovisnosti prema krajnjim programerima web stranica. To je najveća
prednost koju sustav Oculi donosi pred postojećim konceptom semantičkog weba ili
standarda Schema.org.
Algoritmi organizacije web stranica u semantičke cjeline temeljeni su na strojnom
učenju. Prvi korak je bio označavanje podataka za koji je napravljena ekstenzija za
označavanje web stranica kako bi se moglo prikupiti što više potrebnih podataka za
učenje gdje i najobičniji korisnici weba mogu koristiti taj alat. Označeni podaci šalju se
na poslužitelj Oculi, gdje se osim DOM reprezentacija pohranjuje i MHTML format
označenih podataka kako bi njihova kvaliteta mogla provjeriti. Vrlo je bitno imati stranice
bez šuma što će rezultirati točnijim dinamičkim modelom. U tu svrhu, napravljen je
posebni sustav provjere označivača.
Nakon prikupljenih podataka, krenulo se s ekstrakcijom značajki za svaku pojedinu
kategoriju. Sam proces ekstrakcije značajki diktirao je i procesima čišćenja i
perzistencije pomoćnih podataka kako bi se što više značajki moglo iskoristiti. Za
ekstrakciju značajki napravljene su funkcije koje izračunavaju vrijednosti značajka i tako
generiraju vektor primjera pojedinog HTML elementa.
Sljedeći korak bio je odabir modela za koji sam koristio stroj potpornih vektora s
radijalnim baznim funkcijama kao jezgrama. Razlog odabira tog modela bila je upravo
mogućnost korištenja jezgara koje su dobre pri usporedbi sličnosti strukturiranih
objekata. Pretraživanjem rešetke pronašao sam optimalne hiperparametre modela koji
su dalje korišteni pri treniranju modela. Treniranje modela je potom slijedilo vrlo
jednoznačno koje je dalo dobar, ali vrlo varirajući rezultat. Varirajući rezultat upravo je
svojevrsna napomena premalog repozitorija podataka za učenje. Repozitorij podataka
za učenje mora zadovoljavati kriterije dovoljne raznovrsnosti i veličine podataka koji će
75
se potom koristiti za treniranje. Repozitorij velike raznovrsnosti također omogućuje i
kvalitetniju ekstrakciju značajki pri čemu se omogućuje detaljnija analiza struktura stabla
HTML elemenata. Treniranje je učinjeno nad malim repozitorijem čija je jedina prednost
bila da greške nisu postojale.
Na kraju se izradio i prezentacijski dio koncepta koji se može pregledati na poslužitelju
Oculi, kako bi budućim označivačima što jasnije bilo koji je smisao samog označavanja
web stranica. Također, na poslužitelju se može dohvatiti zadnja verzija repozitorija za
vlastite potrebe.
Temeljem zaključaka po pojedinim koracima, glavni smjer daljnjeg razvoja ovog
projekta je u prikupljanju podataka. Trenutno označeni repozitorij sastoji se od malog
broja WordPress stranica koje omogućuju vrlo ispravnu klasifikaciju samo na vrlo
sličnim stranicama. Nakon prikupljanja većeg broja podataka bit će potrebno uvesti,
odnosno ekstrahirati nove značajke i uključiti značajke koje su u skladu sa standardom
Schema.org pošto postoji dosta velik broj stranica izgrađenih prema tom standardu.
76
6. Literatura
[1] Nepoznat autor, "Total number of Websites", http://www.internetlivestats.com/total-
number-of-websites
[2] Berners-Lee, T., "Tim Berners-Lee", 3.3.2015., http://www.w3.org/People/Berners-
Lee/, 14.3.2015.
[3] Passin, T. B., "Explorer's Guide to the Semantic Web", ožujak 2004.
[4] Jagušt, T., predavanja s kolegija "Napredni modeli i baze podataka", Fakultet
elektrotehnike i računarstva, prosinac 2013.
[5] RDF Working Group, RDF, 25.2.2014., http://www.w3.org/RDF/, 17.3.2015.
[6] Berners-Lee, T; Hendler, J; Lassila, O; "The Semantic Web", 17.5.2001.
http://www.cs.umd.edu/~golbeck/LBSC690/SemanticWeb.html, 18.3.2015.
[7] Berners-Lee, T; Shadbolt, N; Hall, W; "The Semantic Web Revisited", svibanj/lipanj
2006., http://eprints.soton.ac.uk/262614/1/Semantic_Web_Revisted.pdf, 18.3.2015.
[8] Reuters, "Berners-Lee looks for Web's big leap", 22.5.2006.,
http://web.archive.org/web/20070930221904/http://news.zdnet.co.uk/internet/0,1000
000097,39270671,00.htm, 18.3.2015.
[9] Wikipedia, "HTML5", 15.5.2015., http://en.wikipedia.org/wiki/HTML5, 18.5.2015.
[10] w3schools, "HTML Element Reference", http://www.w3schools.com/tags/,
18.5.2015.
[11] Wikipedia, "Microdata (HTML)", 14.4.2015. http://en.wikipedia.org/wiki/Microdata_
(HTML), 18.5.2015.
[12] Wikipedia, "Schema.org", 13.4.2015., http://en.wikipedia.org/wiki/Schema.org,
18.5.2015.
[13] Alpaydin, E. "Introduction To Machine Learning, second edition", 2010.
[14] Šnajder, J; Dalbelo Bašić, B; predavanja s kolegija "Strojno učenje", Fakultet
elektrotehnike i računarstva, 2014.
[15] Šnajder, J; Dalbelo Bašić, B; skripta s kolegija "Strojno učenje", "Grupiranje" -
"Primjene grupiranja", Fakultet elektrotehnike i računarstva, 2014.
[16] Chrome Developer, "JavaScript APIs", https://developer.chrome.com/extensions/api_index, 18.5.2015.
[17] Chrome Developer, "Overview", https://developer.chrome.com/extensions/overview, 18.5.2015.
77
[18] Chrome Developer, "Content Scripts",
https://developer.chrome.com/extensions/content_scripts, 18.5.2015.
[19] Mozilla Developer Network, "Block-level elements", 12.2.2015.,
https://developer.mozilla.org/en/docs/Web/HTML/Block-level_elements, 21.5.2015.
[20] W3C, "Declaring language in HTML", 29.5.2015,
http://www.w3.org/International/questions/qa-html-language-declarations, 27.5.2015.
[21] Škvor, D., predavanja s kolekija "Račnarstvo zaslovano na uslugama", Fakultet elektrotehnike i računarstva, 2013.
[22] Berners-Lee, T. RFC 3986 "URI Generic Syntax", 6.2.2.1. poglavlje, siječanj 2005., https://www.ietf.org/rfc/rfc3986.txt, 4.6.2015.
[23] Masse, M, "REST API Design Rulebook", 28.11.2011.
[24] Wikipedia, "Node.js", 31.5.2015., http://en.wikipedia.org/wiki/Node.js, 4.6.2015.
[25] Fidanov, S., "Best practices for Express app structure", http://www.terlici.com/2014/08/25/best-practices-express-structure.html, 4.6.2015.
[26] Wikipedia, "MongoDB", 2.6.2015., http://en.wikipedia.org/wiki/MongoDB, 4.6.2015.
[27] Wikipedia, "MHTML", 24.5.2015., http://en.wikipedia.org/wiki/MHTML, 5.6.2015.
78
7. Sažetak
Tomislav Tenodi
Dinamičko prepoznavanje dijelova
web stranica
Web, s gotovo milijardu stranica, predstavlja današnji glavni izvor podataka. Semantički
web ili standardi, kao Schema.org omogućuju programerima stranica da naprave svoje
stranice dostupne bez ljudskog utjecaja. No, programeri često ne dijele interes za tim
konceptima.
Prednost i novitet koju dinamički model prepoznavanja semantičkih dijelova web
stranica, napravljen ovim radom, donosi sastoji se u mogućnosti dohvaćanja stranica
sa semantičkom organizacijom bez nužne ovisnosti o programerima. S druge strane,
model je fleksibilan i može iskoristiti prednosti metapodataka semantičkog weba i
metapodataka standarda Schema.org te tako predstavlja univerzalnu početnu točku za
semantičkom segmentacijom web stranica.
Osim dinamičkog modela, napravljena je označna ekstenzija i poslužitelj. Označna
ekstenzija, napravljena kao Google Chrome ekstenzija, omogućava označivačima
diljem svijeta da označuju stranice, a zatim ih pošalju na poslužitelj.
Poslužitelj, osim pohranjivanja označenih stranica, služi za prezentaciju i dokumentaciju
sveukupnog koncepta, perzistenciju modela i sadrži komponentu za provjeru kvalitete
označenih stranica. Poslužitelj također pruža API putem kojeg se može pristupiti
dinamičkom modelu i preko kojeg se dobiva semantički segmentirana web stranica.
Sve tri opisane komponente s budućim Oculi agentima, koji će koristiti API na
poslužitelju, čine sustav Oculi. Namjena sustava Oculi je približiti web svim korisnicima i
dati svim statičkim komponentama stranica semantičku vrijednost.
Ključne riječi: Prepoznavanje semantičkih dijelova, Web, Strojno učenje, Semantički
Web
79
8. Summary
Tomislav Tenodi
Dynamic identification of web page parts
Web, with nearly a billion websites online, acts as the primary data source of today's
people. Semantic web or other standards, like Schema.org enable website
programmers to make their websites accessible without human interaction. However,
these concepts often do not represent interest to website programmers.
The advantage and novelty that dynamic model for semantic recognition of website
parts, discussed within this work, brings along is that it allows retrieving semantically
organised websites without the necessary dependency towards programmers. On the
other hand, it is flexible and can create advantage of the usage of semantic web
metadata or Schema.org metadata, which makes it universal starting point for semantic
segmentation of websites.
Along with dynamic model, labeling extension and server were created. Labeling
extension, made as Google Chrome extension, allows taggers across the world to label
websites which are then sent to server.
Server, in addition to storing labeled website, serves for presentation and
documentation of overall concept, persistence of the model and contains component for
evaluating the quality of labeled websites. Server also provides an API, through which
dynamic model is used and one can get semantically segmented website.
All three described components, together with the future Oculi agents, who will use the
API of the server, make the Oculi system. The Oculi system intends to bring web closer
to all of its users and to give all static page components semantic value.
Keywords: Recognition of semantic parts, Web, Machine learning, Semantic Web