České vysoké učení technické v Praze Fakulta elektrotechnická
ˇ VUT FEL katedra pocˇı´tacˇu˚ C
Bakalářská práce
Normalizace dat pro neuronovou síť GAME Dezider Meško
Vedoucí práce: Ing. Mirek Čepek
Studijní program: Elektrotechnika a informatika Obor: Výpočetní technika Červen 2008
iv
Poděkování V úvodu bych chtěl poděkovat všem, kteří mi při vzniku této práce pomáhali jak s technickou, tak s formální stránkou. v
vi
Prohlášení Prohlašuji, že jsem svou bakalářskou práci vypracoval samostatně a použil jsem pouze podklady uvedené v přiloženém seznamu.
V Praze dne 13.6.2008
.............................................................
vii
viii
Abstrakt Tato práce pojednává o lineární a nelineární normalizaci vstupních dat před jejich použitím při výpočtech pomocí neuronových sítí. Tyto normalizace se implementují do systému FAKE GAME a poté je jejich implementace otestována. Následně je na několika souborech testovacích dat rámcově porovnán jejich vliv na úspěšnost modelů systému FAKE GAME.
Abstract This thesis deals with the linear and nonlinear input data normalization before it is used for neural networks calculation. These normalizations are implemented into FAKE GAME system and the implementation is afterwards tested. Its influence on GAME models is generally compared through several testing data files.
ix
x
Obsah Seznam obrázků
xiii
Seznam tabulek
xiii
1 Úvod
1
2 Metody normalizace
3
2.1
Lineární transformace – min-max normalizace . . . . . . . . . . . . . . .
3
2.2
Nelineární transformace - soft-max normalizace . . . . . . . . . . . . . .
5
2.3
Z-score normalizace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
2.4
Transformace střední hodnoty . . . . . . . . . . . . . . . . . . . . . . . .
9
2.5
Vlastní metody normalizace . . . . . . . . . . . . . . . . . . . . . . . . .
9
2.5.1
JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.5.2
Jazyk MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
3 Implementace
11
3.1
Podpůrná třída pro normalizaci . . . . . . . . . . . . . . . . . . . . . . .
12
3.2
Min-max normalizace . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
3.3
Soft-max normalizace . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.4
Z-score normalizace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
3.5
Transformace střední hodnoty . . . . . . . . . . . . . . . . . . . . . . . .
19
3.6
Uživatelem definovaná normalizace . . . . . . . . . . . . . . . . . . . . .
19
3.6.1
JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
3.6.2
Jazyk MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
4 Implementační testy
23
5 Funkční testy
25
5.1
Kosatce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
5.2
Nevyžádaná pošta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
6 Závěr
29 xi
7 Příloha – obsah přiloženého CD
31
8 Literatura
33
xii
Seznam obrázků 2.1
Kvůli hodnotě 80 jsou téměř všechny ostatní hodnoty transformovány do 60% výstupního rozsahu . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.2
Průběh funkce podle rovnice 2.4 s různými hodnotami parametru α . . .
5
2.3
Hodnoty transformované vztahem 2.5 s různými hodnotami parametru λ
6
2.4
Hodnoty transformované vztahem 2.4 s různými hodnotami parametru α při λ = 3
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.5
Velikost upravených hodnot po transformaci z-score normalizací . . . . .
8
2.6
Velikost hodnot po transformaci střední hodnoty . . . . . . . . . . . . . .
9
Seznam tabulek 3.1
Parametry modulu pro min-max normalizaci . . . . . . . . . . . . . . . .
14
3.2
Parametry modulu pro soft-max normalizaci . . . . . . . . . . . . . . . .
16
3.3
Parametry modulu pro z-score normalizaci . . . . . . . . . . . . . . . . .
17
3.4
Parametry modulu pro normalizaci střední hodnoty . . . . . . . . . . . .
19
3.5
Parametry modulu pro normalizaci skriptu v jazyce JavaScript
. . . . .
20
3.6
Parametry modulu pro normalizaci skriptu v jazyce MATLAB . . . . . .
21
5.1
Některé parametry systému FAKE GAME pro použití z příkazového řádku 25
5.2
Výsledky klasifikace květin při použítí různých normalizačních metod . .
26
5.3
Výsledky klasifikace zpráv při použítí různých normalizačních metod . . .
27
xiii
xiv
KAPITOLA 1. ÚVOD
1
1 Úvod Neuronové sítě dnes nacházejí stále širší možnosti uplatnění v různých průmyslových odvětvích. Jednou z možností z využití neuronových sítí je i dolování informací. Mezi systémy pro dolování informací patří i systém FAKE GAME. Tento systém sestává ze dvou částí. Část GAME (The Group of Adaptive Models Evolution) je neuronová síť založená na metodě GMDH (The Group Method of Data Handling), která si klade za cíl modelovat systémy z reálného světa na základě mnoha vstupních veličin, ale relativně málého množství záznamů těchto dat. Druhou částí je framework FAKE (The Fully Automated Knowledge Extraction), který zjednodušuje a automatizuje použití části GAME. [1] Cílem této práce je rozšířit možnosti frameworku FAKE o základní metody normalizace vstupních dat a ukázat některé možnosti použití systému FAKE GAME.
2
KAPITOLA 1. ÚVOD
KAPITOLA 2. METODY NORMALIZACE
3
2 Metody normalizace Mezi nejpoužívanější metody normalizace při úpravě vstupních dat pro neuronové sítě patří: • min-max normalizace (lineární transformace) • z-score normalizace (normalizace na základě odchylky od průměrné hodnoty) • dekadická normalizace (posuv desetinné čárky hodnot tak, aby spadaly do daného intervalu) • soft-max normalizace (nelineární transformace logistickou funkcí) V této práci se budu zabývat implementací některých z nich do systému FAKE GAME. Pro lepší představu o funkci jednotlivých transformací a jejich vzorců jsem vygeneroval náhodnou řadu čísel se dvěma extrémními hodnotami (peaks). Dále zobrazené grafy pak budou na ose x reprezentovat vstupní data a jejich hodnotu a na ose y data transformovaná. Z grafů je možné porovnat hodnoty a udělat si obrázek o tom, jak se ta či ona trasformace chová k danemu souboru hodnot.
2.1
Lineární transformace – min-max normalizace Obecný tvar lineární transformace můžeme vyjádřit rovnicí:
xi 0 = axi + b
(2.1)
kde a je koeficient zmenšení (zvětšení), x je transformovaná hodnota a b je velikost posuvu nové hodnoty. Častou úpravou je transformace dat do intervalu h0, 1i, pro kterou můžeme použít rovnici [2]:
xi 0 =
x − min(x1 ..xi ) max(x1 ..xi ) − min(x1 ..xi )
(2.2)
4
KAPITOLA 2. METODY NORMALIZACE
kde funkce min() a max() vracejí hodnotu nejmenšího a největšího prvku transformované množiny. Toto ovšem může být problém, protože při normalizaci musíme znát minimální a maximální hodnoty, které jsou známé pro množinu cvičných dat, ale ne pro množinu reálných vstupních dat. Důsledkem překročení rozsahu vstupních dat, je transformace hodnot mimo interval h0, 1i. Řešení tohoto problému spočívá v optimálním odhadu minimální a maximální vstupní hodnoty, nebo v ořezání, či úplnému vynechání hodnot překračujících předpokládaný vstupní rozsah. Převod z intervalu h0, 1i do jakéhokoli jiného už jednoduše provedeme pomocí rozšíření předchozí rovnice:
xi 0 =
xi − min(x1 ..xi ) × (Omax − Omin ) + Omin max(x1 ..xi ) − min(x1 ..xi )
(2.3)
kde Omax a Omin jsou hranice výstupního intervalu. Nevýhodou lineární normalizace je skutečnost, že v případě, kdy množina obsahuje hodnoty výrazně větší či menší, než je velikost střední hodnoty vstupních dat, zůstáva většina rozsahu nevyužita. Jestliže jsou tyto hodnoty navíc výsledkem špiček či anomálií, zapříčiní podstatné zkreslení relevantních vstupních informací.
Obrázek 2.1: Kvůli hodnotě 80 jsou téměř všechny ostatní hodnoty transformovány do 60% výstupního rozsahu
KAPITOLA 2. METODY NORMALIZACE
5
Jednou z možností, jak tento nepříjemný efekt potlačit, je použití nelineární transformace – soft-max normalizace.
2.2
Nelineární transformace - soft-max normalizace Tato transformace se chová k maximálním a minimálním hodnotám
jemně“. ” Transformuje je do úzkého rozsahu pomocí logaritmické funkce, zatímco většinu hodnot ve středu rozsahu transformuje lineárně. Takto se chová například tato funkce:
L(xi 0 ) =
1 1 + e−αxi 0
(2.4)
kde α určuje strmost křivky.
1 0.8 0.6 0.4 0.2 α=1 α=2 α=3
0 -10
-5
0
5
10
Obrázek 2.2: Průběh funkce podle rovnice 2.4 s různými hodnotami parametru α
Tato funkce sice splňuje požadavky na tvar, ale nedovoluje transformovat hodnoty z požadovaného rozsahu a také nedovoluje určit, jaká šířka rozsahu se má ještě transformovat lineárně. Z grafu funkce 2.2 je navíc vidět, že změna parametru α nijak výrazně nedovoluje ovlivnit výsledek transformace, a proto jeho automatické nastavovaní nemá velký smysl.
6
KAPITOLA 2. METODY NORMALIZACE
Obrázek 2.3: Hodnoty transformované vztahem 2.5 s různými hodnotami parametru λ
Jako řešní se nabízí transformovat nejdříve vstupní proměnnou lineárně k hodnotě blízké střední hodnotě mx následovně:
xi 0 =
xi − E(x) λ( σ2πx )
(2.5)
kde E(x) je střední hodnota veličiny x, σ x je směrodatná odchylka veličiny x (výpočet hodnoty σ x je uveden v kapitole 2.4) a λ je velikost lineární odezvy měřená v násobcích σ x (σ x pokrývá 68%, 2σ x pokrývá 95,5% a 3σ x pokrývá 99,7% rozsahu). Tyto hodnoty následně můžeme transformovat pomocí vztahu 2.4 do požadovaného rozsahu. Všimněme si na obrázku 2.4, že při parametrech α = 2 a 3 jsou už hodnoty okolo 40 transformovány stejně jako extrémní hodnota 80 – a blíží se 1,0.
2.3
Z-score normalizace Často používanou metodou pro standardizaci dat ve statistice je použití z-score
normalizace. Z-score vyjadřuje vzdálenost daného bodu (hodnoty) od střední hodnoty množiny. Tato vzdálenost je v případě z-score normalizace vyjádřena násobkem velkosti výběrové směrodatné odchylky.
KAPITOLA 2. METODY NORMALIZACE
7
Obrázek 2.4: Hodnoty transformované vztahem 2.4 s různými hodnotami parametru α při λ = 3
Střední hodnotu pro danou řadu dat získame vydělením součtu výsledků pozorování počtem těchto pozorování (rovnice 2.6). Střední hodnota udává centrální umístění a směrodatná odchylka udává rozptyl dané množiny dat. [3]
n 1X xi x= n i=1
(2.6)
Jako příklad lze uvést pohled na průměrnou teplotu ve dvou místech s různým klimatem. Zatímco obě místa mohou mít totožnou průměrnou teplotu, směrodatná odchylka místa ve vnitrozemí bude větší než místa na pobřeží. Toto poskytuje informaci o tom, že předpověď teploty pro místo ve vnitrozemí bude méně spolehlivá pravě kvůli větším odchylkám od průměru. [3] Zde je ještě dobré se pozastavit nad výpočtem hodnoty směrodatné odchylky σ x . Pro empiricky zjištěnou řadu čísel se používá výběrová směrodatná odchylka, kterou lze vypočítat podle vzorce:
σx =
v u u t
N 1 X (xi − x)2 N − 1 i=1
(2.7)
8
KAPITOLA 2. METODY NORMALIZACE
kde x je aritmetický průměr ze zadaných hodnot. Tento vzorec však vyžaduje předběžný výpočet x, což znamená jednu iteraci přes všechny vstupní hodnoty. Pomocí transformace tohoto vzorce na vzorec 2.8 však můžeme výpočet optimalizovat a všechny operace provést v jedině iteraci. Toto bude mít za následek téměř dvojnásobné zrychlení výpočtu. Podle [4] je však nevýhodou tohoto způsobu optimalizace riziko vlivu zaokrouhlovacích chyb na přesnost výsledku.
σx =
v u u t
N X 1 x2i − N x 2 N − 1 i=1
!
(2.8)
Obrázek 2.5: Velikost upravených hodnot po transformaci z-score normalizací Vstupní data normalizujeme tak, že od každé hodnoty odečteme střední hodnotu vstupních dat a poté výsledek vydělíme velikostí směrodatné odchylky.
z=
x−x σ
(2.9)
KAPITOLA 2. METODY NORMALIZACE
2.4
9
Transformace střední hodnoty Cílem této metody je docílit, nulové střední hodnoty vstupních dat. Toto může být
užitečné v případě, že máme více zdrojů porovnatelných dat se vzájemným offsetem. Jako dobrý příklad je možné uvést zpracování dat z několika teplotních senzorů. Tyto senzory nemusí být správně zkalibrované, ale správně vyjadřují hodnotu rozdílu měřených teplot. Normalizace probíhá zpracováním hodnot podle vzorce 2.10
x0 = x − x
(2.10)
kde x je střední hodnota dané množiny hodnot, x je aktuální hodnota z dané množiny.
Obrázek 2.6: Velikost hodnot po transformaci střední hodnoty
2.5
Vlastní metody normalizace Existuje velké množství metod pro normalizaci, ale v projektu FAKE GAME není
možné všechny dopředu zahrnout. Uživatel systému navíc může chtít upravit vstupní
10
KAPITOLA 2. METODY NORMALIZACE
hodnoty nějakým nestandartním způsobem. Pro tento účel je vhodné, aby si celý algoritmus normalizace mohl navrhnout a implementovat sám i za cenu snížené rychlosti výpočtu a větší pracnosti. Při volbě druhu skriptovacího jazyka jsem se rozhodl pro JavaScript a jazyk systému Matlab. 2.5.1
JavaScript JavaScript je skriptovací jazyk nejčastěji používaný při tvorbě webových stránek.
Je dynamický, slabě typovaný a objektově orientovaný. Jeho syntax se podobá syntaxi jazyka C a jazyka JAVA, které mnoho uživatelů ovládá, proto tvořit skripty v tomto jazyce pro ně nebude příliž složité. Od verze 1.6 jazyka JAVA je podpora tohoto skriptovacího jazyka nativní, což znamená, že pro psaní skriptů a jejich spuštění není třeba do systému instalovat žádné dodatečné knihovny či aplikace. Kód pro připočtení hodnoty 100 k vektoru testVector1 v jazyce JavaScript: for(i=0; i
2.5.2
Jazyk MATLAB Tento jazyk je rozšířený hlavně v akademické a výzkumné sféře. Jeho syntax je na-
víc přizpůsobena práci s maticemi a vektory. To velice ulehčuje zpracování vstupních dat, která jsou reprezentovány pravě jako vektory. Zatímco v jazyce JavaScript je třeba pomocí cyklu procházet všechny hodnoty a upravovat je jednotlivě, v jazyce MATLAB stačí provést operaci nad vektorem. Kód pro připočtení hodnoty 100 k vektoru testVector1 v jazyce MATLAB: testVector1=testVector1+100;
KAPITOLA 3. IMPLEMENTACE
11
3 Implementace Protože systém FAKE GAME je psaný v jazyce Java a je uvolněn pod licencí GPL [5], byla volba jazyka pro implementaci jednoznačná. Konkrétní použitá verze je Java 1.6. [6] Projekt využívá pro správu verzí systém Subversion. [7] Díky modularitě FAKE GAME je rozšíření systému velice snadné. Metody pro normalizaci si našly své místo v balíčku game.preprocessing.methods.Normalization.*. Každý typ normalizace má svou vlastní třídu, jejíž jméno je ve tvaru TypNormalizaceNormalizer a svoji vlastní třídu pro konfiguraci, jejíž jméno má tvar TypNormalizaceNormalizerConfig. Například pro soft-max normalizaci je to SoftmaxNormalizer a SoftmaxNormalizerConfig. Třída TypNormalizaceNormalizer od třídy game.preprocessing.methods.BasePreprocessor dědí a předefinuje metody. Jde například o run() (pro spuštění samotné normalizace) loadConfigurationFromFile(String filename) (pro načtení konfigurace při dávkovém zpracování vstupních dat) a některé další. Třída TypNormalizaceNormalizerConfig rozšiřuje třídu game.preprocessing.methods.BasePreprocessorConfig předefinováním funkce setInitialValues(). Tato metoda obsahuje volání funkcí addConfigKey() a add2IONames(), které slouží pro přidání, či inicializaci vstupních parametrů a výběr vstupních a výstupních hodnot. Konfigurace jednotlivých vstupních parametrů se provádí v konfiguračním dialogu každé jednotlivé normalizace (neplatí pro automatizované výpočty bez GUI, kdy se načte z uloženého souboru). Protože se bude zpracovávat více vstupních datových vektorů, je možné u všech číselných parametrů nastavit hodnotu pro každý vektor samostatně ve tvaru: vektor1=hodnota;vektor2=hodnota;vekstorX=hodnota Uživatelské rozhraní je možné rozšířit o nové funkce tak, že přidáme do souboru ./cfg/units.cfg řádek ve tvaru: #Normalization.LinearNormalizer, kde znak mřížky určuje dialog, kam se má daná možnost přidat (v našem případě je to preprocessing dialog). Normalization je název větve stromu, od kterého tečkou oddělíme jméno třídy, která se má pro daný úkon spustit.
12
KAPITOLA 3. IMPLEMENTACE
3.1
Podpůrná třída pro normalizaci Protože většina normalizačních tříd používá stejné funkce, umístnil jsem je do jedné
třídy NormalizationToolbox. Tato třída obsahuje dvě statické funkce. 1. separateCfgValues(HashMaphString, Doublei values, String configstring) – tato funkce slouží pro separaci konfiguračních řetězců. Rozkládá řetězce ve tvaru vektor1=hodnota; vektor2=hodnota; vekstorX=hodnota na páry klíč-hodnota. Toto umožňuje individuální konfiguraci pro každý datový vektor. 01: static public void separateCfgValues( HashMap<String, Double> values, String configstring) { 02: String[] pairs = configstring.split(";"); 03: for (String pair : pairs) { 04: String[] keyvalue = pair.trim().split("="); 05: if (keyvalue.length != 2) 06: continue; 07: 08: keyvalue[0] = keyvalue[0].trim(); 09: keyvalue[1] = keyvalue[1].trim(); 10: 11: if (keyvalue[0].isEmpty() || keyvalue[1].isEmpty()) 12: continue; 13: 14: Double value=0D; 15: try { 16: value = Double.parseDouble(keyvalue[1]); 17: } catch (NumberFormatException e) { 18: continue; 19: } 20: values.put(keyvalue[0], value); 21: } 22: }
2. getSigma(FastVector data, Double avg) – tato funkce se používá na výpočet směrodatné odchylky. Jako parametry má proměnnou data typu FastVector a proměnnou avg typu Double. V proměnné data jsou uložena data, pro která se má σ vypočítat. V proměnné avg funkce očekává střední hodnotu předávaných dat, kterou použije pro výpočet podle vzorce 2.7. V případě, že hodnota avg je null, funkce zvolí pro výpočet vzorec 2.8
KAPITOLA 3. IMPLEMENTACE
13
01: static public double getSigma(FastVector data, Double avg) { 02: int count = data.size(); 03: double temp = 0; 04: // if avg == null, we will use one pass sigma calculation 05: if (avg == null) { 06: avg = 0D; 07: for (int j = 0; j < count; j++) { 08: double value = ((Double) data.elementAt(j)).doubleValue(); 09: temp += (value * value); 10: avg += value; 11: } 12: avg /= count; 13: avg *= avg; 14: avg = avg * count; 15: temp = (temp - avg) / (count - 1); 16: return Math.sqrt(temp); 17: } 18: for (int j = 0; j < count; j++) { 19: double value = ((Double) data.elementAt(j)).doubleValue() - avg; 20: temp += value * value; 21: } 22: return Math.sqrt(temp / (count - 1)); 23: }
3.2
Min-max normalizace Jak bylo zmíněno v kapitole 2.1, při min-max normalizaci potřebujeme znát maxi-
mální a minimální hodnotu transformované množiny. Tu můžeme získat tak, že v prvním průchodu zjistíme extrémní hodnoty, v druhém průchodu provedeme samotnou transformaci. Další možnost je nechat na uživateli, aby zvolil hranice a všechny hodnoty, které jsou mimo tento rozsah budou ořezány na spodní resp. horní hranici. Mnou použitá implementace umožňuje aplikovat obě výše zmíněné metody. Pokud uživatel nenastaví konfigurační proměnné Input Low a Input High, nebo je nastaví obě na stejnou hodnotu, modul zjistí minum a maximum vstupních hodnot a tyto použije pro samotnou normalizaci. V opačném připadě použije hodnoty zadané uživatelem. Podobně funguje i nastavení výstupního rozsahu modulu. Jestliže jej uživatel nezadá, nebo zadá identické hodnoty Output Low a Output High, modul použije jako vý-
14
KAPITOLA 3. IMPLEMENTACE Jméno parametru
Význam
Datový typ
Předvolená hodnota
Input Low
Dolní hranice vstupu
Double
automaticky
Input High
Horní hranice vstupu
Double
automaticky
Output Low
Dolní hranice výstupu
Double
0
Output High
Horní hranice výstupu
Double
1
Tabulka 3.1: Parametry modulu pro min-max normalizaci stupní rozsah interval h0, 1i. Rychlost výpočtu je závislá jenom na počtu vstupních hodnot a na tom, jestli uživatel sám zvolí Input Low a Input High. V případě, že tak neučiní, je třeba tyto hodnoty zjistit a projít všechny vstupní hodnoty. Pak může proběhnout samotný výpočet podle vzorce 2.3. Časová složitost výpočtu je tak lineární. Podle toho, zda uživatel zadal vstupní hranice, funkce Run() zjistí maximální a minimální hodnotu vstupních dat (řádky 6-26). Poté v případě potřeby jednotlivé hodnoty ořeže tak, aby nebyly větší než zadané vstupní hranice (řádky 31-35) a nakonec je transformuje podle vzorce 2.3 (řádek 36) a přepočítá do daného výstupního rozsahu (řádek 38). 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
FastVector f = store.getDeepCopy(idx); Double inputMin = 0D, inputMax = 0D, avg = 0D; Integer count; count = store.getAttributeLength(idx); if (autorange) { for (int j = 0; j < count; j++) { double value = ((Double) f.elementAt(j)).doubleValue(); if (j == 0) { // initialize min and max value inputMin = value; inputMax = value; } avg += value; if (value < inputMin) { inputMin = value; continue; } if (value > inputMax) { inputMax = value; continue; }
KAPITOLA 3. IMPLEMENTACE 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
3.3
15
} avg /= count; imin = inputMin; imax = inputMax; } for (int j = 0; j < count; j++) { double value = ((Double) f.elementAt(j)).doubleValue(); double nvalue = 0; if (value > imax) { value = imax; } else if (value < imin) { value = imin; } nvalue = (value - imin) / (imax - imin); nvalue = nvalue * (omax - omin) + omin; f.setElementAt(new Double(nvalue), j); } store.setDeepCopy(idx, f);
Soft-max normalizace Logistická funkce použitá pro soft-max normalizaci má jen omezený rozsah, a tedy
i použití. Nastavení parametru α taktéž nepřináší rozšíření kontroly nad samotnou transformací. Jak bylo zmíněno a ukázáno v kapitole 2.2, je zajímavější kontrolovat transformaci prvotní úpravou hodnot, kde určíme šířku lineární odezvy funkce parametrem λ a až poté použít logistickou funkci. Implementace dovoluje nastavit všechny zmíněné parametry podle požadavků uživatele. Pokud uživatel nezadá parametr σ, funkce ho vypočítá automaticky. Rychlost výpočtu v tomto případě není závislá od nastavení parametrů uživatelem. I když jsme v kapitole 2.4 uvedli možnost, jak zrychlit výpočet parametru σ, střední hodnotu potřebujeme znát i pro výpočet podle rovnice 2.4, modul tedy vždy provede dva průchody vstupními hodnotami. V prvním průchodu vypočítá střední hodnotu, která se použije pro výpočet logistické funkce a výpočet parametru σ. Druhý průchod už přímo transformuje jednotlivé hodnoty podle vzorce 2.5 a 2.4. Časová složitost transformace je tak opět lineární.
16
KAPITOLA 3. IMPLEMENTACE
Jméno parametru
Význam
Datový typ
Předvolená hodnota
Alpha
Parametr logistické funkce
Double
2
Lambda
Násobek směrodatné odchylky
Double
2 (95,5%)
Sigma
Směrodatná odchylka
Double
automaticky
Output Low
Dolní hranice výstupu
Double
0
Output High
Horní hranice výstupu
Double
1
Tabulka 3.2: Parametry modulu pro soft-max normalizaci Samotná funkce Run() nejdříve vypočítá průměr ze vstupních hodnot (řádky 610), v případě že uživatel nezadal parametr Sigma vypočítá ho (řádky 11 a 12) a poté na každou hodnotu ze vstupních dat použije vzorce 2.5 a 2.4 (řádky 18 a 19). Finálně výslednou hodnotu přepočítá do zvoleného výstupního rozsahu (řádek 21). Zde stojí za zmínku, že pro výpočet podle vzorce 2.4 je použita funkce Math.expm1() (řádek 19), která podle [6] dává pro hodnoty blízké nule výrazně přesnější výsledky. 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
FastVector f = store.getDeepCopy(idx); Double avg = 0D; Integer count; count = store.getAttributeLength(idx); for (int j = 0; j < count; j++) { double value = ((Double) f.elementAt(j)).doubleValue(); avg += value; } avg /= count; if (sigma == 0) sigma = NormalizationToolbox.getSigma(f, avg); for (int j = 0; j < count; j++) { double value = ((Double) f.elementAt(j)).doubleValue(); double nvalue = 0; nvalue = (value - avg) / (lambda * (sigma / (2 * Math.PI))); nvalue = 1 / (1 + Math.expm1(-alpha * nvalue) + 1); nvalue = nvalue * (omax - omin) + omin; f.setElementAt(new Double(nvalue), j); } store.setDeepCopy(idx, f);
KAPITOLA 3. IMPLEMENTACE Jméno parametru
Význam
Average
17 Datový typ
Předvolená hodnota
Střední hodnota
Double
0
Sigma
Směrodatná odchylka
Double
1
Mode
Konfigurační režim
String
AUTO(0)
Config file path
Cesta ke konfiguračnímu
String
.\ZscoreNormalizer.cfg
souboru Tabulka 3.3: Parametry modulu pro z-score normalizaci
3.4
Z-score normalizace Z-score normalizace má pro každý z vektorů dat jako nastavitelné parametry veli-
kost střední hodnoty a směrodatné odchylky. Tato třída má tři pracovní režimy: 1. Režim AUTO. V tomto režimu se vypočítá směrodatná odchylka i střední hodnota každého z vektorů automaticky. Tento režim se zapíná nastavením konfigurační proměnné Mode na hodnotu AUTO nebo 0. Tento režim je předvolený. 2. Režim SEMI. V tomto režimu se v případě, že není nalezen konfigurační soubor na cestě zadané parametrem Config file path, vypočítají střední hodnota a směrodatná odchylka automaticky. Poté se vytvoří soubor, do kterého se spočítané hodnoty uloží. Při dalším spuštění se již použije vytvořený soubor. Tento postup je možné použít pro zjednodušení konfigurace (uživatel nemusí vyplňovat všechny hodnoty – stačí když upraví vytvořený soubor) nebo pro automatické nastavení, či jeho zachování pro opakované spuštění pro jinou množinu dat. Tento režim se zapíná nastavením konfigurační proměnné Mode na hodnotu SEMI nebo 1. 3. Režim MANUAL. V tomto režimu velikost střední hodnoty i směrodatné odchylky zadá sám uživatel. Tento režim se zapíná nastavením konfigurační proměnné Mode na hodnotu MANUAL nebo 2. 01: FastVector f = store.getDeepCopy(idx); 02: Double avg = 0D, sigma = 0D;
18 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45:
KAPITOLA 3. IMPLEMENTACE Integer count; count = store.getAttributeLength(idx); switch (mode) { default: case AUTO: // average input values for (int j = 0; j < count; j++) { double value = ((Double) f.elementAt(j)).doubleValue(); avg += value; } avg /= count; sigma = NormalizationToolbox.getSigma(f, avg); break; case SEMI: if (compute) { for (int j = 0; j < count; j++) { double value = ((Double) f.elementAt(j)).doubleValue(); avg += value; } avg /= count; sigma = NormalizationToolbox.getSigma(f, avg); avgString += ";" + datasetName + "=" + avg; sigmaString += ";" + datasetName + "=" + sigma; } else { avg = cavg; sigma = csigma; } break; case MANUAL: // use user defined value avg = cavg; sigma = csigma; break; } // process every value in dataset for (int j = 0; j < count; j++) { double value = ((Double) f.elementAt(j)).doubleValue(); double nvalue = (value - avg) / sigma; f.setElementAt(new Double(nvalue), j); } store.setDeepCopy(idx, f);
Funkce Run() operuje v závislosti na nastaveném režimu. V režimu AUTO (řádky 8-16) vypočítá velikost střední hodnoty a směrodatné odchylky. V režimu SEMI (řádky
KAPITOLA 3. IMPLEMENTACE
19
17-31) dle toho zda existuje nebo neexistuje konfigurační soubor hodnoty spočíta respektive načte. V režimu MANUAL (řádky 17-36) použije hodnoty zadané uživatelem. Poté podle vzorce 2.9 upraví jednotlivé hodnoty (řádky 39-43). Pro výpočet střední hodnoty a směrodatné odchylky je třeba projít všechny hodnoty – časová složitost algoritmu je linární.
3.5
Transformace střední hodnoty Třída pro transformaci střední hodnoty se téměř úplně shoduje s třídou pro z-
score normalizaci. Rovněž má tři funkční režimy. Chybí v ní však výpočet a konfigurační parametr pro hodnotu směrodatné odchylky σ. Výpočet proběhne podle vzorce 2.10. Jméno parametru
Význam
Datový typ
Předvolená hodnota
Average
Střední hodnota
Double
0
Mode
Konfigurační režim
String
AUTO(0)
Config file path
Cesta ke konfiguračnímu
String
.\MeanNormalizer.cfg
souboru Tabulka 3.4: Parametry modulu pro normalizaci střední hodnoty
3.6 3.6.1
Uživatelem definovaná normalizace JavaScript Skriptování jazykem JavaScript je implementováno třídou CustomJsNormalization.
Tato třída ma jediný parametr Script path, který udává cestu ke skriptu, jenž se má vykonat. Skript obdrží najednou všechny vektory dat jako jednotlivá pole. Tato pole jsou datového typu String a jejich jméno se shoduje se jmény vektoru v systému FAKE GAME. Zde je důležité upozornit na to, že pole je předáváno jako pole řetězců. Operace sčítání tedy automaticky přetypuje případné číslo opět na řetězec. To pak může mít za následek nepředvídatelné chování skriptu a programu. 01: ScriptEngineManager manager = new ScriptEngineManager(); 02: ScriptEngine engine = manager.getEngineByName("JavaScript"); 03:
20
KAPITOLA 3. IMPLEMENTACE Jméno parametru
Význam
Script path
Cesta k skriptu
Datový typ String
Předvolená hodnota c:\script.js
Tabulka 3.5: Parametry modulu pro normalizaci skriptu v jazyce JavaScript 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
// load every dataset as array into the javascript engine for (int i = 0; i < s.length; i++) { String datasetName = s[i]; int idx = store.getAttributeIndex(datasetName); FastVector f = store.getDeepCopy(idx); engine.put(datasetName, f.toArray()); } // execute script try { File tmp = new File(sPath); System.out.println(tmp.getAbsolutePath()); engine.eval(new FileReader(sPath)); } catch (FileNotFoundException e) { } catch (ScriptException e) { } // get variables back and store them for(String name : s){ int idx = store.getAttributeIndex(name); Object[] newValues = (Object[]) engine.get(name); FastVector f = new FastVector(); for (int j=0; j
Funkce Run() nejdříve vytvoří JavaScript engine (řádky 1-2), poté do něj přídá všechny vektory dat (řádky 5-9) a vykoná skript na cestě zadané uživatelem v parametru Script path (řádky 13-19). Nakonec vybere všechny hodnoty a uloží je zpět do systému FAKE GAME (řádky 22-30). 3.6.2
Jazyk MATLAB Implementace jazyka MATLAB je složitější než implementace jazyka JavaScript.
Pro vykonání samotného skriptu byl použit systém Octave, který je volně šířitelný pod
KAPITOLA 3. IMPLEMENTACE
21
Jméno parametru
Význam
Datový typ
Předvolená hodnota
Script path
Cesta k skriptu
String
c:\script.m
Octave path
Cesta k systému Octave
String
c:\program files\octave \bin\octave.exe
Tabulka 3.6: Parametry modulu pro normalizaci skriptu v jazyce MATLAB licencí GPL. [8] Jazyk tohoto systému je kompatibilní s jazykem MATLAB. Pro provázání systémů FAKE GAME a Octave bylo navíc potřeba využít knihovny joPAS. [9] Stabilní verze knihovny joPAS už je několik let stará a bylo ji potřeba upravit tak, aby fungovala s jazykem Java ve verzi 1.6. Při této úpravě jsem také odstranil starší knihovny, které jsou už použity v systému FAKE GAME a zmenšil tak velikost knihovny joPAS na 30kB (původně 4,1MB). Taktéž jsem přidal další konstruktor pro objekt Matrix, díky kterému se zjednodušší jeho používání. Stejně jako v předchozím případě jsou všechny datové vektory předány najednou pod jménem vystupujícím v systému FAKE GAME. Samotnou implementaci je možno najít ve třídě CustomOctaveNormalizer. Kromě parametru Script path, který by měl odkazovat na soubor se skriptem, má tato třída ještě parametr Octave path, kde je třeba nastavit cestu k systému Octave. Poměrně závažným nedostatkem je, že systém Octave startuje až několik sekund a tak výrazně prodlužuje celý proces normalizace. 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16:
// joPAS initialization String[] path = { oPath }; Jopas jopas = new Jopas(path); // load every dataset into the jopas variable for (int i = 0; i < s.length; i++) { String datasetName = s[i]; int idx = store.getAttributeIndex(datasetName); FastVector f = store.getDeepCopy(idx); Double[] doublearray = new Double[f.size()]; Object[] objarray = f.toArray(); for(int j=0; j<doublearray.length; j++){ doublearray[j]=(Double) objarray[j]; }
22 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
KAPITOLA 3. IMPLEMENTACE
// push jopas params Matrix tmpMatrix = new Matrix(doublearray, datasetName); jopas.Load(tmpMatrix); } // execute jopas script sPath = sPath.replace(’\\’, ’/’); jopas.Execute("source (\"" + sPath + "\")"); // pop jopas params and store it for(String name : s){ int idx = store.getAttributeIndex(name); Matrix result = jopas.Save(name); if(!result.isVector()){ System.out.println("Dataset "+name+" is not vector, skipping"); continue; } FastVector f = new FastVector(); int cols = result.getColumns(); for (int j=0; j
Funkce Run() vytvoří objekt jopas, který má na starosti komunikaci se systémem Octave (řádky 1-3). Dále vytvoří matice dat se jmény ekvivalentními jménům v systému FAKE GAME a načte je do engine joPAS (řádky 5-21). Provede skript zadaný uživatelem pomocí parametru Script path (řádky 23, 24). Nakonec všechny data vybere, uloží zpět do systému FAKE GAME (řádky 27-39) a ukončí systém Octave (řádek 42).
KAPITOLA 4. IMPLEMENTAČNÍ TESTY
23
4 Implementační testy Přestože projekt FAKE GAME nemá žádnou zaužívanou metodiku pro testování kódu, který programátoři napíší, rozhodl jsem se, že budu svůj kód automaticky testovat. Za standard pro automatické testování se v dnešní době považuje systém JUnit. [10] Tento systém vznikl z obdobného systému pro jazyk SmallTalk. Principem tohoto systému je, že programátor napíše testy pro jednotlivé moduly programu (ty mohou být reprezentovány například třídami) a v rámci vývojového cyklu jsou tyto testy opakovaně spouštěny. Předpokládá se, že jestliže je každá část systému funkční, je výrazně větší šance, že i celý systém bude fungovat. Testování tímto způsobem poté nabízí řadu výhod: • testy zajistí, že po změně v některém z modulů nevznikne chyba či nekompatibilita na jiném místě • testy je možno napsat dříve než samotný kód, a tak ověřit správnost návrhu rozhraní (vývoj řízený testováním) • kód separovaný do modulů se dá provázat deklarativně (třeba pomocí Google Guice nebo Spring) Psaní testů v systému JUnit 4.0 probíhá následovně: ? uživatel vytvoří třídu (TestCase) s metodami, ve kterých testuje daný modul. Jednotlivé metody třídy označí pomocí anotací. Díky tomu systém rozpozná, která metoda se má volat před samotným testem (@Before), která metoda je vlastní test (@Test), a která metoda se má volat po testu (@After) ? poté názvy všech testovacích tříd shrne ve třídě (TestSuite), která zabezpečí jejich postupné spuštění a vyhodnocení. Pro vykonání mnoha testů je třeba, aby byla k dispozici data či objekty, na kterých bude možné dané operace otestovat. Tyto objekty (mock objects) jsou vytvořeny uměle jenom za účelem testování. Pro testování tříd pro normalizaci bylo potřeba vytvořit jediný falešný objekt, a to objekt typu SimplePreprocessingStorage, obsahujicí datové vektory. Pravě vytvoření tohoto objektu v každém testu má za úkol metoda setUp(), která je
24
KAPITOLA 4. IMPLEMENTAČNÍ TESTY
označena anotací @Before. Testy samotné operují nad tímto úložištěm a poté porovnávají výsledky dané normalizace s očekávaným výsledkem pomocí metody assertArrayEquals(), která porovnává jednotlivé prvky pole a v případě neshody vyhodnotí test jako neůspěšný. Pro testování normalizačních tříd jsem pro každou z nich vytvořil třídu s názvem jménoTřídyTest tzn. například LinearNormalizerTest. Vytvořená třída obsahuje výše zmíněnou metodu setUp(), která se stará o přípravu testovacích dat, a několik metod, které se starají o samotné testování. Všechny tyto třídy jsou obsaženy v třídě AllNormalizationTests, která zabezpečí jejich postupné provedení. Celkově proběhne patnáct testů, které například kontrolují správnost výstupního rozsahu metod nebo jejich funkčnost v různých režimech. Na závěr je třeba zdůraznit, že tyto testy pomohly odhalit několik chyb, které byly zaneseny do kódu při jeho změnách a optimalizaci, a dokonce se postaraly i o odhalení chyb mimo samotný balíku game.preprocessing.methods.Normalization. Tímto prokázaly, že jejich použití má smysl, zvyšuje kvalitu kódu a snižuje čas potřebný na údržbu projektu.
KAPITOLA 5. FUNKČNÍ TESTY
25
5 Funkční testy Test vlivu každé normalizace byl ověřován její aplikací na skupiny testovacích dat a poté bylo provedeno vyhodnocení uspěšnosti klasifikace neuronové sítě. Protože systém FAKE GAME používá genetické algoritmy, je třeba každý test několikrát zopakovat, abychom jsme se vyhnuli náhodně neůspěšnému či naopak příliž úspěšnému modelu. Pro několikanásobné opakované testování není efektivní používat grafické rozhraní systému FAKE GAME. Proto jsou všechny testy vykonány přes příkazový řádek. Jméno parametru
Význam
-h nebo –help
Zobrazí všechny parametry
-n h číslo i nebo –number h číslo i
Počet vytvořených modelů
-d h soubor i nebo –traindata h soubor i
Soubor s trénovacími daty
-t h soubor i nebo –testdata h soubor i
Soubor s testovacími daty
-s h soubor i nebo –script h soubor i
Soubor se skriptem pro preprocessing
-c h soubor i nebo –config h soubor i
Soubor s konfigurací systému GAME
Tabulka 5.1: Některé parametry systému FAKE GAME pro použití z příkazového řádku Konkrétní konfigurace použitá při testech: java -Xmx512M -Xms128M -Djava.library.path=../lib/net.java.dev.j3d; ../lib/net.java.dev.jogl; -jar ../lib/fake_runtime.jar -c ../cfg/config.cfg -n 1 -d ../data/data1.txt -t ../data/data1test.txt -s preprocessing.scr Pro konfiguraci byl použit soubor config.cfg, který obsahuje základní – nijak upravovanou – konfiguraci systému GAME. Výpočet modelů byl omezen na jeden. Pro preprocessing byly použity skripty obsahující vždy jednu normalizační metodu. Skript má nasledující tvar: "název normalizace 1" "konfigurační soubor 1" "název normalizace 2" "konfigurační soubor 2" . . . "Mean value normalizer" "mean.config"
26
KAPITOLA 5. FUNKČNÍ TESTY
bez normalizace
min-max
soft-max
mean
z-score
[%]
normalizace [%]
normalizace [%]
normalizace [%]
normalizace [%]
1
100
100
100
100
100
2
100
100
100
100
100
3
100
100
100
100
100
4
100
100
100
100
100
5
100
100
100
100
100
Iris setosa
1
100
100
93,3
100
100
2
86,6
73,3
100
86,6
100
3
100
73,3
100
86,6
100
4
100
100
100
100
73,3
5
86,6
100
100
93,3
100
1
93,3
93,3
100
100
80
2
100
100
100
100
100
3
73,3
73,3
100
100
73,3
4
93,3
73,3
100
100
100
5
100
86,3
100
100
100
Iris versicolor
Iris virginica
Průměr
seto.
100
100
100
100
100
vers.
94,4
89,3
98,6
93,3
94,6
virgi.
91,8
85,3
100
100
90,6
95,5
91,5
99,5
97,7
95,1
Celkem
Tabulka 5.2: Výsledky klasifikace květin při použítí různých normalizačních metod Jednotlivé objekty budou postupně za sebou volány s konfigurací načtenou ze souboru. Díky tomu, že metody lze řetězit, je možné použít několikrát tu samou metodu různým způsobem (s různou konfigurací). Například pro jeden datový vektor použít automatické zpracování a pro další použít ručně zadaných hodnot.
5.1
Kosatce V této úloze je použita neuronová síť pro rozeznávaní druhů kosatců (konkrétně
druhů Iris Setosa, Iris Versicolor, Iris Virginica) podle velikosti jejich okvětních lístků a korunních plátků. Pro učení byla použita množina 135 měření. Pro test bylo vybráno jiných 15 měření (všechny tři druhy měly stejné početné zastoupení). Výpočet modelu a následná klasifikace byly zopakovány pětkrát pro každou metodu, a také pro případ, kdy nebyla použita žádná normalizační metoda. Všechny měření byly realizovány nejen se základním nastavením pro systém GAME, ale i se základním
KAPITOLA 5. FUNKČNÍ TESTY
27
nastavením všech normalizačních metod – předvolené hodnoty je možné videť v tabulkách 3.1, 3.2, 3.3 a 3.4. Z tabulky 5.2 je patrné, že neuronová síť měla největší problémy s určováním druhů virginica a versicolor. Největší úspěšnost měly soft-max a mean normalizace, které jako jediné byly lepší než model vytvořený bez normalizace.
5.2
Nevyžádaná pošta V tomto úkolu má neuronová síť na základě několika indexů rozhodnout o tom, zda
příchozí zpráva patří (spam) nebo nepatří (ham) do nevyžádané pošty. Pro učení byla použita množina 654 případů a pro test bylo použito dalších 219 případů. bez normalizace
min-max
soft-max
mean
z-score
[%]
normalizace [%]
normalizace [%]
normalizace [%]
normalizace [%]
1
89,4
90,8
91,3
90,8
84,9
2
89,9
86,3
90,8
89,9
89,9
3
87,2
89,0
90,4
90,4
90,8
4
91,7
91,7
87,2
92,2
91,3
5
90,4
88,1
91,3
85,3
90,8
1
87,2
91,7
90,4
90,4
89,4
2
88,5
89,9
89,0
92,3
91,7
3
91,3
87,2
91,3
92,2
90,8
4
91,3
87,6
89,9
86,3
92,6
5
92,2
90,4
89,9
91,3
90,8
spam
89,7
89,1
90,2
89,7
89,5
ham
90,1
89,3
90,1
90,5
91,0
89,9
89,2
90,1
90,1
90,3
Spam
Ham
Průměr Celkem
Tabulka 5.3: Výsledky klasifikace zpráv při použítí různých normalizačních metod Z tabulky 5.3 je zřejmé, že v tomto případě normalizace nijak nenapomáhá k markantně lepším výsledkům. Příčinou by mohlo být, že drtivá většina dat spadá do intervalu (-1, 1) a rozložení hodnot v tomto intervalu je rovnoměrné. Je důležité, že i když normalizace nenapomáhá k výrazně lepším výsledkům, současně tyto výsledky ani nezhoršuje (většina normalizací ve skutečnosti výsledky přeci jen zlepšila v řádech desetin procent).
28
KAPITOLA 5. FUNKČNÍ TESTY
KAPITOLA 6. ZÁVĚR
29
6 Závěr Normalizace dat je důležitou součástí procesu dolování informací pomocí neuronových sítí. Při implementaci jednotlivých metod jsem se snažil najít kompromis mezi jednoduchostí jejich nastavení a možnostmi, které poskytují. Výsledkem je, že je buď možné nastavit každou metodu indviduálně pro jednotlívé vektory dat, nebo metodu vůbec nekonfigurovat a využít její automatické nastavování. Pro maximální kontrolu uživatele nad normalizací jsem přidal třídy, pomocí kterých si uživatel může celý proces normalizace naprogramovat sám v jazycích JavaScript nebo Matlab. Jak ukázaly testy v závěru, je stále zapotřebí, aby uživatel zvážil použití daných normalizačních metod na konkrétní množině dat. I když obecně normalizační metody ani při neopodstatněném použití výrazně nesnižují úspěšnost GAME modelů, prodlužují dobu výpočtu. Jako možnost pro další zlepšení je možné uvažovat o rozšíření metod tak, aby samotné metody byly schopny vyhodnotit zda je jejich použití vhodné, případně aby byly schopné navrhnout uživateli optimální nastavení svých parametrů.
30
KAPITOLA 6. ZÁVĚR
KAPITOLA 7. PŘÍLOHA – OBSAH PŘILOŽENÉHO CD
7 Příloha – obsah přiloženého CD baka.pdf game-dist-20080610.zip DIST JDK SRC
- soubor bakalářské práce - soubor s distribucí systému FAKE GAME sestavené dne 10.6.2008 - adresář s distribucí systému FAKE GAME, spolu s daty použitými pro testování v BP - adresář s instalačním souborem JDK 1.6 - zdrojové soubory projektu FAKE GAME
31
32
KAPITOLA 7. PŘÍLOHA – OBSAH PŘILOŽENÉHO CD
KAPITOLA 8. LITERATURA
33
8 Literatura [1] Pavel Kordík. Fully Automated Knowledge Extraction using Group of Adaptive Models Evolution, 2006. http://neuron.felk.cvut.cz/game/doc/fake-game.pdf. [2] D. P. Solomatine.
Data-driven modelling: machine learning, data mining and
knowledge discovery, 2003. http://datamining.ihe.nl/tutorial/HTML/. [3] Výpočet směrodatné odchylky. http://en.wikipedia.org/wiki/Standard_deviation. [4] Výpočet směrodatné odchylky. http://cs.wikipedia.org/wiki/Sm%C4%9Brodatn%C3%A1_odchylka. [5] Domovská stránka projektu FAKE GAME. http://sourceforge.net/projects/fakegame/. [6] Dokumentace jazyka Java. http://java.sun.com/javase/6/docs/api/. [7] Domovská stránka systému Subversion. http://subversion.tigris.org/. [8] Dokumentace systému Octave. http://www.gnu.org/software/octave/docs.html. [9] Dokumentace knihovny joPAS. http://jopas.sourceforge.net/documents-eng.html. [10] Dokumentace systému JUnit. http://junit.sourceforge.net/javadoc_40/index.html.