České vysoké učení technické v Praze Fakulta informačních technologií Katedra softwarového inženýrství . . . (18102)
Magisterská práce
Agregátor slevových nabídek s doporučovacím systémem Bc. Martin Vehovský
Vedoucí práce: Ing. Ivo Lašek
9. května 2012
Poděkování Chtěl bych poděkovat vedoucímu práce Ing. Ivu Laškovi za přínosné připomínky a metodické vedení práce. Dále bych chtěl poděkovat Mgr. Ladislavu Peškovi z Matematicko-fyzikální fakulty Univerzity Karlovy v Praze za cenné rady při návrhu doporučovacích algoritmů.
Prohlášení Prohlašuji, že jsem předloženou práci vypracoval samostatně a že jsem uvedl veškeré použité informační zdroje v souladu s Metodickým pokynem o etické přípravě vysokoškolských závěrečných prací. Beru na vědomí, že se na moji práci vztahují práva a povinnosti vyplývající ze zákona č. 121/2000 Sb., autorského zákona, ve znění pozdějších předpisů, zejména skutečnost, že České vysoké učení technické v Praze má právo na uzavření licenční smlouvy o užití této práce jako školního díla podle § 60 odst. 1 autorského zákona.
V Praze dne 9. května 2012
..................... 7
České vysoké učení technické v Praze Fakulta informačních technologií c 2012 Martin Vehovský. Všechna práva vyhrazena.
Tato práce vznikla jako školní dílo na Českém vysokém učení technickém v Praze, Fakultě informačních technologií. Práce je chráněna právními předpisy a mezinárodními úmluvami o právu autorském a právech souvisejících s právem autorským. K jejímu užití, s výjimkou bezúplatných zákonných licencí, je nezbytný souhlas autora.
Odkaz na tuto práci Martin Vehovský. Agregátor slevových nabídek s doporučovacím systémem: Magisterská práce. Praha: ČVUT v Praze, Fakulta informačních technologií, 2012.
Abstract This thesis describes the design, implementation and testing of web application aggregating deals from group buying websites. The first part of this thesis is focused on analyzing the existing solutions trying to find opportunities for improvement. Follows design and implementation of project that is divided into several parts. First is application that aggregates deals from different group buying websites. Second, web application part serve as presentation for end customer. Next part is dedicated to exploring options in the field of recommender systems. Based on this research is designed recommender system that uses collaborative and content-based filtering. Keywords Thesis, deals aggregator, collective buying, recommender systems, collaborative filtering, content-based filtering, XML parser, full text search
Abstrakt Tato diplomová práce se zabývá návrhem, implementací a testováním webového portálu agregujícího nabídky slevových serverů. Nejdříve jsou analyzována existující řešení s cílem nalézt možnosti pro vylepšení. Následuje návrh a implementace projektu, který je rozdělen do několika částí. První částí je aplikace, která agreguje nabídky jednotlivých slevových serverů. Druhá, webová část, slouží k prezentaci nabídek koncovým uživatelům. Další část je věnována rešerši možností v oblasti doporučovacích systémů. Na základě tohoto průzkumu je navržen systém doporučování využívající kolaborativní filtrování a filtrování na základě obsahu nabídek. 9
Klíčová slova Závěrečná práce, agregátor slev, kolektivní nakupování, doporučovací systémy, kolaborativní filtrování, content-based filtrování, XML parser, fulltextový vyhledávač
10
Obsah Úvod 1 Existující řešení 1.1 Slevové agregátory . 1.2 Slevové servery . . . 1.3 Existující agregátory 1.4 Další řešení . . . . . 1.5 Shrnutí . . . . . . .
17
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
19 19 19 22 29 29
2 Analýza 2.1 Byznys Požadavky . . . . . . . 2.2 Situační analýza . . . . . . . . 2.3 Rozbor požadavků . . . . . . . 2.4 Analýza uživatelského rozhraní 2.5 Kolaborativní filtrování . . . . 2.6 Content-based doporučování . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
31 31 31 34 37 40 45
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
3 Návrh 3.1 Webová aplikace . . . . 3.2 Parser XML feedů . . . 3.3 Fulltextový vyhledávač . 3.4 Doporučování . . . . . . 3.5 Použité návrhové vzory
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
47 48 53 54 55 58
4 Realizace 4.1 Webová aplikace . . . 4.2 Parser XML feedů . . 4.3 Fulltextový vyhledávač 4.4 Doporučování . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
61 61 68 75 82
. . . .
5 Testování 87 5.1 Testování experty . . . . . . . . . . . . . . . . . . . . . . . . . . 87 5.2 Selenium . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 5.3 Apache Benchmark . . . . . . . . . . . . . . . . . . . . . . . . . 90 11
5.4
Testování kvality doporučování . . . . . . . . . . . . . . . . . .
92
Závěr
93
Literatura
95
A Seznam použitých zkratek
99
B Obsah přiloženého CD
101
12
Seznam obrázků 1.1 1.2 1.3 1.4 1.5 1.6
Podíly obratů slevových serverů za období Zdroj [26] . . . . . . . . . . . . . . . . . . Skrz.cz - Domovská stránka . . . . . . . . SlevyDnes.cz - Filtrování slev . . . . . . . Slevin.cz - Filtrování slev . . . . . . . . . Sleviste.cz - Domovská stránka . . . . . . ZlateSlevy.cz - Domovská stránka . . . .
leden až . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11. . . . . . . . . . . . .
únor . . . . . . . . . . . . . . . . . .
2011. . . . . . . . . . . . . . . . . . . . . . . . .
20 23 24 26 27 28
2.1
Task Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
3.1 3.2 3.3 3.4 3.5 3.6 3.7
Abstraktní pohled na projekt . . . . . . . . . . . . . . Lo-fi prototyp výsledků vyhledávání . . . . . . . . . . Návštěvnost sociálních sítí v ČR, zdroj Google Trends Tlačítka pro sdílení na sociálních sítích. . . . . . . . . Mapování kategorií . . . . . . . . . . . . . . . . . . . . Návrhový vzor Command, zdroj [6] . . . . . . . . . . . Návrhový vzor Facade, zdroj [6] . . . . . . . . . . . . .
. . . . . . .
47 49 50 51 53 58 59
Zend Framework - MVC pattern . . . . . . . . . . . . . . . . . . . Database schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . Formulář s nestandardní select komponentou . . . . . . . . . . . . Select element - pouze CSS styly . . . . . . . . . . . . . . . . . . . Stavy uživatele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diagram parsování XML s využitím SAX a návrhového vzoru Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7 Stejné ID pro různé nabídky - XML feed Slevopolis.cz . . . . . . . 4.8 Duplicity v XML feedu - Slevopolis.cz . . . . . . . . . . . . . . . . 4.9 Duplicity v XML feedu - MyDeals.cz . . . . . . . . . . . . . . . . . 4.10 Content-based doporučování - vektory pro nabídky z tabulky 4.2 . 4.11 Aho–Corasick - konečný automat, zdroj [1] . . . . . . . . . . . . .
62 65 66 66 68 69 74 74 75 83 84
5.1 5.2
91 92
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
4.1 4.2 4.3 4.4 4.5 4.6
Graf - Apache Benchmark . . . . . . . . . . . . . . . . . . . . . . . Graf - Testování kvality doporučování . . . . . . . . . . . . . . . .
13
Seznam tabulek 1.1 1.2
Specifikace formátu XML . . . . . . . . . . . . . . . . . . . . . . . Žebříček návštěvnosti podle Alexa Traffic Rank Checker . . . . . .
21 23
2.1
Jednoduchý příklad matice uživatel-položka [19] . . . . . . . . . .
43
4.1 4.2
Popis použitých filtrů ve schématu . . . . . . . . . . . . . . . . . . Smyšlené nabídky, pro účely výpočtu podobnostních vektorů . . .
79 83
15
Úvod Slevových agregátorů existuje v dnešní době na trhu celá řada a vznikají stále další. Žádný z agregátorů nepřišel již delší dobu s ničím novým a všichni se omezují na zobrazení všech dostupných nabídek, které je následně možné filtrovat dle kategorií, měst, atd. V záplavě existujících agregátorů je nutné se nějakým způsobem odlišit, z toho důvodu již od začátku byl projekt koncipován spíše jako vyhledávač slev, než jako slevový agregátor. Zpočátku se dokonce uvažovalo, že na hlavní stránce nebude nic jiného než vyhledávací pole a tlačítko hledej, jako je tomu v případě Googlu. Z tohoto důvodu bude třeba silná podpora fulltextového vyhledávání v nabídkách, v ideálním případě zavést i podporu vyhledávání dle kořenů slov. Další inovativní myšlenkou, která umožní odlišení od konkurence, je způsob zasílání nabídek na e-mail, který je agregátory často označovaný jako zpravodaj. Inspirací byla služba Google Alerts poskytující upozornění o nejnovějších výsledcích vyhledávání na Google. Zpravodaj by měl fungovat na stejném principu s tím, že budou zasílány nejnovější výsledky vyhledávání v nabídkách slev. Výzvou je najít optimální způsob, jakým doporučovat podobné nabídky. Přesto, že v běžných e-shopech funguje doporučování již velice dlouho, agregátory v této oblasti zaostávají. V dnešní době se za každé vylepšení doporučovacích algoritmů vyplácí vysoké sumy peněz, příkladem může být soutěž Netflix Prize s hlavní cenou 1 milion amerických dolarů. Prioritou tedy bude nalézt optimální algoritmus využívající buď kolaborativního filtrování, nebo filtrování, které je založené na podobnosti obsahu nabídek. Teoretickou část práce tvoří kapitoly jedna, dvě a částečně kapitola tři. V první kapitole je provedena analýza existujících řešení na poli slevových agregátorů s cílem zjistit slabá a silná místa jednotlivých řešení. Ve druhé kapitole jsou analyzovány funkční i nefunkční požadavky na projekt a také obsahuje rešerši v oblasti doporučovacích systémů využívajících kolaborativní filtrování, nebo filtrování na základě obsahu. Praktickou část práce tvoří kapitoly tři, čtyři a pět. Je v nich rozebrán návrh, realizace a testování celého projektu, který je rozdělen do 4 částí webová aplikace, parser XML feedů, fulltextový vyhledávač a doporučovací systém. V kapitole tři je tedy postupně rozebrán návrh všech 4 částí projektu. 17
Úvod Kapitola čtyři se zabývá realizací, jsou zde popsány zajímavé části implementace. Poslední nedílnou součástí vývoje jakékoli aplikace je testování, které je rozebráno v kapitole pět.
18
KAPITOLA
Existující řešení 1.1
Slevové agregátory
Slevových agregátorů je spousta, Mixo 1 uvádí, že se v současnosti jejich počet blíží k 200. Důvodů, proč je jich tolik, je hned několik, náklady na vstup na trh nejsou nijak vysoké a potencionální zisk je při minimálních nákladech velice slušný. Většina agregátorů se od sebe liší hlavně grafickým designem a přehledností, protože co se funkčnosti týče nabízejí většinou velice podobné a často stejné funkce. Pokud už nějaký z agregátorů přijde s něčím novým a ostatní zjistí, že to funguje, netrvá dlouho a danou funkcionalitu implementují také [25]. I přes neustále narůstající počet agregátorů existuje řada věcí, které by mohly být udělány lépe.
1.2
Slevové servery
Předchůdci slevových serverů se objevili koncem roku 2009, jednalo se ale stále jen o obchody se zbožím ve značné slevě. Až začátkem dubna roku 2010 přišli první slevové servery jako takové, byl to Slevomat2 a Vykupto3 . Následovala obrovská vlna dalších slevových serverů a koncem února roku 2011 jich bylo bezmála 200. Za rok 2010 dosáhl obrat slevových portálů 350 – 400 milionů Kč, při průměrné 20% marži by zisk dosáhl 70 – 80 milionů Kč. Největší tržby měli provozovatelé serverů Slevomat, Zapakatel a Vykupto 1.1. Celkem se objevilo na 350 slevových portálů 4 , z nichž již řada zanikla [9] [26]. 1
Mixo.cz - Hitparáda světa akčních slev, dostupný z http://www.mixo.cz/cs/agregatory/ Slevomat.cz - dostupný z http://www.slevomat.cz/ 3 Vykupto.cz, dostupné z http://www.vykupto.cz/ 4 Mixo.cz - Hitparáda světa akčních slev, dostupný z http://www.mixo.cz/cs/weby-slev/ 2
19
1
1. Existující řešení
Obrázek 1.1: Podíly obratů slevových serverů za období leden až 11. únor 2011. Zdroj [26]
1.2.1
XML feed
Všechny slevové servery poskytují XML feed s aktuálně nabízenými slevami. Jediným, kdo XML feed neposkytuje veřejně, je Slevomat. Tagy ve feedech si každý ze serverů řeší z části po svém. Po analyzování řady feedů se dá říci, že struktura feedu vypadá více méně následovně. <SERVER>
1 <TITLE>Jen 350 Kč za vstupenku I. kategorie do Divadla Hybernia! Nechte se pohltit vášnivým příběhem! Buďte u~toho s~50\% primaslevou! <TITLE_SHORT>Taneční muzikál LUCREZIA BORGIA! Praha http://www.primasleva.cz/cache/images/ 20
1.2. Slevové servery Tabulka 1.1: Specifikace formátu XML Element <SERVER> <TITLE> <TITLE_SHORT> <MIN_CUSTOMERS> <MAX_CUSTOMERS> ...
Popis Obalovací element všech nabídek Obalovací element konkrétní nabídky Jednoznačný identifikátor slevy Popis nabízené slevy v několika málo větách Zkrácený popis slevy s nejdůležitějšími informacemi Obalovací element seznamu měst Město, kde je slevu možné uplatnit Obalovací element seznamu obrázků URL obrázku, který patří k nabídce URL adresa nabídky Začátek možnosti nákupu nabídky Konec možnosti nákupu nabídky Konkrétní kategorie nabídky Cena před slevou Cena po zlevnění Začátek možnosti uplatnění zakoupeného voucheru Konec možnosti uplatnění zakoupeného voucheru Obalovací element seznamu šťítků Konkrétní štítek Minimální počet zákazníků potřebný k aktivaci nabídky Maximální počet prodaných voucherů Celá řada dalších..
470x223-crop/lucrezia-borgia-pokus-2-pic.jpg http://www.primasleva.cz/praha/637-tanecnimuzikal-lucrezia-borgia/ 2012-04-02 00:00:00 2011-04-15 23:59:59 Kultura 699 350 2012-04-16 00:00:00 2011-05-31 00:00:00 muzikál 21
1. Existující řešení <MIN\_CUSTOMERS>10 <MAX\_CUSTOMERS>3000 Další elementy, které jsou někdy používány:
, , , , <WEB>, <EMAIL>, , , a řada dalších.
1.2.2
Affiliate programy
Zdrojem obživy pro agregátory jsou právě affiliate programy. Ne všechny slevové servery mají affiliate program, především pak ty malé, které právě začínají. To se pochopitelně argerátorům nelíbí, proč by měly podporovat někoho, kdo jim za přivedení uživatelů nic nedá? Jedním z takových důvodů je snaha mít co největší nabídku slev, což daný agregátor může odlišit od konkurence. Pro zprostředkování affiliate programů jsou nejčastěji využívany systémy CJ5 a eHub6 . Další možností je využít affiliate systém Rival7 , jehož tvůrcem je Martin Tavalášek, provozovatel agregátoru Skrz.cz [24]. Výhodou je jednotný XML Feed, s jednotnou strukturu kategorií a měst, navíc není nutné se starat o přidávání nových slevových serverů a sledování jejich affiliate programů, vše zajistí Rival. Nevýhodou je, že si samozřejmě nechává část provize od slevových serverů pro sebe [20]. Dva velké agregátory Zlaté Slevy8 a Slevín9 se dohodly na provozu nového provizního systému PayLo10 . PayLo tak bude mít možnost cílit na 50.000 návštěvníků denně a stát se konkurencí Rivala [27].
1.3 1.3.1
Existující agregátory Skrz.cz
Skrz.cz12 (Obrázek 1.2), jehož autorem je Martin Talavášek, je jedním z nejdéle fungujících argerátorů. K jeho založení došlo v roce 2010 [17]. Na snapshotu13 z 8.září je vidět, že v nabídce bylo 41 slev z 10 měst. 1.3.1.1
Popis
Jak je vidět podle Alexy(Tabulka 1.2), jedná se v současnosti o nejnavštěvovanější agregátor v České republice. Návštěvnost se podle autora pohybuje 5
http://www.cj.com/ http://ehub.cz/ 7 https://rival.cz/ 8 http://www.zlateslevy.cz/ 9 http://www.slevin.cz/ 10 https://www.paylo.cz/ 12 Skrz.cz, dostupné z http://skrz.cz/ 13 Internet Archive: Wayback Machine, doztupný z http://archive.org/ 6
22
1.3. Existující agregátory Tabulka 1.2: Žebříček návštěvnosti podle Alexa Traffic Rank Checker11 Server skrz.cz slevydnes.cz slevin.cz sleviste.cz zlateslevy.cz modreslevy.cz
Pořadí mezi CZ servery březen 2011[25] duben 2012 295 194 792 334 606 763 797 1.362 422 3.458 3.479 11.267
Obrázek 1.2: Skrz.cz - Domovská stránka
v desítkách tisíc návštěv denně [21]. Jeho velkou výhodou je dlouhé působení na trhu a především jako jediný agregátor spolupracuje se Slevomatem. Server nabízí filtrování podle kategorií a subkategorii, dále pak poměrně slušné vyhledávání ve slevách. Navíc nabízí svým uživatelům řadu výhod, například za každý nákup na skrz.cz dostane uživatel tzv. „zlaťáky“, což jsou virtuální peníze, za které může později nakupovat zdarma. „Zlaťáky“ je možné získat i za doporučování slev přátelům a psaní recenzí ke slevovým serverům. Další výhodou je například tzv. Ombudsman, který si klade za cíl pomáhat uživatelům při reklamacích a řešení problémů, které by při uplatňování voucherů mohly vzniknout. Je tedy zřejmé, že se serveru Skrz.cz daří, když si může dovolit poskytovat svým uživatelům takovéto výhody. Zajímavou novou funkcí je zobrazení slev na mapě, tady je ale Skrz.cz odkázán na milost slevovým serverům a ty bohužel adresu u řady slev neuvádí. 23
1. Existující řešení
Obrázek 1.3: SlevyDnes.cz - Filtrování slev
1.3.1.2
Výhody a nevýhody
Výhody • Velké množství slevových nabídek • Spolupracuje se Slevomatem • Bonus program ve formě „zlaťáků“, virtuálních peněz • Ombudsman, pomáhá uživatelům řešit problémy s uplatňováním voucherů Nevýhody • Omezené možnosti vyhledávání – doba vyhledávání – nízká relevantnost výsledků
1.3.2
SlevyDnes.cz
SlevyDnes14 (Obrázek 1.3) je další z velice oblíbených slevových agregátorů, který provozuje firma Dynamix investment. Jedná se o jeden z těch mladších agregátorů, jeho vznik se datuje do roku 2011 [17]. 14
24
SlevyDnes.cz, dostupné z http://www.slevydnes.cz/
1.3. Existující agregátory 1.3.2.1
Popis
Přesto, že SlevyDnes nebyly v té úplně první vlně slevových agregátorů, jsou momentálně 2. nejnavštěvovanějším agrerátorem, viz. Tabulka 1.2. Od začátku vsadily na širokou nabídku slev všech možných slevových serverů, včetně těch, které nemají žádný affiliate program. Tento krok se evidentně vyplatil. Jak je vidět z Obrázku 1.3, celkový dojem ale kazí obrovský panel úplně nahoře na stránce, který slouží k filtrování nabídek. Mezi další funkce patří e-mailový zpravodaj, snadné doporučení slevy známým opět přes e-mail a vyhledávání v nabízených slevách. Přesto, že SlevyDnes inzerují, že nabízí slevy i od Slevomatu, ve skutečnosti tomu tak není. 1.3.2.2
Výhody a nevýhody
Výhody • Nejširší nabídka slev ze všech agregátorů
15
Nevýhody • Méně přehledné filtrování • Načítání všech slevy bez stránkování - při pomalém připojení je web takřka nepoužitelný • U slevového zpravodaje je možné nastavit pouze hlavní kategorii - denní záplava nezajímavých slev • Nízká relevantnost výsledků vyhledávání
1.3.3
Slevin.cz
Slevin 16 (Obrázek 1.4) provozovaný stejnojmennou firmou je dalším velkým hráčem na poli agregátorů, vznikl v roce 2010 [17]. 1.3.3.1
Popis
Jedná o 3. nejnavštěvovanější agregátor v České republice, viz. Tabulka 1.2. Snad jako jediný každý den ručně zkracuje popisky jednotlivých slev, díky tomu je zobrazení slev mnohem úspornější a nezabere tolik místa. Pokud uživatele zkrácený popisek zaujme, může si buď zobrazit celý popisek, nebo přejít rovnou na stránky poskytovatele slevy. Nabízeno je standardní filtrování slev, vyhledávání ve slevách a jejich zasílání na e-mail. Další předností tohoto agregátoru je aplikace pro mobilní telefony s OS Android nazvaná Slevoid. 15 16
Bohužel není možné prakticky ověřit, zda všech 3000 inzerovaných slev je unikátních Slevin.cz, dostupný z http://slevin.cz/
25
1. Existující řešení
Obrázek 1.4: Slevin.cz - Filtrování slev
1.3.3.2
Výhody a nevýhody
Výhody • Ruční zkracování popisků jednotlivých slev • Rychlé filtrování a vyhledávání • Aplikace pro OS Android Nevýhody • Nízká relevantnost výsledků vyhledávání
1.3.4
Sleviste.cz
Sleviste17 (Obrázek 1.5) působí na trhu od roku 2010 [17], koncem listopadu stejného roku bylo nabídnuto k prodeji a záhy bylo koupeno vydavatelstvím Ringier [25]. 1.3.4.1
Popis
[25] Od koupi společností Ringier se Slevisti poměrně daří, a to díky propagaci v tištěných médiích. [15] Ringier má ve svém portfoliu 26 tištěných titulů, 17
26
Sleviste.cz, dostupné z http://www.sleviste.cz/
1.3. Existující agregátory
Obrázek 1.5: Sleviste.cz - Domovská stránka
mezi které patří například Blesk, nejčtenější bulvární deník v ČR. Momentálně je Sleviště 4. nejnavštěvovanějším agregátorem v ČR, viz. Tabulka 1.2. Zajímavou funkcí je bazar slevových kuponů, kde mohou lidi prodat zakoupené vouchery, například, pokud vědí, že voucher nestihnou uplatnit. Nabízí dokonce aplikace pro mobilní telefony s iOS i Android. 1.3.4.2
Výhody a nevýhody
Výhody • Bazar slevových kuponů • Aplikace pro mobilní telefony iOS a Android Nevýhody • Nižší přehlednost a omezenější možnosti filtrování • Velice nízká relevantnost výsledků vyhledávání 27
1. Existující řešení
Obrázek 1.6: ZlateSlevy.cz - Domovská stránka
1.3.5
ZlateSlevy.cz
ZlateSlevy18 (Obrázek 1.6) provozované firmou Neogenia působí na trhu již od září roku 201019 . 1.3.5.1
Popis
Za poslední rok agregátoru postupně klesá návštěvnost, ještě v březnu 2011, viz. Tabulka 1.2, byl 2. nejnavštěvovanějším v České republice, nyní je s poměrně velkým odstupem na 5. místě. K propagaci mu pomáhá server SMSbrana.cz, který je provozován stejnou firmou. Nabízí standardní filtrování slev i fulltextové vyhledávání, které je ale aktuálně mimo provoz. Při odebírání newsletteru jsou uživatelé zařazeni do měsíčního slosování o zajímavé ceny, jako jsou zájezdy, masáže, apod. Nabízeny jsou aplikace pro iOS i Android. 1.3.5.2
Výhody a nevýhody
Výhody 18
ZlateSlevy.cz, dostupné z http://www.zlateslevy.cz/ Zdrojem informace Internet Archive: Wayback z http://archive.org/ 19
28
Machine,
doztupný
1.4. Další řešení • Měsíční slosování o zajímavé ceny • Aplikace pro mobilní telefony iOS a Android • Zajímavý design stránek k názvu „Zlaté Slevy“ Nevýhody • Nefunkční vyhledávání • Složitější filtrování v nabídkách • Příliš mnoho možností nastavení pro odebírání newsletteru
1.4
Další řešení
Na trhu slevových agregátorů je celá řada dalších zajímavých řešení, většina z nich se ale jen snaží kopírovat funkce již zajetých agregátorů a pak se zviditelnit reklamami na Facebooku, Google AdWords, partnerskými servery, apod [24].
1.5
Shrnutí
Analýzou existujících řešení jsem došel k závěru, že je stále co zlepšovat. Jako největší problém pro většinu méně zkušených uživatelů se jeví méně přehledné filtrování nabídek a především ne příliš dobře fungující vyhledávání. Lidé jsou zvyklí z Googlu nebo Seznamu, že příliš nezáleží na tom, zda vyhledají slovo v jednotném nebo množném čísle, vždy dostanou nějaké výsledky. Další problém jsou slevové zpravodaje, které nabízejí všichni agregátoři, ale nastavení odebíraných kategorií je příliš obecné. Lidé pak dostávají na e-mail desítky nezajímavých nabídek a snadno tak přehlédnou ty, které je skutečně zajímají.
29
KAPITOLA
Analýza Ve fázi analýzy by mělo dojít k sestavení jasných požadavků na implementovaný projekt. Mělo by být jasné jakých funkcionalit chceme dosáhnout a jakým nárokům je třeba vyjít vstříc.
2.1
Byznys Požadavky
Spíše známé pod anglickým názvem Business requirements, představují nejabstraktnější pohled na vytvářený projekt. Jsou to cíle nejvyšší úrovně, nic už ale není řečeno o tom, jak těchto cílů má být dosaženo. Tyto požadavky vznikly analýzou zadání diplomové práce a průzkumem existujících řešení na trhu. BP 1: Agregátor slevových nabídek. BP 2: Kvalitní doporučování podobných slev. BP 3: Vyhledávač slevových nabídek. BP 4: Moderní a přehledný design.
2.2
Situační analýza
V předchozí kapitole jsem se věnoval analýze existujících řešení, zjišťoval, jaké funkce jsou současnými agregátory nabízeny, co je na nich dobré a co nikoli. Po konzultaci této analýzy se zadavatelem (vedoucím práce) byl sestaven seznam funkčních požadavků, který se následně stal součástí FURPS+ analýzy, která pohlíží na kvalitu softwaru z 5 různých hledisek. 31
2
2. Analýza
2.2.1 2.2.1.1
FURPS+ Funkčnost
F 1: Pravidelná kontrola XML feedů slevových serverů pro evidování nových slev. F 2: Snadné přidání nového slevového serveru. F 3: Automatické zařazování nabídek do definovaných kategorií. F 4: Možnost vyhledávání v nabídkách. F 4.1: Umožnit vyhledávání podle kořenů slov F 4.2: Upřednostňovat zajímavé slevy a ty, u kterých končí možnost zakoupení. F 5: Možnost filtrování nabídek podle kritérií. F 6: Přehledné zobrazení nabídek. F 6.1: Zobrazit jak dlouho je ještě možné nabídku pořídit. F 6.2: Zobrazit procentuální slevu nabídky. F 6.3: Zobrazit server, který slevu nabízí. F 7: Možnost hodnocení slevových serverů - psaní recenzí F 7.1: Možnost ohodnotit přínosnost recenze F 7.2: Upřednostňovat přínosnější recenze F 8: Evidence uživatelů F 8.1: Možnost jednoduché registrace F 8.2: Možnost trvalého přihlášení uživatele F 9: Propojení se sociálními sítěmi - Facebook a Google+ F 9.1: Možnost sdílení konkrétní nabídky přes sociální sítě F 9.2: Možnost přihlášení uživatele přes Facebook F 10: Možnost odesílání nabídek na e-mail - newsletter. F 10.1: Možnost nastavení klíčových slov, která musí nabídka obsahovat. F 10.2: Možnost nastavení frekvence zasílání newsletteru. F 10.3: Možnost nastavení počtu nabídek v newsletteru. 32
2.2. Situační analýza F 10.4: Možnost slučování newsletterů F 11: Možnost logování činnosti uživatelů F 11.1: Zobrazení detailu konkrétní nabídky F 11.2: Navštívení konkrétní nabídky F 11.3: Vyhledávané fráze F 12: Možnost doporučování slev. F 12.1: Doporučování slev na Homepage. F 12.2: Doporučování podobných slev, při navštívení konkrétní slevy. 2.2.1.2
Spolehlivost
R 1: Vysoká spolehlivost – především proto, že existuje takové množství agregátorů, takže nechceme dát uživateli důvod jít jinam R 2: Vysoká dostupnost – 24 / 7 / 365 R 3: MTFB (Mean Time Between Failures) a MTTR (Mean Time To Recovery) 2.2.1.3
Užitečnost
U 1: Systém by měl bezproblémově fungovat ve všech majoritních i minoritních prohlížečích – Internet Explorer, Mozilla Firefox, Google Chrome, Opera, Safari U 2: Není požadována podpora starších verzí těchto prohlížečů, pouze aktuální stabilní verze U 3: Moderní design aplikace 2.2.1.4
Výkon
P 1: Doba odezvy by měla být co nejnižší, mezi 200 - 400 ms P 1.1: Obrázky načítat asynchronně, aby bylo možné se stránkou normálně pracovat ještě před načtením obrázků P 2: Počet uživatelů paralelně využívajících tuto aplikaci P 2.1: V raných fázích se počet uživatelů bude pochybovat v řádu desítek 33
2. Analýza 2.2.1.5
Nefunkční požadavky
NF 1: Technologické řešení – Java, PHP a MySQL NF 2: Projekt bude rozdělen do 3 částí - parser XML feedů, fulltextový vyhledávač, webová aplikace NF 3: Webová aplikace bude naprogramována v jazyce PHP NF 3.1: Použití Zend Frameworku podmínkou NF 3.2: Použití libovolného ORM frameworku, či jiných užitečných frameworků výhodou NF 4: Back-endové technologie jako parser XML feedů a fulltextový vyhledávač budou v jazyce Java NF 4.1: Fulltextové vyhledávání bude řešeno pomocí Apache Solr
2.3
Rozbor požadavků
Řada zmíněných funkčních požadavků z FURPS+ analýzy proto nemusí být pro nezainteresovaného člověka na první pohled jednoznačná. Druhý nefunkční požadavek NF 2 říká, že projekt bude rozdělen do 3 částí - parser XML feedů, fulltextový vyhledávač, webová aplikace. Jednotlivé požadavky se vztahují k jedné z těchto tří částí, k jaké a co přesně znamenají, rozeberu v následujících podkapitolách.
2.3.1
Požadavky na parser XML feedů
Z nefunkčního požadavku NF 4 zjistíme, že má být parser XML feedů naprogramován v programovacím jazyku Java. Důvodů k tomu je hned několik, obecné vlastnosti jazyka Java jako je multiplatformnost a stabilita runtime prostředí samozřejmě sehrály svou roli. Důraz byl ale u parseru kladen na propojení s s fulltextovým vyhledávačem, open-source projektem Apache Solr, který je rovněž naprogramován v jazyku Java, pro kterou poskytuje kvalitní API. Co se funkčních požadavků na parser týče, patří sem F 1, který mluví o pravidelné kontrole XML feedů slevových serverů. Cron bude automaticky parser spouštět v definovaných intervalech, tyto intervaly budou pravděpodobně v rozmezí 10 minut až 1 hodiny, až bude zjištěno, jak často se feedy mění a je nutné je aktualizovat. Požadavek F 2 klade důraz na snadné přidání nového slevového serveru do parseru. Seznam slevových serverů a jejich XML feedů načítat z databáze. Parser musí být dostatečně abstraktní a vypořádat se i s případy, že nový server přidá do svého XML feedu neznámý tag, který parser neví, jak zpracovat. 34
2.3. Rozbor požadavků Požadavek F 3 požaduje automatické zařazování nabídek do definovaných kategorií. Každý slevový server může nazvat stejnou kategorii jiným termínem, např. někdo použije kategorii nazvanou "Gastronomie", jiný "Jídlo a pití"a třetí z toho udělá kategorie dvě "Jídlo"a "Pití". Z tohoto důvodu je nutné provést mapování kategorii a pokud narazíme na neznámou kategorii, musí být uložena, aby mohla být později ručně namapována. Podobně to platí i o městech, například "Praha západ"i "Praha centrum"by měla být sjednocena pod jedno město "Praha".
2.3.2
Požadavky na fulltextový vyhledávač
Jak již bylo řečeno a jak uvádí nefunkční požadavek NF 4.1, pro fulltextové vyhledávání bude použit Apache Solr. Jedná se o open-source projekt, který je postavený na Apache Lucene. Mezi hlavní vlastnosti patří velice dobré fulltextové vyhledávání, zvýrazňování shodujících se slov, filtrování výsledů vyhledávání, dynamické klustrování, integrace s databází, podpora dokumentů ve formátech word, pdf. atd. Solr je tedy naprogramovaný v jazyce Java, který běží jako samostatný fulltextový vyhledávací server. Funkční požadavek F 4, bude splněn samotným nasazením fulltextového vyhledávače Apache Solr, který vyhledávání v nabídkách umožní. Složitější je ovšem požadavek F 4.1, který požaduje vyhledávání podle kořenů slov, tedy například dotaz "steaky v Praze"by měl vrátit stejné výsledky, jako "steak Praha". Požadavek F 4.2 potom požaduje upřednostňování zajímavých nabídek a těch, kterým končí platnost. Obecně zatím není jasné, co bude rozhodujícím kritériem toho, že je sleva zajímavá. Musí ale existovat možnost, jak podle nějakého parametru slevu posunout na přední pozice ve výsledcích vyhledávání. Posledním funkčním požadavkem, který se vztahuje k fulltextovému vyhledávači, je požadavek F 5, tedy možnost filtrování nabídek podle kritérií, jako jsou například kategorie, města nebo štítky.
2.3.3
Požadavky na webovou aplikaci
Všechny funkční požadavky od F 6 jsou již na samotnou webovou aplikaci. Než se k nim dostanu, za zmínku stojí nefunkční požadavek NF 3.1, zadavatel totiž z důvodu jeho zkušeností s vývojem webových aplikací v Zend Frameworku20 vyžadoval jeho použití. Nefunkční požadavek NF 3.2 mluví o použití libovolného ORM frameworku, či jiného užitečného frameworku, to proto, že zadavatel (vedoucí práce) požaduje co nejstandardizovanější přístup, aby případně později mohl kdokoli ve vývoji projektu pokračovat a nemusel studovat moje vlastní knihovny vytvořené jen pro účely této diplomové práce. Požadavky F 6, 6.1, 6.2 a 6.3 jsou spojené s přehledným zobrazením nabídek, jde o to, aby všechny podstatné informace byly okamžitě viditelné, ale 20
Zend Framework, dostupný z http://framework.zend.com/
35
2. Analýza zároveň aby množství zobrazených informací neubíralo na přehlednosti. Pro uživatele není nic horšího než stránka přeplácaná informacemi, v které je těžké se na první pohled zorientovat. Požadavky F 7, 7.1, a 7.2 jsou spojené s psaním recenzí o slevových serverech. Idea samozřejmě pochází od srovnávačů cen, které umožňují napsat recenzi k jednotlivým produktům, nebo samotným e-shopům. U slevového agregátoru je však psaní recenzí k jednotlivým slevám bezpředmětné a to především z velmi omezeného času, kdy je slevu možno zakoupit. Proto je rozumnější se podělit o názor na samotný server, který slevu poskytl. Požadavky F 8, 8.1, a 8.2 hovoří o evidenci uživatelů, která bude důležitá především kvůli správě zpravodajů (newsletterů), po přihlášení bude mít uživatel možnost spravovat své zpravodaje, rušit je nebo přidávat nové. Registrace by měla být co možná nejjednodušší, nechce uživatele odrazovat vyplňováním spousty osobních údajů. Nebude ani vyžadováno potvrzení registrace na zadané e-mailové adrese, pokud uživatel zadá neexistující adresu, je už na něm, aby si pro každý zpravodaj nastavil ručně správný e-mail. Dále je žádoucí, aby se uživatel nemusel stále znovu přihlašovat, proto požadavek F 8.2 hovoří o trvalém přihlášení uživatele, které bude řešeno pomocí cookie. Požadavky F 9, 9.1, a 9.2 jsou spojené se sociálními sítěmi, které jsou v současné době obrovským fenoménem. Uživatelé proto musí mít možnost stisknutím jednoho tlačítka sdílet pro ně zajímavou slevu na vybrané sociální síti. Dalším bonusem pro uživatele sociální sítě Facebook je ten, že se nebudou muset registrovat, pro přihlášení a následnou zprávu svých zpravodajů budou moci využít svůj účet na Facebooku, to vše stisknutím jediného tlačítka. Požadavky F 10, 10.1, 10.2, 10.3 a 10.4 jsou spojené se slevovým zpravodajem, často označovaným jako newsletter. Ten by měl fungovat poněkud jinak, než je zvykem u existujících slevových agregátorů. Myšlenka je založená na službě Google Alert, nastavíme si jaká klíčová slova musí daná nabídka obsahovat a pokud se taková nabídka objeví, budeme informováni e-mailem. Tímto způsobem bude možné zasílat jen takové nabídky, které uživatele zajímají, ten nebude nucen procházet desítky nabídek denně, jen aby nakonec stejně zjistil, že ho nic nezaujalo. Příliš veliký počet zasílaných nabídek může narazit na problém lenosti uživatelů, ti si přečtou prvních 5 - 10 nabídek, zjistí, že je žádná nezaujala a další již prohlížet nebudou. To je běžná praxe i z mé osobní zkušenosti, proto je třeba, aby zpravodaj byl více cílený na konkrétního uživatele. Za zmínku stojí ještě požadavek 10.4, slučovaní newsletterů je myšleno tak, že pokud si uživatel vytvoří více newsletterů, které si nechá posílat na stejný email, přijdou mu všechny v jednom mailu. Požadavky F 11, 11.1, 11.2 a 11.3 souvisí s logováním činnosti uživatelů při užívání webové aplikace. Musí být zaznamenány všechny důležité činnosti, které uživatel provedl. Logovat budeme vyhledávané fráze, informace o tom, jaké slevy uživatel navštívil, dokonce i informace o zobrazení detailu slevy. Logování umožní využití různých doporučovacích algoritmů, které potřebují informace o tom, jakým způsobem se jednotliví uživatelé na stránkách chovají. 36
2.4. Analýza uživatelského rozhraní Požadavky F 12, 12.1 a 12.2 jsou na doporučování slev, půjde hlavně o to najít vhodný algoritmus pro doporučování slev na homepage a podobných slev při navštívení detailu slevy. Oproti doporučovacím algoritmům, které se používají např. v e-shopech, je zde mnohem kratší životnost doporučovaných položek, většina slev není v průměru aktivní déle než týden.
2.4
Analýza uživatelského rozhraní
Tato analýza vznikla jako část semestrální práce na předmět MI-NUR - Návrh uživatelského rozhraní. Cílem práce bylo vytvořit uživatelsky přívětivé rozhraní, k tomu je zapotřebí vědět, jaké činnosti bude uživatel se systémem provádět, tyto činnosti kategorizovat a výsledné uživatelské rozhraní jim přizpůsobit. Následně vytvořit prototyp tohoto rozhraní, nechat ho otestovat uživatelům, zapracovat připomínky, atd.
2.4.1
Use Cases Brainstorming
V této části analýzy je podstatné zachytit všechny možné i nemožné interakce s uživatelem. Není podstatné, zda daná interakce bude nakonec ve výsledném produktu, proto se jedná o "Brainstorming". Interakce, které nebudou dávat smysl, nebo budou duplicitami jiných interakcí přesto, že na první pohled tento fakt není zřejmý, budou odstraněny v dalších fázích analýzy. • Měl by umožnit vyhledávání v nabídkách • Měl by umožnit přehledné zobrazení nabídek • Měl by umožnit filtrování nabídek podle kritérií - kategorie, města, tagu, serveru • Měl by zobrazit jak dlouho je nabídku ještě možné pořídit • Měl by zobrazit procentuální slevu každé nabídky • Měl by vybírat nejzajímavější nabídky dne - ručně, automaticky, podle počtu zakoupeni • Měl by umožnit odesílání nabídek na e-mail - Newsletter • Měl by umožnit nastavit, jak často chci Newsletter dostávat • Měl by umožnit nastavit maximální počet nabídek v Newsletteru • Měl by umožnit filtrování nabídek v Newsletteru podle kritérií - kategorie, města, tagu • Měl by umožnit napsání recenze k zakoupené slevě 37
2. Analýza • Měl by umožnit napsání recenze o slevovém serveru, ze kterého byla sleva zakoupena • Měl by mít funkci zobrazení důvěryhodnosti slevového serveru • Měl by preferovat nabídky známých/důvěryhodných serverů před méně známými • Měl by umět předpovídat na základě statistik, například kdy se objeví další nabídka na masáž v Praze • Měl by automaticky odfiltrovat podvodné nabídky • Měl by poskytovat nápovědu • Měl by poskytovat odpovědi na často kladené dotazy
2.4.2
Use Cases analysis
Po fázi brainstormingu by jsme si měli dát minimálně denní pauzu a následně kriticky zhodnotit interakce, které byly vymyšleny. Pokud byl brainstorming prováděn v teamu, bylo by vhodné, aby tyto dvě fáze prováděly jiné teamy. Za nevhodné se ukázaly tyto interakce: • Měl by umožnit filtrování nabídek v Newsletteru podle kritérií - kategorie, města, tagu • Měl by umožnit napsání recenze k zakoupené slevě • Měl by mít funkci zobrazení důvěryhodnosti slevového serveru • Měl by preferovat nabídky známých/důvěryhodných serverů před méně známými • Měl by umět předpovídat na základě statistik, například kdy se objeví další nabídka na masáž v Praze • Měl by automaticky odfiltrovat podvodné nabídky
2.4.3
Task List a Task Analysis
Metodicky by bylo správně udělat tyto dvě části odděleně, ale vzniknou v podstatě dva totožné seznamy, rozdíl je pouze v tom , že jeden seznam je strukturovaný a druhý nikoli, proto jsem se rozhodl tyto dvě části spojit. Cílem je vytvořit z uživatelských interakcí se systémem, které vznikly při brainstormingu, pokud možno atomické požadavky. • Zobraz homepage 38
2.4. Analýza uživatelského rozhraní • Vyhledej nabídku • Filtruj zobrazené nabídky - kategorie, města, štítku • Zobraz nejlepší nabídky dne • Zobraz nabídku – jak dlouho bude nabídka ještě aktivní – procentuální slevu – informace o slevovém serveru – podrobnosti • Odešli nabídky na e-mail • Nastav časový interval • Nastav počet nabídek • Napiš recenzi ke slevovému serveru • Zobraz formulář pro napsání recenze • Zobraz nápovědu • Zobraz FAQ
2.4.4
Task Groups
Přesto, že je výše uvedený „Task List“ strukturovaný a poměrně přehledný, když se nad danými požadavky zamyslíme, dají se rozdělit do dvou skupin. Zobrazení • Zobraz homepage • Zobraz nejlepší nabídky dne • Zobraz nabídku • Zobraz formulář pro napsání recenze • Zobraz nápovědu • Zobraz FAQ Uživatelské akce • Vyhledej nabídku • Filtruj nabídky - kategorie, města, štítku 39
2. Analýza
Obrázek 2.1: Task Graph
• Napiš recenzi ke slevovému serveru • Nastav odesílání nabídek na e-mail - Newsletter • Nastav počet nabídek a časový interval Newsletteru
2.4.5
Task Graph
Slouží pro lepší přehlednost a zobrazení vztahu mezi jednotlivými uživatelskými akcemi. Jednotlivé skupiny akcí jsou zobrazeny jinou barvou. Často se uvádí pouze hlavní akce, která může být rozdělena na několik menších, například jsem v následujícím grafu, Obrázek 2.1, spojil akce týkající se newsletteru do jedné zvané "Odebírej Newsletter".
2.5
Kolaborativní filtrování
Kolaborativní filtrování je založené na myšlence z běžného života, každý den spoléháme na doporučení známých, odborných časopisů, novin, televize, atd. Často je to jediný způsob jak se v dostatečně rychlém čase zorientovat mezi desítkami, stovkami, tisíci produkty či službami. Těchto doporučení je mnoho a jsou cílené na různé skupiny lidí. Na jaké doporučení dáme, se rozhodujeme např. podle podobnosti zájmů s doporučitelem. Z této myšlenky vychází kolaborativní filtrování, která musela být samozřejmě přizpůsobena vlastnostem a možnostem internetového prostředí [19] .
2.5.1
Sběr dat
Lidé si typicky chtějí na internetu udržet určitý stupeň anonymity, především pak u stránek, které neznají a tedy jim zatím nedůvěřují. Proto preference jednotlivých uživatelů mohou být zjišťovány 2 způsoby a to buď s aktivním zapojením uživatele, nebo bez jeho vědomí. 40
2.5. Kolaborativní filtrování 2.5.1.1
Explicitní feedback
Typickým příkladem explicitního feedbacku je zapojení uživatele, který ohodnotí zakoupený produkt, napíše recenzi přečtené knihy, atd. Dá se předpokládat, že tento uživatel poskytne objektivní názor na produkt či službu s kterou přišel do kontaktu. Problém ale je, že spousta lidí považuje takovéto hodnocení za ztrátu času, navíc je běžné, že lidé mnohem častěji vyjádří tímto způsobem svou nespokojenost než naopak. Množství získaných dat pro účely kolaborativního filtrování je proto poměrně malé, což by mělo dopad na kvalitu doporučování. 2.5.1.2
Implicitní feedback
Častěji je tedy využíváno implicitního feedbacku, což je způsob, při kterém není potřeba interakce s uživatelem. Jsou shromažďovány informace o tom, jaké produkty uživatel zakoupil, jaké produkty navštívil, jaké rádiové stanice poslouchal, jaké fráze vyhledával, atd. Záleží na charakteru webu a co je pro něj klíčové. Důležitým faktorem je doba strávená na dané stránce, pokud je velice krátká, dá se předpokládat, že se uživateli stránka nezamlouvá. Dat získaných tímto způsobem je již mnohem více.
2.5.2
Výzvy a problémy Kolaborativního filtrování
V době, kdy nekvalitní doporučení mohou znamenat ztrátu zákazníka je extrémně důležité, aby doporučovací algoritmy poskytovaly kvalitní doporučení. Existuje řada problémů, které je třeba překonat [19] [10]. 2.5.2.1
Řídkost Dat
Tento problém může nastat v několika situacích, především při tak zvaném „studeném startu“, tedy například přidáním nového zboží do katalogu, nebo při příchodu nového uživatele. Ve zmíněných případech není dostatek informací k tomu, aby mohly být vytvořeny kvalitní doporučení. „Pokrytím“ často označujeme procento položek, pro které jsme schopni generovat kvalitní doporučení. Problém „malého pokrytí“ pak nastává v případě že máme mnoho položek, pro které není k dispozici hodnocení uživatelů. Problém „transitivity sousedů“ je případ, kdy dva uživatelé s podobným vkusem nebudou označení za podobné díky tomu, že neohodnotili ani jednu stejnou položku [19] [11] . 2.5.2.2
Škálovatelnost
Je typickým problémem naprosté většiny algoritmů kolaborativního filtrování, kdy výpočetní náročnost se stává neakceptovatelnou. Jak [19] uvádí, pro desítky miliónů zákazníků (M) s milióny různých produktů (N) je i algoritmus 41
2. Analýza se složitostí online výpočtu O(n) příliš. Řada systémů musí být schopna generovat okamžitě kvalitní doporučení, bez možnosti offline předvýpočtu, což vyžaduje vysokou škálovatelnost [19]. 2.5.2.3
Ekvivalentnost
Ekvivalentností jsou myšleny případy, kdy stejné, nebo velice podobné položky jsou jinak označené, mají různé názvy. Většina algoritmů není schopna tento fakt odhalit a jednají s nimi jako s různými položkami. Například „children movie“ a „children film“ jsou ve skutečnosti rovnocenné, ale memory-based algoritmy by tento fakt neodhalily. A ve skutečnosti je ekvivalentnost v názvech položek vyšší než by se mohlo zdát. Ekvivalentnost výrazně snižuje efektivnost algoritmů. Tento problém je často řešen vytvořením slovníku a následným automatickým zpracováním ekvivalentních slov. Problém tohoto postupu však je, že se může stát, že slova mají jiný význam, než bylo předpokládáno, což dramaticky ovlivní efektivnost algoritmů [19]. 2.5.2.4
Šedé a černé ovce
Za „šedé ovce“ jsou považováni uživatelé, jejichž názor není konzistentní s žádnou jinou skupinou uživatelů a tedy pro ně kolaborativní filtrování nemůže být efektivní. Za „černé ovce“ jsou pak považováni uživatelé, jejichž výstřední vkus znemožňuje generování kvalitních doporučení. Protože jsou tyto extrémní případy problémem i pro běžné doporučovací způsoby, jsou považovány za akceptovatelnou chybu [19]. 2.5.2.5
Shilling Attacks
V případě, kdy je umožněno hodnocení všem, autoři či prodejci mohou poskytnout spoustu pozitivních recenzí pro své položky a naopak podat negativní hodnocení položek konkurence. Hůře se však odhalují případy falešných uživatelů s pečlivě spravovanými profily, kteří mají za úkol svést doporučení určitým směrem. Proto je žádoucí, aby od takového jednaní byly tito lidé nějakým způsobem odrazeni [19] [4]. 2.5.2.6
Další výzvy a problémy
Existují i další problémy, mezi které patří například ochrana soukromí, protože lidé často nechtějí, aby někdo věděl, jaké položky je zajímají. Výzvou pro doporučování je objasnění, proč by se daná položka měla uživateli líbit. Například informace typu „Tato kniha se Vám bude líbit, protože se Vám líbily tyto knihy..“ bude pro uživatele zajisté přínosná, bez ohledu na to, zda je zcela přesná [19]. 42
2.5. Kolaborativní filtrování Tabulka 2.1: Jednoduchý příklad matice uživatel-položka [19] U1 U2 U3 U4 U5
2.5.3
I1 4 4 3 4 2
I2 ? 2 4 1
I3 5 1 2
I4 5
3
5
4
Kategorizace
V literatuře nepanuje příliš shoda na kategorizaci jednotlivých algoritmů kolaborativního filtrování. [19] Rozděluje algoritmy do tří hlavních skupin. 2.5.3.1
Memory-Based
Do této skupiny patří algoritmy, které ke generování doporučení využívají celou nebo nějakým způsobem redukovanou matici uživatel-položka 2.1. Každý uživatel se stane součástí určité skupiny uživatelů s podobnými zájmy. Až se podaří identifikovat tzv. sousedy nového uživatele, je možné pro něj generovat kvalitní doporučení [19]. Výhody • Snadná implementace • Snadné přidání nových dat • Nemusí řešit obsah doporučovaných položek • Slušná škálovatelnost Nevýhody • Závislá na hodnocení uživatelů • Nízká kvalita doporučení při nedostatku dat • Nedokáže generovat doporučení pro nové uživatele či položky • Omezená škálovatelnost pro velké datasety 2.5.3.2
Model-Based
Využívají metod strojového učení, nebo vytěžování dat k vytvoření modelů, které pomohou v trénovacích datech odhalit vzory chování, pomocí kterých dokáží poskytnout kvalitní doporučení na testovacích nebo reálných datech. Do této skupiny patří například Bayesovské modely, klusterové modely, sítě 43
2. Analýza závislostí(dependency networks), které byly zkoumány zda budou schopny vyřešit některé problémy memory-based metod [19]. Výhody • Lépe si poradí s nedostatkem dat, škálovatelností i dalšími problémy • Vyšší kvalita doporučení • Dokáží podat rozumné vysvětlení pro dané doporučení Nevýhody • Náročnost vytvoření modelu • Musí být zvolen kompromis mezi kvalitou doporučení a škálovatelností • Ztráta důležitých informací při snaze překonat nedostatek dat 2.5.3.3
Hybrid
Kombinují kolaborativní filtrování s jinou metodou doporučování, typicky s Content-based doporučováním [19]. Výhody • Vyrovnají se s problémy Memory-Based i Model-Based algoritmů • Vyšší kvalita doporučení • Dokáží překonat nedostatek dat i šedé ovce Nevýhody • Náročnost implementace • Potřebují dodatečné informace, které nejsou často k dispozici
2.5.4
Výpočet podobnosti
Výpočet podobnosti mezi položkami nebo uživateli je pro Memory-Based algoritmy kritickým krokem. Pokud algoritmus potřebuje vyhodnotit podobnost dvou položek, zjistí, zda existují uživatelé, kteří obě tyto položky hodnotili a na základě toho vypočte podobnost. Existují různé způsoby, jak podobnost vypočíst [19]. 44
2.6. Content-based doporučování 2.5.4.1
Correlation-Based
Pro výpočet podobnosti wj,i dvou položek i a j je využit např. Pearsonův korelační koeficient, nebo libovolný jiný korelační koeficient. Výpočet dle Pearsonova korelačního koeficientu, viz. vzorec 2.1. P
wi,j = qP
u∈U (ru,i
u∈U (ru,i
− ri )(ru,j − rj )
− ri )2
qP
u∈U (ru,j
(2.1)
− rj )2
kde U je množina uživatelů, kteří hodnotili položky i i j, ru,i je hodnocení položky i uživatelem u, ri je průměr hodnocení i-té položky těmito uživateli. 2.5.4.2
Cosine-Based
Pokud si představíme sloupce či řádky z tabulky 2.1 jako vektory, můžeme jejich podobnost zjistit vypočtením kosinu úhlu mezi nimi. Formálně tedy pro matici R (uživatel-položka) velikosti m * n spočítáme podobnost dvou položek i a j jako kosinus n-dimenzionálního vektoru i-tého a j-tého řádku. Například → − → − pro vektor A = x1 , y1 a vektor B = x2 , y2 , by se kosinovu podobnost vektorů → − → − A a B spočítaly dle vzorce 2.2. → − → − → − → − A•B x1 x2 + y1 y2 wA,B = cos( A , B ) = → − → − = q 2 2q 2 2 k Ak ∗ kB k x 1 y1 x 2 y2
2.6
(2.2)
Content-based doporučování
Content-based doporučování je založeno na analyzování textových informací v popisu položek, dokumentů, navštívených URL, uživatelských profilů, atd., snaží se najít podobnost v jejich obsahu. Pokouší se tedy doporučit položky, které jsou nějakým způsobem podobné těm, které uživatel v minulosti navštívil. Algoritmy se zaměřují především na naučení preferencí uživatele a následné filtrování nově přidaných položek, v kterých hledají podobnost. Tyto techniky trpí „start-up“ problémy, potřebují dostatek informací k vytvoření spolehlivého klasifikátoru. Jsou také limitovány vlastnostmi položek, které se snaží doporučit, může být problém potřebné informace (např. v e-shopu se typicky jedná o kategorii, výrobce, cenu, parametry produktu, atd.) extrahovat. Dalším problémem je, že dokáží doporučit pouze položky, které jsou obsahově podobné již navštíveným, což snižuje šanci doporučit něco zajímavého [22] [19].
45
KAPITOLA
Návrh Tato kapitola bude věnována návrhu jednotlivých částí diplomové práce. Jak je vidět z Obrázku 3.1, bude třeba rozebrat návrh 4 různých částí, z nichž každá je něčím specifická.
Obrázek 3.1: Abstraktní pohled na projekt 47
3
3. Návrh
3.1 3.1.1
Webová aplikace Návrh uživatelského rozhraní
Jednou z kritických částí návrhu webové aplikace je návrh uživatelského rozhraní. V kapitole 2.4 byly vytvořeny požadavky na uživatelské rozhraní, nyní se budeme věnovat vytvoření prototypu uživatelského rozhraní. 3.1.1.1
Lo-Fi prototyp
Lo-Fi prototypu se někdy také říká wireframe, nebo mockup. Je to úplně základní představa o tom, jak budou rozložené komponenty uživatelského rozhraní a jaké budou vztahy mezi jednotlivými stránkami. Slouží jako podklad, který definuje strukturu každé stránky, její obsah i funkčnost. Prototypy předchází grafickým návrhům, jsou typicky černobílé a často jsou kresleny pouze tužkou na papír. Hlavní výhodou těchto prototypů je možnost cokoli změnit, protože nás to v této chvíli bude stát minimum úsilí [3] [23]. Prototypy je možné vytvářet buď „odshora“, nejdříve se zaměřit na rozmístění komponent a až poté na jejich detail. Nebo „odsdola“, nejprve navrhnout detail komponent a poté se zaměřit na jejich rozmístění. Nejlepší je kombinace těchto přístupů, lehce si rozmyslet vzhled komponent i jejich rozmístění, poté navrhnout samotné rozmístění a případně komponenty upravit [13]. Celkem bylo v této fázi vytvořeno 6 Lo-fi prototypů, každý prošel několika iteracemi. Z prostorových důvodů uvedu pouze výsledný Lo-fi prototyp pro výsledky vyhledávání - viz. Obrázek 3.2. 3.1.1.2
Vyhodnocení bez uživatelů
Jak [14] uvádí, vyhodnocení kvality prototypu může probíhat bez uživatelů, tímto způsobem se nedají řádně testovat pouze „exotická“ uživatelská rozhraní. Často je k účelu vyhodnocování používána heuristická analýza od Jakoba Nielsona, která se skládá z následujících 10 pravidel: 1. Viditelnost stavu systému - Systém musí neustále informovat uživatele o tom co dělá a poskytnout tuto informaci v rozumném čase. 2. Shoda systému s realitou - Systém musí „mluvit jazykem uživatele“. Např. ikonka na smazané soubory má podobu odpadkového koše. 3. Minimální zodpovědnost - Je nutné umožnit uživatelům kdykoli návrat do předchozího stavu (undu). 4. Shoda s použitou platformou a obecnými standardy - Používání standardních UI komponent - program pod Windows by měl vypadat a chovat se jako program pod Windows. 48
3.1. Webová aplikace
Obrázek 3.2: Lo-fi prototyp výsledků vyhledávání
5. Prevence chyb - Pokud je to možné neumožnit uživateli zadání chybné hodnoty, případně poskytnout nápovědu. 6. Kouknu a vidím - Uživatel by neměl být nucen si něco pamatovat, akce by měly být viditelné a snadno dosažitelné. 7. Flexibilita a efektivita - Použití klávesových zkratek, nabídnout mód pro začátečníky i pokročilé uživatele. 8. Minimalita - Zobrazovat pouze potřebné informace, grafický návrh by neměl snižovat použitelnost. 9. Smysluplné chybové hlášky - Z chybové hlášky by měl uživatel poznat, co se stalo a mělo by mu být nabídnuto řešení tohoto problému. 10. Nápoveda a dokumentace - Co nejstručnější, snadno by se v ní mělo vyhledávat. 3.1.1.3
Testování experty
Za experta je většinou považován člověk vzdělaný v IT. Expertem, který testoval prototyp, byl Bc. Martin Švihlík. Zjistil několik nedostatků: • U tlačítka zobrazit, není jasné že dojde k přesměrování na poskytovatele slevy, přidat popup, aby o tom byl uživatel informován. 49
3. Návrh
Obrázek 3.3: Návštěvnost sociálních sítí v ČR, zdroj Google Trends
• U tlačítka Koupit, není jasné že koupě proběhne na serveru poskytovatele slevy. • Nevýrazný a lehce přehlédnutelný odkaz na zobrazení všech slev.
3.1.2
Integrace sociálních sítí
S rostoucí oblibou sociálních sítí roste i význam jejich integrace do webových aplikací. Dle [5] je např. sociální síť Facebook21 využívána téměř polovinou české internetové populace a to s 3.3 milióny aktivními uživateli. Jak je vidět z 3.3 Facebook je zdaleka nejpoužívanější sociální sítí v ČR. Proto bude při integraci brán zřetel primárně na sociální síť Facebook. 3.1.2.1
Přihlašování přes účet na sociální síti
Dnes je již docela běžné umožnit uživatelům přihlášení přes sociální sít Facebook, Twitter22 nebo jejich účet na Googlu. Výhodou je, že se uživatelé mohou přihlásit přes službu, kterou znají a důvěřují ji a nemusí se obávat o zneužití svých hesel. Nevýhodou je omezování uživatelů, kteří účet na těchto sítích 21 22
50
Sociální síť Facebook, dostupná z https://www.facebook.com/ Sociální síť Twitter, dostupná zhttps://twitter.com/
3.1. Webová aplikace
Obrázek 3.4: Tlačítka pro sdílení na sociálních sítích.
nemají, ti by neměli možnost využití služeb dostupných jen pro přihlášené uživatele. Přihlašování přes sociální sítě bude tedy pouze jako alternativa ke klasickému způsobu registrace. 3.1.2.2
Sdílení
Uveřejňování nejrůznějšího obsahu od videí po novinové články přes sociální síť je každodenní záležitostí. Pro slevový agregátor je nutné umožnit sdílet jednotlivé nabídky a to přes jediné tlačítko dané sociální sítě. Sdílení bude umožněno přes sociální síť Facebook a Google+, viz. Obrázek 3.4.
3.1.3
Dlouhodobé přihlášení
Každému nově příchozímu uživateli bude vygenerován unikátní hash, který umožní monitorovat zájmy daného uživatele. To je extrémně důležité hlavně pro účely kolaborativního filtrování. Tento vygenerovaný hash bude uložen do cookie, které bude nastavena velice dlouhá platnost v řádu desítek let. Při registraci uživatele, nebo prvním přihlášení přes sociální síť dojde k uložení této hash do databáze, aby mu mohla být následně přiřazena i při přihlášení z jiného počítače. Bude tak možné dlouhodobě sledovat zájmy uživatele a poskytnout mu kvalitnější doporučení nabídek, které by ho mohli zajímat. Dlouhodobé přihlášení bude umožněné přes cookie, pokud uživatel implicitně neklikne na odkaz pro odhlášení, zůstane přihlášen až do vypršení platnosti cookie. Kvůli možnosti využívání jednoho počítače více uživateli, především potom na veřejných místech, bude při odhlášení vygenerována nová hash a monitorovány budou zájmy nového uživatele.
3.1.4
Sitemap
Sitemapy jsou způsobem, jak pomoci Googlu zaindexovat i stránky, které by běžným způsobem objevit nemohl. Sitemapa je XML dokument obsahující všechny stránky webové aplikace, včetně těch, které by crawler Googlu neobjevil. Navíc je tak možné poskytnout více údajů o obsahu stránky, například pokud se na stránce nachází video, je možné specifikovat jeho délku nebo kategorii, u obrázků je např. možné specifikovat informace o licenci pro další použití [7]. Sitemapy jsou užitečné především: • Pro stránky s dynamickým obsahem, bohatým využitím Ajax, Silverlight, nebo Flash obsahu. 51
3. Návrh • Pro stránky s velkým množstvím obsahu, který není dobře provázán odkazy. Ukázka Sitemapy: http://www.example.com/ 2005-01-01 monthly <priority>0.8 Význam jednotlivých tagů: 1. loc - Celé URL stránky včetně protokolu (http, https), musí mít méně než 2048 znaků. 2. lastmod - Datum a čas poslední změny stránky v ISO 8601 formátu. 3. changefreq - Jak často bude daná stránka měněna. Možné hodnoty: always, hourly, daily, weekly, monthly, yearly, never. 4. priority - Význam stránky vůči ostatním stránkám webu, hodnoty jsou z intervalu <0,1>, kde 1 je nejdůležitější stránka.
3.1.5
Zpracování obrázků
Dalším důležitým aspektem je nakládání s obrázky, které se nacházejí u všech nabídek získaných od slevových serverů. Jak je vidět z Tabulky 1.1 z feedu dostaneme URL obrázků, které patří ke slevě, bohužel ale neexistuje žádná specifikace o vlastnostech konkrétních obrázků. Dva velké problémy, kvůli kterým není možné využít poskytnutou URL, tak jak je získána z XML feedu: • Různé rozměry obrázků - deformace • Dlouhá doba odezvy serverů, na kterých se obrázky nacházejí Obrázky bude nutné oříznout a uložit lokálně na serveru, kde poběží webová aplikace. Z kapacitních důvodů je cílem ukládat obrázky pouze těch nabídek, které byly někdy navštívené a to při prvním zobrazení dané nabídky. 52
3.2. Parser XML feedů
Obrázek 3.5: Mapování kategorií
3.2
Parser XML feedů
Jak plyne z kapitoly 2.3.1, bude parser XML feedů naprogramován v jazyce Java. Dále, jak je zřejmé z Obrázku 3.1, bude ukládat naparsované nabídky do databáze a zároveň do fulltextového vyhledávače.
3.2.1
Neznámé XML elementy
Z důvodu nestandardních XML feedů je velice pravděpodobné, že budou postupně odhalovány nové elementy, které budou muset být nějakým způsobem zpracovány. Kvůli snadnosti přidání nových elementů bylo rozhodnuto o použití návrhového vzoru Command, viz. kapitola 3.5.1. Při zpracovávání XML bude po zjištění názvu elementu vytvořen odpovídající Command, který bude vědět, jak s tímto elementem naložit. Později se nad Commandem zavolá metoda execute() a bude vykonána požadovaná operace.
3.2.2
Mapování
Při podrobnějším zkoumání XML feedů bylo zjištěno, že nepanuje shoda na zařazování nabídek do kategorií. Obdobně to platí i pro města, v kterých je možné slevy uplatnit. Proto bylo rozhodnuto o umožnění mapování, jak je vidět na Obrázku 3.5.
3.2.3
Nečekané události
Parser bude zpracovávat desítky až stovky XML feedů různých slevových serverů. Musí se počítat s tím, že může nastat spousta neočekávaných událostí jako: 53
3. Návrh • nedostupnost XML feedu • nevalidní XML dokument, který nebude možné zpracovat • nevalidní hodnoty elementů Je však důležité, aby při těchto událostech bylo pokud možno umožněno zpracování zbývajících nabídek v daném feedu, pokud to možné nebude, musí být umožněno alespoň zpracování zbývajících feedů.
3.3
Fulltextový vyhledávač
V této části návrhu se budeme zabývat fulltextovým vyhledáváním. Z kapitoly 2 víme, že má být postaveno na Apache Solr, což je open source enterprise search platforma založená na projektu Apache Lucene 23 . Slouží jako vyhledávač např. pro CNet24 , Zappos25 , nebo Netflix26 . Naprogramován je v jazyku Java, ale protože se jedná o server komunikující pomocí standardů jako je HTTP a XML, není znalost programovacího jazyka Java nezbytná. Nabízí řadu užitečných funkcí, které jsou při vyhledávání často požadovány, jako je zvýrazňování nalezených frází, filtrování výsledků vyhledávání, pravopisná kontrola dotazů, auto-suggest, atd. [18].
3.3.1
Relevantní pole
Jak bylo řečeno v kapitole 3.2, parser XML feedů bude ukládat nabídky do databáze a zároveň je bude posílat do Sorlu. Evidentní otázkou bylo, jaká data nabídek budou ukládány do DB a jaká do Sorlu. Aby bylo možné odpovědět na tuto otázku, bylo nutné se rozhodnout, jak bude probíhat komunikace mezi fulltextovým vyhledávačem a webovou aplikací. Při odeslání dotazu na fulltextový vyhledávač buď obdržíme: 1. Kompletní informace potřebné pro zobrazení 2. ID relevantních nabídek Výhodou 2. možnosti je, že nebudou vznikat žádné duplicity, ale při každém požadavku na vyhledání v nabídkách bude nutný další dotaz na DB. Protože vyhledávání v nabídkách je naprosto prioritní funkce, byla dána přednost možnosti č. 1, nabídky sice budou uloženy duplicitně jak v DB tak v Sorlu, ale odpadne nutnost dalšího dotazování DB. 23
Apache Lucene, dostupný z http://lucene.apache.org/ CNet - publikace článků o spotřební elektronice, dostupný z http://www.cnet.com/ 25 Zappos - největší internetový obchod s botami, dostupný z http://www.zappos.com/ 26 Netflix - internetová videopůjčovna, dostupná z http://www.netflix.com/ 24
54
3.4. Doporučování
3.3.2
Vyhledávací pole
Dalším důležitým rozhodnutím bylo zvolení vyhledávacích polí, jak je vidět z Tabulky 1.1, bylo by možné umožnit vyhledávání nabídek např. podle data, nebo ceny. Přesto, že uživatelé jsou zvyklí tyto ukazatele využívat k filtrování nabídek, není obvyklé podle nich vyhledávat. Nakonec bylo rozhodnuto umožnit vyhledávání podle: • Slevových serverů • Popisů nabídek • Kategorií • Měst • Štítků
3.4
Doporučování
Cílem bylo vytvořit inteligentní algoritmus pro kolaborativní filtrování, které ovšem může být efektivní pouze pokud bude dostatek dat uživatelů, kteří využívají webovou aplikaci. Z kapitoly 1 je jasné, že existuje spousta agregátorů, musí se tedy počítat s tím, že dat od uživatelů dostatek nebude. Bylo tedy rozhodnuto o vytvoření záložního algoritmu pro tento případ, ten bude založen na Content-based doporučování na základě podobnosti obsahu jednotlivých nabídek. Byly identifikovány specifické vlastnosti pro doporučování slevových nabídek: • Krátká doba platnosti slev - průměrná doba platnosti cca 14 dní • Podobné slevy se budou často měnit - podobná sleva musí být aktivní • Orientace kupujících na zajímavost konkrétní nabídky a celkovou cenu, před výší slevy a dalšími faktory [2]
3.4.1
Kolaborativní filtrování
Sběr dat pro účely kolaborativního filtrování bude prováděn pomocí implicitního feedbacku, viz. kapitola 2.5.1.2. Po vytvoření návrhu uživatelského rozhraní bylo zřejmé, že bude možné sledovat tyto uživatelské akce: • Vyhledávané fráze • Navštívení detailu slevy • Proklik na server poskytovatele slevy 55
3. Návrh 3.4.1.1
Item-to-Item Collaborative Filtering
Algoritmus publikovaný autory doporučovacího systému pro internetový obchod Amazon27 . Místo propojování uživatele s podobnými uživateli dochází k propojování zakoupeného nebo hodnoceného zboží s podobným zbožím. Pro výpočet podobnosti je nutné sestavit „tabulku podobností“ zboží, ve které se nachází zboží, které uživatelé kupují nejčastěji společně. Bylo by sice možné sestavit matici všech produktů a iterovat mezi všemi dvojicemi a spočítat podobnost všech těchto párů. Velké množství těchto párů ovšem nemá žádného společného zákazníka, tento postup by byl neefektivní jak z pohledu výpočetní tak paměťové složitosti. Následující pseudokód algoritmu je mnohem efektivnější: [10]. For each item in product catalog, I1 For each customer C who purchased I1 For each item I2 purchased by customer C Record that a customer purchased I1 and I2 For each item I2 Compute the similarity between I1 and I2 Pro účely doporučování slevových nabídek potom bude vypadat pseudokód následovně: For všechny nabídky, N1 For všechny uživatele U, navštívili N1 For všechny aktivní nabídky N2, které uživatel U~navštívil Zaznamenej, že uživatel navštívil N1 a N2 For všechny nabídky N2 Vypočítej podobnost mezi N1 a N2 Změna je pouze v jediné části „For všechny aktivní nabídky N2, které uživatel U navštívil“. U internetového obchodu nevadí, pokud doporučené zboží není aktuálně skladem, zákazník si nechá zboží zaslat, až dojde k jeho naskladnění. V případě slevových nabídek je třeba zajistit, aby se v doporučení neobjevily slevy, kterým vypršela platnost, protože se již nikdy nebudou dát koupit. Předvýpočet této „tabulky podobností“ bude probíhat offline. Jak [10] uvádí je velice výpočetně nenáročný s asymptotyckou složitostí O(N2 M), v praxi se složitost spíše blíží O(NM), protože uživatelé navštíví jen malou část z celkového množství položek. Na základě „tabulky podobností“ algoritmus najde podobné nabídky těm, které uživatel navštívil, ty agreguje a poté doporučí nejpopulárnější z nich. Tento výpočet je již rychlý, záleží na počtu nabídek, které uživatel navštívil. 27 Amazon - jeden z nejstarších a největších internetových obchodů, dostupný z http://www.amazon.com/
56
3.4. Doporučování
3.4.2
Content-Based filtrování
Doporučovat slevy na základě jejich vzájemné podobnosti bude možné hned podle několika faktorů: • Štítky • Cena • Kategorie • Město • Slevový server Pokud by se podobnost zjišťovala např. jen na základě ceny, kategorie a města, shluky podobných slev by byly příliš obecné. Proto jsou z těchto faktorů velice důležité štítky, které by měly několika málo slovy vystihnout obsah nabídky. Tím se shluky podobných slev zúží a bude možné podat kvalitnější doporučení. Problém ovšem je, že řada slevových serverů štítky ve svých feedech neposkytuje. 3.4.2.1
Tvorba štítků
Možností, jak vytvořit štítky z popisků slev, bylo diskutováno několik, patří mezi ně: • Frekvenční analýza - provedení frekvenční analýzy výskytu jednotlivých slov v popiscích slev. Vyřazení slov s nejnižší a nejvyšší frekvencí výskytu, všechna ostatní slova považovat za štítky. • Vytvoření slovníku - při nalezení slova ze slovníku v popisku slevy, bude toto slovo považováno za štítek. – Ruční tvorba slovníku – Automatická tvorba slovníku - slovník vytvořit automaticky na základě frází, které vyhledávají na stránkách uživatelé. Poměrně rychle byla zavrhnuta možnost vytvoření slovníku ručně z důvodu náročnosti jeho tvorby. Přiklonili jsme se nakonec k automatické tvorbě slovníku, především z toho důvodu, že ve štítcích se objeví slova, která uživatelé skutečně někdy vyhledávali, tedy jsou pro ně zajímavá. V druhé řadě bude tento způsob oproti frekvenční analýze méně výpočetně náročný. 57
3. Návrh
Obrázek 3.6: Návrhový vzor Command, zdroj [6]
3.5 3.5.1
Použité návrhové vzory Command
Vzor Command patří mezi behaviorální návrhové vzory. „Zabalí metodu do objektu, takže s ní pak lze pracovat jako s běžným objektem. To umožňuje dynamickou výměnu metod za běhu programu a optimalizaci přizpůsobení programu požadavkům uživatele. Definice z GoF: Zapouzdří požadavek jako objekt, čímž umožní parametrizovat klienty s různými požadavky, vytvářet fronty a záznamy požadavků a podporovat odvolatelné operace.“ [12]. Jak je vidět z Obrázku 3.6, třída Command je pouhé rozhraní definující metodu execute(). Třída ConcreteCommand implementuje toto rozhraní a ví o objektu nad kterým bude požadavek vykonávat, ten je označen jako z Reciever. Client vytváří ConcreteCommand, kterému určí Reciever. Invoker je ten kdo zavolá metodu execute() na takto vytvořeném ConcreteCommandu.
3.5.2
Facade
Vzor Facade - viz Obrázek 3.7, je strukturální návrhový vzor. „Ukazuje, jak nahradit sadu rozhraní jednotlivých subsystémů sjednoceným rozhraním zastupujícím celý systém. Definuje tak rozhraní vyšší úrovně, které usnadní využívání podsystémů. Jejím cílem je zjednodušit rozhraní celého systému a snížit 58
3.5. Použité návrhové vzory
Obrázek 3.7: Návrhový vzor Facade, zdroj [6]
počet tříd, s nimiž musí uživatel přímo či nepřímo komunikovat.“ [12]. Facade neskrývá třídy subsystému, pokud se tedy klient rozhodne pro jejich použití, nic mu nebrání. Vzor umožňuje rozšíření funkcionality, toho dosáhne kombinací jednotlivých subsystémů.
59
KAPITOLA
Realizace 4.1 4.1.1
Webová aplikace Zend Framework
Jedním z nefunkčních požadavků v kapitole 2.2.1 bylo využití Zend Frameworku28 . Jedná se o open-source, objektově orientový webový aplikační framework pro PHP 5. Struktura komponent je jedinečná v tom, že jsou na sobě více méně nezávislé a je možné je použít odděleně. Vývojáři tedy mohou použít jen ty komponenty, které se jim hodí. Zend Framework vyžaduje od verze 1.7.0 použití minimálně PHP 5.2.4 a vyšší. Pro spuštění unit testů je vyžadována knihovna PHPUnit 3.3.0 nebo novější. Řada komponent vyžaduje některé z modulových rozšíření jazyka PHP29 . Jednou z výhod využití Zend Frameworku je široká komunita uživatelů, existuje celá řada knižních publikací zaměřených na vývoj aplikací v Zend Frameworku a samozřejmě také spousta zdarma dostupných materiálů. 4.1.1.1
Zend MVC
Zend framework implementuje architektonický vzor MVC, viz. Obrázek 4.1. • Model: Uchovává data a poskytuje k nim přístup. • View: Definuje, co přesně uvidí uživatel. Většinou view obdrží od controlleru data, která nějakým specifickým způsobem prezentuje uživateli. Často také získává data od uživatele. 28
Zend Framework, dostupný z http://zendframework.com/ Seznam komponent a nutných rozšíření, z http://framework.zend.com/manual/en/requirements.introduction.html 29
dostupný
61
4
4. Realizace
Obrázek 4.1: Zend Framework - MVC pattern
• Controller: Manipuluje s daty, podle uživatelských požadavků rozhodne, jaký view má být zobrazen a předá mu všechna potřebná data. Může dokonce přenechat zpracování požadavku na jiném controlleru.
4.1.2
Doctrine 2
Přesto, že Zend Framework poskytuje knihovny pro práci s databází, konkrétně Zend_Db_Table implementující architektonický vzor Table Data Gateway, bylo rozhodnuto o využití flexibilnějšího řešení. Doctrine 2 je nejrozšířenějším ORM pro PHP, součástí projektu je také DBAL. Umožňuje psaní dotazů v objektově orientované SQL dialektu zvaném DQL, kterému byl inspirací Hibernate a jeho HQL. Doctrine 2 využívá namespace, proto minimálním požadavkem je PHP 5.3 nebo novější. Problémem je, že Zend Framework v aktuální verzi30 namespace nevyužívá a je tedy nutné využít Autoloader z Doctrine 2 pro automatické načítání tříd dodržujících určité konvence pojmenování. Komunitou okolo obou projektů byly vytvořeny knihovny, které značně usnadňují integraci Doctrine 2 do ZF projektu31 . Definice entit se v mnohém podobá JPA anotacím, viz. kapitola 4.2.2. Každá entita musí být označena anotací @Entity a musí mít jedinečný identifikátor @Id, který může zahrnovat více atributů. Zde je ukázka konkrétní entity. 30
Aktuální verze ZF 1.11 Knihovny jsou dostupné z GitHubu, https://github.com/guilhermeblanco/ZendFramework1Doctrine2 31
62
4.1. Webová aplikace namespace CC\ E n t i t y ; /∗∗ ∗ @Table ( name=" d e a l s " ) ∗ @Entity ∗/ c l a s s Deal { /∗∗ ∗ @Id ∗ @Column ( name=" d e a l _ i d " ) ∗ @GeneratedValue ( s t r a t e g y ="IDENTITY " ) ∗/ private $id ; /∗∗ ∗ @ManyToMany( ∗ t a r g e t E n t i t y =" City " , ∗ i n v e r s e d B y =" d e a l s " , ∗ c a s c a d e ={" p e r s i s t " } ∗ ) ∗ @JoinTable ( name=" d e a l s _ c i t i e s " , ∗ joinColumns={ ∗ @JoinColumn ( ∗ name=" d e a l _ i d " , ∗ referencedColumnName=" d e a l _ i d " ∗ ) ∗ }, ∗ i n v e r s e J o i n C o l u m n s={ ∗ @JoinColumn ( ∗ name=" c i t y _ i d " , ∗ referencedColumnName=" c i t y _ i d " ∗ ) ∗ } ∗ ) ∗/ private $ c i t i e s ; ... } Co se týče dotazovacího jazyku DQL, většinu standardních dotazů bylo možné vykonat. Bohužel DQL nepodporuje například UNION, proto některé dotazy musely být napsány v čistém SQL a namapovány na příslušné entity. Čistého SQL také bylo využito v případech vnořených dotazů. Zde je ukázka nativního 63
4. Realizace dotazu: $ e n t i t y M a n a g e r = $ t h i s −>getEntityManager ( ) ; $rsm = new \ D o c t r i n e \ORM\ Query \ ResultSetMapping ; $rsm−>a d d S c a l a r R e s u l t ( ’ deal_id_2 ’ , ’ deal_id ’ ) ; $ s q l = ’SELECT ‘ deal_id_2 ‘ FROM ‘ recommendations ‘ WHERE ‘ deal_id_1 ‘ IN ( SELECT DISTINCT ‘ deal_id ‘ FROM ‘ s t a t s _ b u f f e r _ v i s i t e d _ d e a l s ‘ WHERE ‘ hash ‘ = ? AND ‘ date_time ‘ > NOW( ) − INTERVAL 1 WEEK ) ORDER BY ‘ s i m i l a r i t y ‘ LIMIT 4 0 ’ ; $query = $entityManager −>c r e a t e N a t i v e Q u e r y ( $ s q l , $rsm ) ; 4.1.2.1
Doctrine Repository and Service Layer
Doctrine Repository umožňuje správu jednotlivých entit, je možné použít metody jako findBy, findOneBy, findById, atd., např. při dotazování entity User, který má atribut nickname, je možné použít metodu findOneByNickname. Funkcionalitu Repository je samozřejmě možné rozšířit a definovat vlastní metody pro snadnou správu Entit. Přesto, že je možné modely MVC architektury řešit pouze využitím Repository, použití servisní vrstvy ( „Service Layer“) je komunitou doporučováno především proto, že mohou obstarat část řídící logiky controlleru a umožní tak udržení tzv. „Skinny Controllers“. Service využívá interně Repository, kterých může využít i více najednou, navíc může obstarávat validační logiku, atd. Pokud by např. bylo třeba při registraci nového uživatele odeslat mu uvítací email, UserService by si interně vyžádala NotificationService a email odeslala.
4.1.3
Mysql databaze schema
Schéma databáze je na Obrázku 4.2, skládá se celkem ze 23 tabulek, z toho dvě( „deals_cities“ a „deals_tags“) jsou propojovací pro realizaci many-tomany vazby. V databázi bylo vytvořeno několik rutin(triggerů) pro automatizaci přepočtu hodnocení recenzí slevových serverů. Zde je ukázka jedné rutiny: CREATE PROCEDURE ‘ r e c o u n t _ r e v i e w s ‘ BEGIN UPDATE d e a l s _ s e r v e r s SET r a t i n g = ( SELECT avg ( r a t i n g ) FROM d e a l s _ s e r v e r s _ r e v i e w s 64
4.1. Webová aplikace
Obrázek 4.2: Database schema
WHERE d e a l _ s e r v e r _ i d = p_deal_server_id ) WHERE d e a l _ s e r v e r _ i d = p_deal_server_id ; UPDATE d e a l s _ s e r v e r s SET r e v i e w s _ c o u n t = ( SELECT count ( r a t i n g ) FROM d e a l s _ s e r v e r s _ r e v i e w s WHERE d e a l _ s e r v e r _ i d = p_deal_server_id ) WHERE d e a l _ s e r v e r _ i d = p_deal_server_id ; END
4.1.4
Problémy grafického návrhu
Vytvořený grafický návrh webové aplikace je velice elegantní a opticky příjemný. Z hlediska designu je zde však řada problémů, např. zaoblené rohy naprosté většiny komponent. U formulářů a tagů input bylo zaoblených rohů 65
4. Realizace
Obrázek 4.3: Formulář s nestandardní select komponentou
Obrázek 4.4: Select element - pouze CSS styly
dosaženo obalením do div tagu, kterému byl na pozadí vložen obrázek. Dále např. u tabulek bylo využito vlastnosti CCS3 border-radius, pokud tedy uživatel používá starší prohlížeč, rohy tabulek zaoblené nebudou. Jedním z největších problémů však bylo použití nestandardní komponenty select, jak je vidět na Obrázku 4.3. Select je komponenta, která je v jednotlivých prohlížečích různě vykreslována a její vykreslení závisí také na operačním systému. Pouze pomocí CSS stylů není možné dosáhnout požadovaného efektu. Je nutné přistoupit k javascriptu, skrýt původní select, jeho obsah nakopírovat do neuspořádaného seznamu ul a ten nastylovat CSS styly. Vzhled selectu s využitím pouze CSS stylů je vidět na Obrázku 4.4.
4.1.5
Zpracování obrázků
Jak již bylo řečeno v kapitole 3.1.5, obrázky je nutné oříznout kvůli různým rozměrům a s tím související deformací obrázků. Při způsobu zpracování obrázků byl brán ohled především na použitelnost webu a to v době, kdy teprve dochází k samotnému ořezu a ukládání obrázků na lokální server. Pro snadný ořez a změnu velikosti obrázků byl zvolen framework PhpThumb32 . Při ukládání obrázků je nejdříve vytvořena hash z URL obrázku, která představuje 32
66
PHP thumbnail generator, dostuponý z http://phpthumb.sourceforge.net/
4.1. Webová aplikace jméno ukládaného obrázku, navíc první dva znaky této hash značí podadresář, kam bude obrázek uložen. Uložení v podsložkách zajistí mnohem lepší efektivitu vyhledávání obrázků. Pokud je zjištěno, že daný obrázek na disku neexistuje, je source obrázku následující: <domain>/image . php /? u r l=&w=<width>&h= Skript image.php načte obrázek z dané URL, ořízne ho podle požadovaných rozměrů, postará se o jeho uložení a následné zobrazení. Výhodou tohoto postupu je možnost práce se stránkou, zatímco jsou zpracovávány jednotlivé obrázky.
4.1.6
Doporučování nabídek
Realizace doporučovacích algoritmů je probrána v kapitole 4.4, kde je popsán způsob offline předvýpočtu podobných nabídek. Samotné doporučování nabídek na webu se liší dle toho, kde je doporučení třeba. Doporučování v detailu nabídek je realizováno pouhým zjištěním nejpodobnějších nabídek k aktuální a jejich doporučením - jsou doporučeny 3 nejpodobnější nabídky dle kolaborativního filtrování a 3 dle content-based filtrování. Doporučování na domovské stránce je řešeno velice podobným způsobem, který je popsán v [10]. Nejprve je zjištěno, jaké nabídky uživatel za poslední týden navštívil, k těmto nabídkám je vybrána skupina 30 nejpodobnějších. Z těchto nabídek je vždy náhodně vybráno 6, které jsou uživateli doporučeny, je tak zajištěna dostatečná různorodost doporučení při opakované návštěvě domovské stránky. Pokud se jedná o nového uživatele, který nemá žádnou historii navštívených nabídek, doporučení je založené na oblíbenosti dle počtu prodaných kuponů. Opět je vybíráno náhodně 6 nabídek ze skupiny o velikosti 30.
4.1.7
Facebook integrace
Facebook se snaží zjednodušit integraci svých služeb a pro PHP nabízí Facebook PHP SDK33 , které má spoustu nedostatků a řada funkcí nefunguje přesně dle dokumentace. Přihlašování přes Facebook je realizováno pomocí Facebook JavaScript SDK34 , protože není nutné přesměrování na stránky facebooku a zpět, jako je tomu v případě využití PHP SDK. Dalším problémem PHP SDK je generování odkazu na odhlášení, který odhlásí uživatele i ze stránek Facebooku, proto tento způsob odhlašování není využit. Uživatelé samozřejmě mají možnost přihlášení bez účtu na facebooku, stačí se zaregistrovat. Stavy v jakých se uživatel může nacházet, jsou na Obrázku 4.5. Co se bezpečnosti uživatelských hesel týče, do databáze jsou ukládány 33 34
Facebook PHP SDK, dostupné z https://github.com/facebook/facebook-php-sdk Facebook JavaScript SDK, dostupné z https://developers.facebook.com/docs/reference/javascript/
67
4. Realizace
Obrázek 4.5: Stavy uživatele
pouze hash, které jsou vytvořeny pomocí PHPass frameworku35 , využívána je adaptivní kryptografickou hash funkci bcrypt. Další problém se týkal Open Graph tagů. Po chybném automatickém vyplnění tagu „og:description“ a pokusu o sdílení obsahu této stránky došlo k uložení špatných údajů do cache facebooku. Následně nebylo možné pouhou opravou tagu „og:description“ donutit facebook k aktualizaci dané cache. Každou URL s chybou v Open Graph tagu bylo nutné zadat do Facebooks URL Linter36 , aby k aktualizaci došlo.
4.1.8
Solr integrace
Pro komunikaci se Solr serverem byla zvolena knihovna SolrPhpClient37 , jedná se o knihovnu třetí strany, která je šířená pod New BSD licencí. Knihovna již nějakou dobu nebyla aktualizována a není jasné zda budou podporovány nové funkčnosti Solr serveru. V případě potřeby je možnost knihovny vyměnit, nabízí se buď Solarium38 nebo rozšíření z PECL repositáře39 .
4.2 4.2.1
Parser XML feedů Parsování XML
Prvním důležitým rozhodnutím bylo jakým způsobem parsovat samotné XML dokumenty v jazuku Java. Existuje celá řada dostupných parserů jako je Xer35
PHP password hashing framework, dostupný z http://www.openwall.com/phpass/ Facebooks URL Linter, dostupný z https://developers.facebook.com/tools/debug 37 SolrPhpClient knihovna, dostupná z http://code.google.com/p/solr-php-client/ 38 Solarium Solr client library, dostupné z http://www.solarium-project.org/ 39 The Apache Solr PECL extension, dostupné z http://pecl.php.net/package/solr 36
68
4.2. Parser XML feedů
Obrázek 4.6: Diagram parsování XML s využitím SAX a návrhového vzoru Command ces40 , Crimson41 , JDOM42 , atd. Vzhledem k předem dané struktuře XML feedu a nepotřebě specifických vlastností bylo nakonec rozhodnuto o využití standardních knihoven JAXP, konkrétně tedy rozhraní SAX. SAX umožňuje sériový přístup ke zpracovávanému XML dokumentu. Při proudovém zpracování se dokument rozdělí na jednotlivé části (počáteční a koncové značky, obsahy elementů, komentáře, atd.). Postupně se pak volají události, které ohlašují nalezení konkrétní části. Způsob zpracování událostí je pak již plně v kompetenci programátora [16]. Na Obrázku 4.6 je vidět způsob parsování samotného XML dokumentu s využitím rozhraní SAX a návrhového vzoru Command. Při výskytu chyby v XML syntaxi neumožňuje SAX pokračovat v parsování takového XML dokumentu, proto třída „XmlParser“ nejdříve rozdělí XML dokument do pole nabídek podle značek „<deal>“. Třída „SaxHandler“ poté při samotném parsování XML dokumentu vytvoří při otvíracím elementu novou třídu „XmlElement“ a při uzavření tohoto elementu si podle jeho jména vyžádá od třídy „ElementMapperTable“ odpovídající „ConcreteCommand “, který ví, jak s elementem naložit. Takto je postupně naparsována celá nabídka, která je následně předána třídě „DatabaseHandler“, která zjistí, zda je daná třída již v DB, pokud ano, postará se o její aktualizaci, pokud ne, zajistí její přidání jak do DB tak fulltextového vyhledávače Solr.
4.2.2
ORM Hibernate
Pro spojení s relační MySQL databází byl zvolen Hibernate43 framework, což je jeden z nejznámějších nástrojů pro objektově relační mapování pro progra40
Xerces Java Parser, dostupný z http://xerces.apache.org/xerces-j/ Crimson, dostupný z parserhttp://xml.apache.org/crimson/ 42 JDOM, dostupný zhttp://www.jdom.org/ 43 Hibernate, dostupný z http://www.hibernate.org/ 41
69
4. Realizace movací jazyk Java. Jedná se o open-source projekt, který umožnuje jednoduché mapování Java objektů na tabulky relační databáze. Velkou výhodou je databázová nezávislost44 , při potřebě změnit databázi je nutné změnit pouze několik řádků v souboru persistance.xml. Pro dosažení databázové nezávislosti je třeba použít HQL, obdobu SQL, která je unifikována pro databázovou nezávislost. Pro mapování Java objektů na relační databázi bylo možné buď využití Hibernate core, nebo JPA s využitím Hibernate Entity Manageru. Při použití JPA a dodržení JPA specifikace, je v případě potřeby možné vyměnit ORM engine Hibernate za jiný. Nevýhodou použití JPA je nutnost psaní dotazů v JPQL, který bohužel nemá takové možnosti jako HQL. Zvoleno bylo využití JPA, zde je ukázka mapování: @Entity @Table ( name = " d e a l s " ) p u b l i c c l a s s Deal implements S e r i a l i z a b l e { @Column ( name = " group_id " ) p r i v a t e Long groupID ; @Id @Column ( name = " d e a l _ i d " ) @GeneratedValue ( s t r a t e g y = GenerationType .AUTO) p r i v a t e Long de a lI D ; private String t i t l e ; @Column ( name = " t i t l e _ s h o r t " ) private String titleShort ; @ManyToMany( t a r g e t E n t i t y = City . c l a s s , c a s c a d e = { CascadeType . PERSIST , CascadeType .MERGE } ) @JoinTable ( name = " d e a l s _ c i t i e s " , joinColumns = @JoinColumn ( name = " d e a l _ i d " ) , inverseJoinColumns = @JoinColumn ( name = " c i t y _ i d " ) ) p r i v a t e Set c i t i e s = new HashSet ( ) ; 44
70
Seznam podporovaných databázových dialektů, https://community.jboss.org/wiki/SupportedDatabases2
4.2. Parser XML feedů ... } @Entity @Table ( name = " c i t i e s " ) p u b l i c c l a s s City implements S e r i a l i z a b l e { private String city ; @Id @Column ( name = " c i t y _ i d " ) @GeneratedValue ( s t r a t e g y = GenerationType .AUTO) p r i v a t e Long i d ; @ManyToMany( c a s c a d e = { CascadeType . PERSIST , CascadeType .MERGE} , mappedBy = " c i t i e s " , t a r g e t E n t i t y = Deal . c l a s s , f e t c h = FetchType .LAZY ) p r i v a t e Set d e a l s = new HashSet ( ) ; }
4.2.3
Solrj
Jak bylo řečeno v kapitole 3.2, parser musí po naparsování nabídek a jejich uložení do DB zaindexovat nabídky ve fulltextovém vyhledávači Solr. K tomuto účelu slouží knihovna „Solrj“, tato knihovna je dostupná v oficiální Apache Solr distribuci45 , v adresáři „dist“ je knihovna „apache-solrsolrj-x.x.x.jar “. Práce s touto knihovnou je velice pohodlná, po vytvoření instance třídy „CommonsHttpSolrServer“ je možné volat metody pro přidání dat do Solr indexu „addBean(Object obj)“ nebo „addBeans(Collection> beans)“. Pro přidání výše zmíněných objektů do Solr indexu je třeba přidat „solrj.beans.Field “ anotace. Třída Deal po přidání anotací: @Entity @Table ( name = " d e a l s " ) p u b l i c c l a s s Deal implements S e r i a l i z a b l e { @Column ( name = " group_id " ) p r i v a t e Long groupID ; 45
Apache Solr distribuce, dostupná z http://lucene.apache.org/solr/
71
4. Realizace @Field ( " d e a l _ i d " ) @Id @Column ( name = " d e a l _ i d " ) @GeneratedValue ( s t r a t e g y = GenerationType .AUTO) p r i v a t e Long de a lI D ; @Field ( " t i t l e " ) private String t i t l e ; @Field ( " t i t l e _ s h o r t " ) @Column ( name = " t i t l e _ s h o r t " ) private String titleShort ; @ManyToMany( t a r g e t E n t i t y = City . c l a s s , c a s c a d e = { CascadeType . PERSIST , CascadeType .MERGE } ) @JoinTable ( name = " d e a l s _ c i t i e s " , joinColumns = @JoinColumn ( name = " d e a l _ i d " ) , inverseJoinColumns = @JoinColumn ( name = " c i t y _ i d " ) ) p r i v a t e Set c i t i e s = new HashSet ( ) ; @Field ( " c i t y " ) @Transient p r i v a t e Set<S t r i n g > s o r l C i t y = new HashSet<S t r i n g > ( ) ; ... } Oproti JPA anotacím je zde rozdíl v tom, že vynechání anotace „@Field “ u nějakého atributu třídy znamená totéž jako JPA anotace „@Transient “. Dále je vidět, že seznam měst musí být uveden jako Set názvů měst, před uložením entit do Solr indexu pomocí Solrj knihovny je tedy nutné data předpřipravit. Odebrání slev z fulltextového vyhledávače je v případě potřeby stejně jednoduché a to pomocí přetížené metody „deleteById(String string)“, „deleteById(List<String> list)“.
4.2.4
Problémy s parsováním
Při realizaci parseru bylo postupem času objeveno několik problémů, které bylo třeba řešit. 72
4.2. Parser XML feedů 4.2.4.1
Prodlužování platnosti nabídek
Prodlužování platnosti nabídek jako takové pro parser nepředstavuje problém. Ovšem řada věcí je závislá na datu ukončení nabídky, například řazení nabídek ve výsledcích vyhledávání, nebo archivace slevových nabídek. Bohužel bylo poměrně rychle zjištěno, že tento údaj je velice nespolehlivý. Slevové servery často prodlužují platnost nabídek, posunují datum ukončení „Deal_End“. Důvodů může být několik, tlak na uživatele k rychlému nákupu, dohoda s poskytovatelem nabídky kvůli malému počtu prodaných kuponů, atd. 4.2.4.2
Archivace nabídek
Prvním problémem souvisejícím s prodlužováním platnosti nabídek - viz. kapitola 4.2.4.1, je archivace nabídek. Archivace při ukončení platnosti tedy není možná, docházelo by ke vzniku duplicit. Nějakou dobu se zdálo být dostatečně robustním řešením archivovat nabídku v momentě, kdy již není ve XML feedu slevového serveru. Bohužel opět bylo zjištěno, že ani to není dostatečný důvod pro archivaci nabídky. Některé slevové servery platnost takové nabídky prodlouží a ta se opět objeví v jejich XML feedu. Tento problém byl vyřešen archivací nabídek při jejich odebrání z XML feedu, ovšem aby nevznikaly duplicity, jsou při parsování XML feedů kontrolovány nabídky archivované během posledního týdne. 4.2.4.3
Duplicity
Vznik duplicit může mít několik důvodů: 1. Způsob archivace nabídek 2. Špatná volba jednoznačného identifikátoru 3. Duplicity v samotných XML feedech První důvod vzniku duplicit byl vyřešen, viz. kapitola 4.2.4.2. Druhý problém souvisí s elementem „ID“, který by měl být unikátní pro každou slevu, ukázal se však být velice nespolehlivý. Jak je vidět z např. Obrázku 4.7, pro různé nabídky jsou uváděna stejná „ID“. Mezi problémy s jednoznačným identifikátorem patří: • Neuvádění elementu • Pro různé nabídky uváděno stejné „ID“ • Pro stejné nabídky uváděno různé „ID“ Místo „ID“, byl nakonec jako jednoznačný identifikátor nabídek zvolen element „URL“, bohužel i zde se narazilo na problémy a to takové, že při každé obnově XML feedu byla uváděná URL u stejných nabídek jednou ve tvaru 73
4. Realizace
Obrázek 4.7: Stejné ID pro různé nabídky - XML feed Slevopolis.cz
Obrázek 4.8: Duplicity v XML feedu - Slevopolis.cz
„http://example.com “ a podruhé „http://www.example.com “. Což opět vedlo ke vzniku duplicit, jednoznačným identifikátorem je tedy element „URL“, bez protokolu „http:// “ a domény 3. úrovně „www.“. Posledním problémem jsou duplicity v samotných feedech. Jak je vidět na Obrázku 4.8, jedná se o stejné nabídky nabízené v různých městech, které při správné volbě unikátního identifikátoru, viz. předchozí odstavec, nepředstavovaly problém. Větší problém představovaly duplicity uvedené na Obrázku 4.9, které musely být kvůli různé URL uloženy duplicitně do databáze. Aby se duplicity neobjevovaly ve výsledcích vyhledávání, musely být odfiltrovány před jejich indexací fulltextovým vyhledávačem. Uvedené duplicity ve feedech na Obrázcích 4.8 a 4.9, jsou jedny z mnoha, jediným zaručeným ukazatelem, jak duplicity rozpoznat, se ukázal stejný popisek slevy „TITLE “. 74
4.3. Fulltextový vyhledávač
Obrázek 4.9: Duplicity v XML feedu - MyDeals.cz
4.2.4.4
Ostatní
Mezi další problémy, které se vyskytly při vývoji parseru, patří parsování data. Opět zde panuje velká nejednotnost formátu data, byly zjištěny tyto formáty: • „yyyy-MM-dd“ • „yyyy-MM-dd HH:mm“ • „yyyy-MM-dd HH:mm:ss“ • „MMM d, yyyy“ US locale ( „Feb 13, 2012“) Překlepy při zadávání data byly také běžné, takže např. konec platnosti nabídky v roce „5012“ sice SimpleDateFormat naparsuje bez problémů, ale při pokusu o uložení do DB Hibernate vyhodí MySQL „Out of range value“ Exception. Musí být proveden rollback transakce, který způsobí detach všech entit spravovaných EntityManagerem.
4.3
Fulltextový vyhledávač
Jak již bylo několikrát zmíněno v kapitolách 2 a 3.3, fulltextové vyhledávání bude realizováno pomocí enterprice search serveru Apache Solr, který je založený na projektu Apache Lucene. Apache Lucene je vysoce výkoná information retrieval knihovna napsaná kompletně v jazyku Java, která byla 75
4. Realizace postupně portována do řady dalších jazyků jako C/C++, Python, Perl, Delphi46 . Po stažení oficiální distribuce Solru47 je ve složce „example“ fungující ukázka použití, v přiloženém „README.txt “ je stručně popsán postup pro spuštění a následné přidání dat do indexu.
4.3.1
Rozdíl oproti RDBMS
Jedna z prvních věcí, které je třeba si uvědomit, je rozdíl v data modelu oproti RDBMS. Relační databáze mají svůj data model založený na relacích (tabulkách), které mají stanovené atributy (sloupce). Při stejných datových typech atributů v různých relacích je možné vytváření vazeb mezi těmito relacemi. RDBMS mají velice flexibilní datový model, Lucene spoléhá na „document oriented“ data model, což je v podstatě jedna velká tabulka obsahující všechna data. Jediné, co dokument model podporuje, jsou multi-value atributy (sloupce), které obsahují pole hodnot. Otázka je, zda by bylo možné využití pouze Solru místo DB, zde jsou důvody, proč využít Solr jako doplňku k DB [18]: • No updates - Pokud jakákoli část dokumentu uložená v Solru musí být aktualizována, musí být nahrazen celý dokument, což znamená smazání a přidání dokumentu. • Slow commits - Vysoký výkon vyhledávání a jisté další funkce Solru jsou možné jen díky rozsáhlému využívání cache. Po operaci commit, která je volána po dokončení přidávání nových dokumentů, jsou tyto cache tvořeny znova. To může trvat několik sekund, někdy dokonce minut a v extrémních případech i déle.
4.3.2
Konfigurace
První rozhodnutí při konfiguraci Solru bylo, zda používat jeden kombinovaný index, nebo více oddělených indexů. Jde v podstatě o to, zda bude nutné vyhledávání ve více typech dat, např. v produktech a recenzích. V případě jednoho indexu je stále možné uložení více typů dokumentů do jedné tabulky, některé sloupce jednoduše zůstanou nevyužity a také bude třeba sloupec, podle kterého rozlišíme, o jaký typ dat se jedná. Tento postup je mnohem jednodušší z hlediska údržby, nutnosti správy pouze jedné konfigurace a také snadnosti vyhledávání ve více typech dokumentů najednou. Využití jednoho indexu pro více typů dokumentů má ale také své nevýhody [18]: • Možná kolize jmen sloupců tabulky. 46
Kompletní seznam dostupný z http://wiki.apache.org/lucenejava/LuceneImplementations 47 Solr sitribuce, dostupná z http://lucene.apache.org/solr/
76
4.3. Fulltextový vyhledávač • Při sdílení stejného sloupce, který bude prohledáván, dochází ke snížení kvality relevantnosti výsledků vyhledávání kvůli sub-optimálnímu počtu relevantních dokumentů. • Při velkém počtu uložených dokumentů problémy se škálovatelností. • Při commitu dokumentů jednoho typu musí být znovu vytvořena cache pro oba typy dokumentů. Z uvedených důvodů bylo rozhodnuto o využití více oddělených indexů i přesto, že prozatím bude umožněno prohledávat pouze jeden typ dokumentů - slevové nabídky. 4.3.2.1
Schéma
Dalším krokem je vytvoření schématu, které definuje strukturu uložených dokumentů. Při tvorbě schématu je možné vycházet z dříve zmíněné ukázky použití, v podadresáři „\sorl\conf“ se nachází soubor schema.xml. Pro vytvoření více indexů je nutné celý adresář „conf“ zkopírovat do podsložky „\solr\ \conf“. Nejdříve je třeba definovat datové typy sloupců tabulky, ty jsou definovány mezi tagy „“. Ukázka definice:
4. Realizace i g n o r e C a s e =" t r u e " words=" cc_stopwords . t x t " e n a b l e P o s i t i o n I n c r e m e n t s =" t r u e " /> ... Jak je vidět, element „fieldType“ definuje nový datový typ, který bude uložen v indexu. Pro sloupce, v kterých bude umožněno vyhledávání, byl vytvořen speciální datový typ textcc, který na ukládaný text použije řadu filtrů, které zajistí vyšší relevantnost výsledků. Popis jednotlivých filtrů je uveden v Tabulce 4.1. Jak je také vidět při indexování „
4.3. Fulltextový vyhledávač Tabulka 4.1: Popis použitých filtrů ve schématu Název filtru Popis WhitespaceTokenizer Oddělení slov podle whitespace znaků. WordDelimiterFilter Rozděluje slova na podslova, např. „Wi-Fi“ -> „Wi“, „Fi“; „SD500“ -> „SD“, „500“; atd. LowerCaseFilter Převod na malá písmena. ASCIIFoldingFilter Odstranění diakritiky. StopFilter Odstranění slov se seznamu „stop slov“, typicky spojky, předložky, atd. CzechStemFilter Získání kořenu slova. SynonymFilter K najití synonym je využit seznam, který je nutné napsat ručně. kového pole budou použity stejné filtry jako při jeho dotazování „ 4.3.2.2
Config
Dalším krokem je vytvoření requestHandleru, který bude zpracovávat dotazy. RequestHandleru je specifikován v souboru „solrconfig.xml“. < l s t name=" d e f a u l t s "> <s t r name=" f l "> deal_id , t i t l e , c i t y , c a t e g o r y , . . . s t r > <s t r name="rows">20 s t r > l s t > < l s t name=" i n v a r i a n t s "> <s t r name="defType">dismax <s t r name="echoParams"> e x p l i c i t < f l o a t name=" t i e ">0.1 f l o a t > <s t r name=" q f "> s t i t l e ^0.8 s d e s c r i p t i o n ^0.7 s c i t y ^0.6 . . . s t r > <s t r name=" p f "> s t i t l e ^0.8 s d e s c r i p t i o n ^0.7 s c i t y ^0.6 . . . s t r > 79
4. Realizace <s t r name="q . a l t ">∗:∗ s t r > <s t r name="mm">2& l t ;90% s t r > 2 i n t > 2 i n t > l s t > Pokud je nastaven requestHandler jako výchozí, nemusí být jeho jméno specifikováno v každém dotazu. Elementem „fl“ je specifikováno, jaké sloupce tabulky mají být vráceny. Element „qf (query fields)“ říká, jaké sloupce mají být prohledávány a jaká váha má být každému sloupci přidělena. Jak je vidět, nejvyšší váhu má popisek nabídky. Element „pf (phrase fields)“ slouží k automatickému zvýšení relevance, pokud bude nalezena celá fráze. Dále stojí za zmínku parametr „q.alt“, který vytvoří alternativní dotaz v případě nezadání vyhledávané fráze, v tomto případě vrátí všechny dokumenty uložené v Solru. 4.3.2.3
Full-Data import
Při provádění změn v databázi, např. přidávání nových atributů, může nastat potřeba kompletní aktualizace dat uložených v Solru. K tomuto účelu slouží DataImportHandler, který umožňuje mimo jiné import z databáze přes JDBC. Jediné, co je třeba, je specifikovat v souboru solrconfig.xml konfigurační soubor s parametry pro import dat. V tomto souboru je poté nutné specifikovat query, který z databáze vytáhne potřebná data ve stejném formátu, jako by je posílal parser. Zde je příklad pro seznam měst: ... GROUP_CONCAT(DISTINCT c . c i t y SEPARATOR ’ | ’ ) a s c i t y ... LEFT JOIN c i t i e s c ON c . c i t y _ i d = dc . c i t y _ i d ... < f i e l d column = " c i t y " s p l i t B y ="\|"/ > ...
4.3.3
Dotazování
Po správné konfiguraci Solru je již dotazování snadné, proto budou uvedeny pouze specifické problémy týkající se dotazování nad slevovými nabídkami. 4.3.3.1
Query boosting
Při řazení výsledků vyhledávání by měl být brán ohled na: • Počet prodaných kuponů. • Dobu zbývající do konce platnosti nabídky. 80
4.3. Fulltextový vyhledávač Je třeba, aby nabídky které již není možné dlouho koupit, byly mezi prvními ve výsledcích vyhledávání. Problémem bylo, jak se vypořádat s prodlužováním platnosti nabídek - viz. kapitola 4.2.4.1. Protože tu byly určité nabídky, které se držely na předních místech velice dlouho jen díky tomu, že prodlužovaly postupně svou platnost, tento systém musel být přehodnocen. Fungujícím řešením, které bylo aplikováno, je zaznamenávání toho, kolikrát byla platnost slevy prodloužena a nastavení adekvátní penalizace za každé prodloužení. Výsledkem je, že již při druhém prodloužení platnosti, má nabídka velice malou šanci dostat se na slušné pozice ve výsledcích vyhledávání. Do requestHandleru, viz. kapitola 4.3.2.2, byl k tomuto účelu přidán element „bf (boost query)“: <s t r name=" b f "> s o l r _ b o o s t ^ 0 . 0 2 ord ( c u s t o m e r s ) ^ 0 . 0 1 . . . s t r > 4.3.3.2
Filtrování výsledků
Dalším výzvou pro Solr bylo umožnění filtrování výsledků vyhledávání s tzv. „facetováním“, což znamená, že bude zobrazen počet výsledků s využitím daného filtru. Filtrování mělo být umožněno podle kategorie, města a štítků. Problémem bylo, jak zajistit následující způsob filtrování s využitím co nejnižšího počtu dotazů: • Město – a (50) – b (20) – c (10) Takového výsledku je poměrně snadné dosáhnout tím, že do dotazu bude přidán parametr facet.field, tedy pro filtrování dle zmíněných 3 parametrů, bude do dotazu přidáno: f a c e t . f i e l d =c i t y &f a c e t . f i e l d =c a t e g o r y &f a c e t . f i e l d =t a g Při filtrování dle města „a“, dojde k zobrazení 50 výsledků vyhledávání. Ale protože nabídky mohou být nabízeny ve více městech, je nutné, aby následné filtrování vypadalo takto: • Město – a – b (+10) 81
4. Realizace – c (+5) Což naznačuje, že při filtrování, dle města „a“ a zároveň „b“ bude zobrazeno 60 výsledků. Pro tento způsob filtrování musí být součástí dotazu parametr „fq (filter query)“, který bude vypadat následovně: NOT( c i t y : " a " ) Protože by při negování „NOT“ jednoho filtru, například města, docházelo k ovlivnění zbývajících dvou filtrů, bylo nutné využít funkce Solru zvané „Tagging and excluding Filters“. Parametr „fq (filter query)“ bude muset vypadat následovně: { ! t a g=c i t y F i l t e r N e g a t i v e }NOT( c i t y : " a " OR c i t y : " b " ) { ! t a g=c i t y F i l t e r } ( c i t y : " a " OR c i t y : " b " ) { ! t a g=c a t e g o r y F i l t e r N e g a t i v e }NOT( c a t e g o r y : " x " ) { ! t a g=c a t e g o r y F i l t e r } ( c a t e g o r y : " x " ) A takto bude zajištěno, že negativní filtr ovlivní pouze požadovaný facet: f a c e t . f i e l d ={ ! ex%3D c a t e g o r y F i l t e r N e g a t i v e , t a g F i l t e r N e g a t i v e , cityFilter } city &f a c e t . f i e l d ={ ! ex%3D c i t y F i l t e r N e g a t i v e , t a g F i l t e r N e g a t i v e , categoryFilter } category &f a c e t . f i e l d ={ ! ex%3D c i t y F i l t e r N e g a t i v e , c a t e g o r y F i l t e r N e g a t i v e , tagFilter } Jediným dotazem bylo takto možné zobrazit správné hodnoty k 3 různým filtrům. Může se zdát, že komplexita dotazu je mnohonásobně vyšší, čas zpracování dotazu ale nijak výrazně ovlivněn nebyl.
4.4
Doporučování
Implementace doporučovacích algoritmů proběhla přesně dle návrhu z kapitoly 3.4. Za zmínku stojí především tvorba vektorů, které byly následně porovnávány pomocí kosínovy podobnosti. Uvedený příklad je pro Content-based doporučování a výpočet těchto vektorů pro dvě slevové nabídky z Tabulky 4.2. Jak je vidět z Obrázku 4.10, při tvorbě těchto vektorů je jeden z nich považován za bázi obsahující samé jedničky. Druhý vektor, označený jako „Vektor A“, má jedničky u složek, které má s „Vektorem B“ totožné. Pro zjištění podobnosti štítků těchto dvou nabídek, jsou zkonstruovány vektory podobnosti 82
4.4. Doporučování Tabulka 4.2: Smyšlené nabídky, pro účely výpočtu podobnostních vektorů Features Štítky Kategorie Město Cena Slevový portál
Nabídka A hotel, pobyt, sauna Pobyty Celá ČR 4.000,-Kč portál A
Nabídka B pobyt, sauna, tenis Pobyty Celá ČR 4.500,-Kč portál B
Obrázek 4.10: Content-based doporučování - vektory pro nabídky z tabulky 4.2
z jejich štítků a spočítána kosínova podobnost. Před výpočtem kosínovy podobnosti vektorů uvedených na Obrázku 4.10 jsou oba vektory vynásobeny váhovým vektorem, který vyjadřuje důležitost podobnosti jednotlivých složek vektorů. Váhový vektor (12, 6, 3, 3, 1) jasně naznačuje, že za nejdůležitější je považována podobnost štítků a kategorií nabídek.
4.4.1
Tvorba štítků
První implementační výzvou byla tvorba štítků pro slevové nabídky z jejich popisků. Tvorba slovníku byla vcelku přímočará, nejdříve pomocí DISTINCT dotazu byly získány všechny unikátní hledané dotazy. Tyto dotazy byly normalizovány, tzn. byla odstraněna diakritika, došlo k převodu na malá písmena a oddělení po jednotlivých slovech. Výsledkem byl slovník o cca 320 slovech, které bylo třeba najít v popiscích cca 20.000 slevových nabídek. Bylo jasné, že slovník již bude jen větší a slevových nabídek bude také přibývat. 83
4. Realizace
Obrázek 4.11: Aho–Corasick - konečný automat, zdroj [1]
4.4.1.1
Aho-Corasick Algoritmus
Aho-Corasick je vyhledávací algoritmus, který vynalezl Alfred V. Aho a Margaret J. Corasick. Je to druh slovníkového vyhledávacího algoritmu, který hledá ve vstupním textu prvky z konečné množiny řetězců (slovníku). Vyhledává všechny řetězce současně. Asymptotická složitost je lineární vhledem k délce vyhledávaných řetězců a délce prohledávaného textu [1]. Algoritmus musí vytvořit konečný automat z konkrétního slovníku, nejdříve vytvoří trie (prefixový strom) z hledaných slov a poté zkonstruuje zpětné hrany pro každý uzel. Ukázka konečného automatu pro slovník „a, ab, bc, bca, c, caa“ je na Obrázku 4.11. Dalším krokem algoritmu je průchod konečným automatem, dochází ke čtení vstupního textu po znacích a následně k ukládání výsledků. Protože algoritmus najde všechny výskyty daného řetězce, může být nalezen až kvadratický počet výskytů, pokud by se shodoval každý podřetězec, například pro slovník „a, aa, aaa, aaaa“ a vstupní text „aaaa“. Jedním ze způsobů jak zajistit, aby se neprohledávaly subřetězce, tedy aby nedošlo ke shodě na řetězci „učitel“ pro slovo „učit“ ze slovníku, je přidat za každý vyhledávaný výraz mezeru. Nakonec však bylo od tohoto způsobu upuštěno, protože velice často nejsou slova v popiscích slev uváděna v základních tvarech a nedocházelo ke shodám na řetězcích typu „hotelu“ pro slovo „hotel“ ze slovníku. 84
4.4. Doporučování
4.4.2
Dávkové zpracování
Dalším problémem bylo jak zajistit dávkové zpracování, aby výpočet doporučování proběhl bez problémů i při milionech nabídek v databázi. Hibernate k tomuto účelu nabízí interface ScrollableResults, který umožňuje postupné načítání záznamů z databáze. Bohužel MySQL Connector/J toto chování pouze imituje, ve skutečnosti načte z databáze všechny záznamy. Při velkém záznamů samozřejmě dojde vyhození „OutOfMemoryError: Java heap space exceptions“ [8]. Problém byl vyřešen ručním nastavením limitu přímo v dotazu: SELECT ∗ FROM d e a l s WHERE de al I D > <maxIdOfLastbatch> ORDER BY de a lI D ASC LIMIT Nabídky jsou řazeny dle svých ID (dealID), nejvyšší ID (maxIdOfLastbatch) současné dávky je uchováno v paměti a v další dávce jsou dotázány pouze nabídky s vyšším ID. Před načtením další dávky je také proveden detach těchto entit od EntityManageru.
4.4.3
Update doporučení
Další implementační výzvou bylo, jak zajistit ukládání doporučení. V době řešení tohoto problému bylo v databázi cca 20.000 slevových nabídek, pro každou bylo ukládáno 10 doporučení nejpodobnějších nabídek. To znamená uložení nějakých 200.000 záznamů pro Content-based doporučování plus teoreticky až 200.000 záznamů pro kolaborativní filtrování. Pro kolaborativní filtrování nebylo tolik záznamů z důvodu nedostatku dat. Samotné persistování tolika záznamů bylo otázkou několika minut. Cílem bylo zajistit update doporučení v databázi, aby nedošlo k výpadku doporučovacího systému na webových stránkách. Truncate tabulky a následná persistence všech doporučení najednou nepřipadala v úvahu, došlo by k výpadku doporučovacího systému minimálně na několik minut. Možnost postupného mazání doporučení dle ID nabídek a ukládání aktuálních doporučení způsobovala vysoké vytížení databáze až na několik desítek minut. Nakonec byla vytvořena v databázi tabulka „recommendations_temp“, do které byly ukládány všechny aktuální doporučení. Po dokončení persistování všech záznamů dojde v jedné transakci k vzájemnému přejmenování tabulek „recommendations“ a „recommendations_temp“.
85
KAPITOLA
Testování 5.1
Testování experty
Testování experty bylo popsáno v kapitole 3.1.1.3, kde probíhalo testování na Lo-Fi prototypu. Nyní je třeba znovu otestovat vzniklou webovou aplikaci. Zde je krátký výčet problémů, které se podařilo odhalit. • Nefunkční přesměrování na slevový server Slevopolis. • Při nezadání hledaného výrazu a kliknutí na tlačítko „Hledej“ nefunguje filtrování nabídek. • V detailu nabídky není vidět popisek, pokud je příliš dlouhý a nevejde se na jeden řádek. • Při vypnutém JavaScriptu nefunguje správně filtrování nabídek. • Stránkování se zobrazuje i v případech, kdy není potřeba. • Rozhozený vzhled formulářů na mobilních telefonech s iOS a Android. Všechny nalezené problémy byly opraveny. Nalezena a opravena byla také celá řada dalších menších problémů, které se týkaly především vzhledu a neměly nic společného s funkčností webové aplikace.
5.2
Selenium
Selenium je sada nástrojů, která umožňuje automatizaci testů webové aplikace. Vytvořené testy je možné spouštět v řadě prohlížečů na různých platformách. Samotné testy je možné psát v mnoha programovacích jazycích, mezi které 87
5
5. Testování patří Java, PHP, Python48 . Selenium projekty jsou dostupné pod Apache 2.0 licencí. Selenium IDE je plugin pro prohlížeč Mozilla Firefox. Jedná se o nástroj, který usnadní psaní testů, protože umožňuje zaznamenávat interakce uživatele s webovou aplikací. Vytvořené testy je možné uložit, nebo dokonce exportovat do jednoho z podporovaných programovacích jazyků. Hlavní výhody testování pomocí Selenium: • Nezávislost na serverové technologii • Možnost testování v libovolném prohlížeči Byly vytvořené testy pokrývající tyto interakce s webovou aplikací: • Vyhledávání nabídek • Filtrování nabídek • Přihlášení přes Facebook • Přihlášení uživatele • Změna uživatelského hesla • Odhlášení uživatele • Vytvoření emailového zpravodaje • Editace emailového zpravodaje • Smazání emailového zpravodaje • Navštívení detailu nabídky • Napsání recenze slevového serveru Ukázka testu na vytvoření mailového zpravodaje: assertTrue ( selenium . isElementPresent ( "// a [ contains ( text ( ) , ’ Odhlasit ’ ) ] " ) ); s e l e n i u m . open ( " / s l e v y −na−e m a i l / " ) ; assertFalse ( 48 kompletní seznam podporovaných z http://seleniumhq.org/about/platforms.html
88
programovacích
jazyků,
dostupný
5.2. Selenium selenium . isTextPresent ( " E d i t o v a t Vase s l e v o v e z p r a v o d a j e " ) ); s e l e n i u m . type ( " i d=s e a r c h " , " s e l e n i u m T e s t 1 " ) ; s e l e n i u m . c l i c k ( " i d=show−d e a l s " ) ; f o r ( i n t s e c o n d = 0 ; ; s e c o n d++) { i f ( s e c o n d >= 6 0 ) f a i l ( " t i m e o u t " ) ; try { i f ( selenium . i s V i s i b l e ( " / / d i v [ @id=’ email −preview ’ ] / d i v [ 2 ] / h2 " ) ) break ; } c a t c h ( E x c e p t i o n e ) {} Thread . s l e e p ( 1 0 0 0 ) ; } assertEquals ( " Bohuzel momentalne n e b y l y n a l e z e n y zadne v y s l e d k y . " , s e l e n i u m . getText ( " / / d i v [ @id=’ email −preview ’ ] / d i v [ 2 ] / h2 " ) ); s e l e n i u m . c l i c k ( " i d=exposeMask " ) ; s e l e n i u m . c l i c k ( " i d=n e w s l e t t e r −submit " ) ; s e l e n i u m . waitForPageToLoad ( " 3 0 0 0 0 " ) ; assertEquals ( " seleniumTest1 " , s e l e n i u m . getText ( " / / form [ @id=’ n e w s l e t t e r −e d i t ’ ] / t a b l e / tbody / t r / td " ) ); a s s e r t E q u a l s ( " Vsechny " , s e l e n i u m . getText ( " / / form [ @id=’ n e w s l e t t e r −e d i t ’ ] / t a b l e / tbody / t r / td [ 2 ] " ) ); 89
5. Testování
a s s e r t E q u a l s ( " Denne " , s e l e n i u m . getText ( " / / form [ @id=’ n e w s l e t t e r −e d i t ’ ] / t a b l e / tbody / t r / td [ 3 ] " ) );
5.3
Apache Benchmark
Zátěžové testy byly prováděny opakovaně v nočních hodinách. Pro testování zátěže byla zvolena nejfrekventovanější stránka webové aplikace, stránka se všemi nabídkami. Testování probíhalo následujícím způsobem: ab −n 1000 −c xx h t t p : / /www. c o c h c e s . c z / s / • -n 1000: celkový počet odeslaných požadavků • -c xx: počet požadavků odeslaných paralelně Kompletní výsledek jednoho z testů: Server Software : S e r v e r Hostname : S e r v e r Port :
Apache / 2 . 2 . 2 2 www. c o c h c e s . c z 80
Document Path : Document Length :
/s/ 234097 b y t e s
Concurrency L e v e l : Time taken f o r t e s t s : Complete r e q u e s t s : Failed requests : Write e r r o r s : Total t r a n s f e r r e d : HTML t r a n s f e r r e d : Requests per second : Time p e r r e q u e s t : Time p e r r e q u e s t :
5 118.889 seconds 1000 0 0 234672000 b y t e s 234097000 b y t e s 8 . 4 1 [#/ s e c ] ( mean ) 5 9 6 . 4 4 3 [ ms ] ( mean ) 1 1 8 . 8 8 9 [ ms ] ( mean , across a l l concurrent requests ) 1 9 2 7 . 6 2 [ Kbytes / s e c ] r e c e i v e d
Transfer rate :
Connection Times (ms) min mean[+/−sd ] median Connect : 0 0 0.7 0 90
max 16
5.3. Apache Benchmark
Obrázek 5.1: Graf - Apache Benchmark
Processing : Waiting : Total :
438 428 438
593 566 594
41.6 41.0 41.6
584 557 584
781 752 781
Percentage of the r e q u e s t s served within a c e r t a i n time (ms) 50% 584 66% 596 75% 607 80% 612 90% 643 95% 692 98% 723 99% 743 100% 781 ( l o n g e s t r e q u e s t )
Během testování byl měněn především počet požadavků odesílaných paralelně. Jak je vidět z Obrázku 5.1, již při 15 paralelních požadavcích se doba zpracování blíží 2 vteřinám, což je z uživatelského pohledu příliš. Při současné návštěvnosti je naměřený výkon serveru dostačující. Je ale zřejmé, že pro zpracování více jak 25 paralelních požadavků je třeba výkonnější server. 91
5. Testování
Obrázek 5.2: Graf - Testování kvality doporučování
5.4
Testování kvality doporučování
Pro testování kvality doporučování byla využita data z Google Analytics49 . Byly porovnávány tyto způsoby doporučování: • Nejpopulárnější nabídky dle počtu prodaných kuponů. • Nejpodobnější nabídky k nabídkám navštíveným za poslední týden – Content-based – Kolaborativní filtrování Uživatelům byla generována na homepage doporučení jedním z výše uvedených způsobů. Sám uživatel nepoznal rozdíl, doporučení byla náhodně promíchána, takže bez nahlédnutí do zdrojového kódu nebylo možné určit, jakým způsobem bylo dané doporučení vygenerováno. Jak je vidět z grafu, viz. Obrázek 5.2, nejlépe si vede doporučovací algoritmus založený na content-based doporučování. Kolaborativní filtrování selhává s největší pravděpodobností z důvodu nízkého počtu uživatelů využívajících webovou aplikaci. Podobné nabídky pomocí kolaborativního filtrování bylo díky tomu možné spočítat pouze pro 47,6% všech nabídek v databázi.
49
92
Google Analytics, dostupný z http://www.google.com/analytics/
Závěr Cílem této práce bylo vytvořit agregátor slevových nabídek s doporučovacím systémem. Tento cíl se podařilo úspěšně splnit, byl navrhnut a implementován projekt složený celkem ze 4 částí - webové aplikace, parseru XML feedů, fulltextového vyhledávače a doporučovacího systému. Byly splněny všechny požadavky, které na projekt byly kladeny. Při vývoji doporučovacího systému byly zkoumány a testovány metody využívající kolaborativního filtrování i filtrování na základě podobnosti obsahu. Ukázalo se, že množství uživatelů, které v současnosti webovou aplikaci využívá, není dostatečné pro využití metod kolaborativního filtrování. Naproti tomu, doporučování na základě podobnosti obsahu se ukázalo být poměrně efektivní. Při vývoji webové aplikace pak byl kladen maximální důraz na uživatelskou přívětivost, přehlednost a moderní design. Webová aplikace se odlišuje od ostatních agregátorů tím, že je koncipována jako vyhledávač slevových nabídek, který navíc umožňuje pohodlné filtrování výsledků vyhledávání. V současnosti jsou agregovány nabídky z více než 50 slevových serverů a denně je tak k dispozici přes 1400 nabídek. O agregátor projevila zájem Mladá fronta a.s., která patří mezi 10 největších poskytovatelů obsahu v České republice. Vývoj agregátoru tedy bude s největší pravděpodobností pokračovat pod vedením Mladé fronty.
93
Literatura [1]
Aho-Corasick string matching algorithm. http://en.wikipedia.org/ wiki/Aho\T1\textendashCorasick_string_matching_algorithm, stav z 10. 4. 2012.
[2]
Aust, O.: Slevové servery sleduje 6 z 10 uživatelů v Česku, víc než třetina na nich už nakoupila. http://www.mediar.cz/ slevove-servery-sleduje-6-z-10-uzivatelu-v-cesku-vic-nez-tretina-na-nichuz-nakoupila/, stav z 10. 4. 2012.
[3]
Becker, L.: The Effective Website: Lo-fi Prototypes Yield High Returns. http://www.grouplens.org/papers/pdf/rec-sys-overview.pdf, stav z 12. 4. 2012.
[4]
Chirita, P.; Nejdl, W.; Zamfir, C.: Preventing shilling attacks in online recommender. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1. 1.60.1540&rep=rep1&type=pdf, stav z 10. 4. 2012.
[5]
Dočekal, D.: Česko a sociální sítě v číslech. http://www.lupa.cz/clanky/ cesko-a-socialni-site-v-cislech/, stav z 13. 4. 2012.
[6]
Dvořák, M.: Návrhové vzory (design paterns). http://objekty.vse.cz/ Objekty/Vzory, stav z 10. 4. 2012.
[7]
Google Inc.: About Sitemaps. http://support.google.com/webmasters/ bin/answer.py?hl=en&answer=156184, stav z 12. 4. 2012.
[8]
Using Hibernate’s ScrollableResults to slowly read 90 million records. http://stackoverflow.com/questions/2826319/ using-hibernates-scrollableresults-to-slowly-read-90-million-records, stav z 10. 4. 2012.
[9]
Kolektivní nakupování. http://cs.wikipedia.org/wiki/Kolektivní_ nakupování, stav z 10. 4. 2012.
[10] Linden, G.; Smith, B.; YorkPan, J.: Amazon.com Recommendations Item-to-Item Collaborative Filtering. http://superpeer8. das2.ewi.tudelft.nl/trac/raw-attachment/wiki/SimilarityFunction/ Amazon-Recommendations.pdf, stav z 10. 4. 2012.
Literatura [11] Pan, W.; Xiang, E. W.; Liu, N. N.; aj.: Transfer Learning in Collaborative Filtering for Sparsity Reduction. http://www.cse.ust.hk/~weikep/ papers/AAAI-10-CST.pdf, stav z 10. 4. 2012. [12] Pecinovský, R.: Návrhové vzory. Brno: Computer Press, a.s., 2007. [13] Ing. Žikovský PhD., P.: 2. přednáška – Návrh UI, prototypy. MI-NUR ZS 2011/12, stav z 12. 4. 2012. [14] Ing. Žikovský PhD., P.: 3. přednáška – Prototypes, Testing without users, Heuristics. MI-NUR ZS 2011/12, stav z 12. 4. 2012. [15] Ringier Axel Springer CZ. http://cs.wikipedia.org/wiki/Ringier_Axel_ Springer_CZ, stav z 10. 4. 2012. [16] Simple API for XML. http://cs.wikipedia.org/wiki/Simple_API_for_ XML, stav z 10. 4. 2012. [17] Seznam všech agregátorů a slevomatů. http://agregatory-slevomaty.cz/, stav z 10. 4. 2012. [18] Smiley, D.; Pugh, E.: Apache Solr 3 Enterprise Search Server. Packt Publishing, 2011. [19] Su, X.; Khoshgoftaar, T. M.: A Survey of Collaborative Filtering Techniques. http://www.hindawi.com/journals/aai/2009/421425/, stav z 10. 4. 2012. [20] Szabó, F.: Affiliate systém skrz.cz – neboli rival.cz. http://www.affilblog. cz/affiliate-system-skrz-cz-neboli-rival-cz/, stav z 10. 4. 2012. [21] Szabó, F.: Rozhovor: Martin Talavášek – rival.cz http://www.affilblog.cz/rozhovor-martin-talavasek-\T1\ textendash-rival-cz-skrz-cz/, stav z 10. 4. 2012.
(skrz.cz).
[22] Terveen, L.; Hill, W.: Beyond Recommender Systems: Helping People Help Each Other. http://www.grouplens.org/papers/pdf/ rec-sys-overview.pdf, stav z 10. 4. 2012. [23] U.S. Department of Health & Human Services: Wireframes. http://www. usability.gov/templates/wireframes.pdf, stav z 12. 4. 2012. [24] Zandl, P.: Agregátory slevových serverů natáhly ruku pro peníze. http:// www.lupa.cz/clanky/agregatory-slevovych-serveru-natahly-ruku/, stav z 10. 4. 2012. [25] Zandl, P.: Když se šetří s rozvahou: agregátory slevových serverů. http://www.lupa.cz/clanky/ kdyz-se-setri-s-rozvahou-agregatory-slevovych-serveru/, stav z 10. 4. 2012. 96
Literatura [26] Zandl, P.: Slevové servery po expanzi, před nástrahami: jak vypadá trh. http://www.lupa.cz/clanky/ slevove-servery-po-expanzi-pred-nastrahami-jak-vypada-trh/?do= articleText-pollInText4850-viewResult, stav z 10. 4. 2012. [27] Zandl, P.: Slevové servery v bublinkách konsolidace. http://www.lupa. cz/clanky/slevove-servery-v-bublinkach-konsolidace/, stav z 10. 4. 2012.
97
PŘÍLOHA
Seznam použitých zkratek SAX Simple API for XML JAXP Java API for XML Processing SQL Structured Query Language HQL Hibernate Query Language JPA Java Persistence API JPQL Java Persistence Query Language RDBMS Relational database management system MVC Model-View-Controller ORM Object Relational Mapper DBAL Database Abstraction Layer DQL Doctrine Query Language PECL PHP Extension Community Library PHP Hypertext Preprocessor
99
A
PŘÍLOHA
Obsah přiloženého CD
readme.html ................................. stručný popis obsahu CD dist ...................... adresár se spustitelnou formou implementace ccParser.jar....................................parser XML feedů ccRecommendation.jar ........................ doporučovací systém src ..................................... adresár se zdrojovými soubory impl...................................zdrojové kódy implementace ccParser.zip......archiv se zdrojovými kódy parseru XML feedů ccRecommendation.zip archiv se zdrojovými kódy doporučovacího systému CoChces.zip .......... archiv se zdrojovými kódy webové aplikace Solr.zip.....archiv se zdrojovými kódy fulltextového vyhledávače cochces.sql.........schema MySQL databáze s testovacími daty thesis ...................... zdrojová forma práce ve formátu LATEX DP_Vehovský_Martin_2012.zip . archiv se zdrojovou formou práce ve formátu LATEX text ....................................................... text práce DP_Vehovský_Martin_2012.pdf..........text práce ve formátu PDF 101
B