• No results found

4 Hledání charakteristického okolí

Tabulka 3 - Konfigurace PC, na kterém byl skript testován

4.3 použitý algoritmus

'1. my $line = unpack('J', $index[3333]);

: 2. seek $korpus, $line, 0;

: 3. chomp($ = <$korpus>);

Ani tato metoda se neprojevila jako příliš vhodná, poněvadž stále musíme pro každého kandidáta zjistit všechny řádky, na kterých se vyskytuje, a s nimi dále pracovat.

Samozřejmě, že na řádku většinou je kandidátu více, takže každý řádek musíme zpracovat vícekrát. Časová náročnost tohoto řešení s počtem zpracovávaných kandidátů exponenciálně rostla.

4.3 použitý algoritmus

Nejvhodnější postup byl samozřejmě nalezen až naposled. Klidně by se dalo říct, že nejvýkonnější postup je ten nejjednodušší. Postup by se tedy dal popsat pomocí čtyř fází popsaných v následujících podkapitolách. Důležitým prvkem všech částí skriptu je fakt, že veškerá vytvořená data, která už nebudou pro další běh programu nutná, je potřeba odstranit z paměti, nebo alepsoň přepsat těmi důležitými.

4.3.1 načtení kandidátů

V první fázi se otevře soubor s jednotlivými kandidáty. Ten se zpracuje řádek po řádku (každý řádek reprezentuje jedno slovo). Toto slovo se musí nějak uložit.

Nejvhodnější metoda bude tedy tohoto kandidáta zadefinovat v rámci asociativního pole, kde klíč bude dané slovo a hodnota bude pouze reprezentovat to, že je tento klíč v poli obsažen, například zjednodušeně:

j 1. while ( my $line = <$kandidati> ) {

! 2. $hashKandidati{$line( = {);

[ 3. }

4.3.2 hledání konkrétních okolí

Druhá část algoritmu má za úkol to nejdůležitější - hledaní okolí z daného zdrojového korpusu (kde každý řádek reprezentuje jednu větu). Snahou o minimalizaci počtů průchodů tímto souborem, neboť bývá obvykle velmi velký, bylo dosaženou pouze jednoho nutného průchodu. Každý jednotlivý řádek (větu) rozdělí pomocí

regulárního výrazu na slova a ty postupně zpracuje. Kdyby pro každé takovéto slovo měl algoritmus iterovat přes všechny kandidáty (zjišťovat, zda slovo je v poli kandidátů), časové nároky by neúměrně rychle rostly. Zde je vidět důvod, proč bylo použito asociativní pole. Tímto způsobem je možno testovat jednoduchou podmínku, zda daný klíč v hashi existuje. Pokud ano, následuje několik větvení skriptu tak, aby se žádná podmínka nevyhodnocovala vícekrát, což by opět znamenalo zpomalení algoritmu. V použitém programu bylo vycházeno z toho, že je třeba hledat pětice slov, kde hledaný kandidát je nejlépe uprostřed. V případě, že je daný kandidát v rámci věty na takovém indexu, že nemůže být uprostřed hledané pětice (reálný index okrajů pětice by byl mimo maximální, resp. minimální index věty), je střed posunut o pozici vlevo, resp. vpravo. Zároveň se počítá s tím, že celá věta může být kratší než pět slov. V tom případě se okolí zkrátí na maximální možné.

Každé takto nalezené okol! je uloženo do původně definovaného asociativního pole. Respektive jako hodnota asociativního pole kandidátů je nové asociativní pole, jehož klíče jsou jednotlivé nalezené okolí a hodnoty jejich četnosti. To znamená, že pro

každé okolí zvýšíme hodnotu hashe hashů o jedničku:

• 1. $hashKandidat±{$kandidat}{$okoli}++;

Po zpracování celého korpusu je možno přikročit k další části.

4.3.3 nalezení nejčetnějších okolí

Ve třetí fázi je pomocí cyklu zpracován každý kandidát, jehož jednotlivé okolí jsou seřazeny podle jejich četností od nejvyšší po nejnižší. Pokud se omezíme jen na nejčetnější (například 5), je už možné mluvit o charakteristickém okolí daného kandidáta v rámci zdrojového korpusu. Zejména pro účely následného exportu jsou nečetnější okolí převedeny do řetězce odděleného tabulátorem (\t). Tímto řetězcem je následně nahrazeno asociativní pole jednotlivých okolí daného kandidáta:

jl. $hashKandidati{$kandidat} = $charOkoliOddeleneTabem;

Takto přehodnocené asociativní poleje už plně připravené pro následný export.

4.3.4 export výsledků

V poslední části běhu programu stačí pouze výsledky vhodně exportovat.

Vzhledem k tomu, že je potřeba data následně importovat do samostatné aplikace, bude opět výstupem programu soubor. Ten bude obsahovat stejný počet řádků jako vstupní soubor kandidátů, tzn. na každém řádku bude daný kandidát, jeho četnost v rámci korpusu a nakonec jeho zjištěné charakteristické okolí. Tyto tři hodnoty by měly být odděleny jinak, než jednotlivá nalezená okolí, aby při importu do databáze vlastní aplikace server poznal, které hodnoty jsou které a nedošlo tak k oseknutí posledních několika okolí. Proto byl použit oddělovač ve formě dvou středníků za sebou ( ; ; ) .

4.4 použití

Celý tento skript se používá velice jednoduše. Jelikož je Perl, jak už bylo řečeno, jazyk interpretovaný, nemusí se program kompilovat. Jeho použití pouze závisí na tom, zda je v systému Perl nainstalovaný. Poté se jednoduše spustí například pomocí příkazové řádky:

|1. kwic.pl korpus.txt kandidati.txt

Prvním parametrem programu je název textového souboru, který obsahuje zdrojový korpus, druhým parametrem je název souboru obsahující seznam kandidátů, ke kterým je potřeba okolí nalézt. Po úspěšném dokončení skriptu je vytvořen výsledný soubor, který se bude jmenovat stejně, jako původní soubor kandidátů, ovšem s koncovkou „.out".

Při testování na korpusu o velikosti cca 500 MB a při hledání okolo 300 000 kandidátů bylo dosaženo na testovacím počítači výsledného času kolem 150 sekund s paměťovými nároky necelých 300 MB.

5 Závěr _ J

Cílem této práce bylo vytvořit software, který umožní efektivní tvorbu diktovacích slovníků. Ty jsou potřeba pro úspěšné rozpoznávání řečového signálu.

Z hlediska technologie bylo nutné navrhnutou aplikaci založit na síťové architektuře.

Proto byl navržen model webové aplikace, kde veškeré důležité algoritmy budou probíhat na serveru a klienti se k němu budou připojovat pomocí běžných webových prohlížečů.

Proto byl pro tuto část použit skriptovací jazyk PHP spolu s databází SQL. Ovšem kdyby byly použity jen tyto jazyky bez jakýchkoliv nadstaveb, výsledná aplikace by byla velice nepřehledná a špatně udržovatelná. Z tohoto důvodu byl nasazen Nette framework, který se ukázal jako velmi výkonný pomocník. Stará se o základní funkce systému ^ řídí běh aplikace a usnadňuje vývoj některých běžných funkcionalit (např.

autorizace a autentizace, formuláře, zabezpečení, atd.). Pro vyšší uživatelskou přívětivost byl použit klientský JavaScript spolu s frameworkem jQuery.

Z původních požadovaných funkčních nároků na aplikaci byly téměř všechny implementovány. Umožňuje spravovat uživatele, jejich role a oprávnění. Nabízí intuitivní uživatelské rozhraní pro opravování a zpracovávání slov, tvoření jejich výslovnostních variant a k nim příslušných fonetických transkripcí. Zároveň je možné slova rychle vyhledávat na internetu, aby bylo jasné, co znamenají. K tomuto účelu slouží i náhled na charakteristické okolí z původního zdrojového korpusu. Pokud by se stalo, že opravený tvar slova již ve výsledném slovníku je, aplikace na tuto skutečnost upozorní a ušetří tím práci.

Použití skloňování slov pomocí SpellCheckeru se ve výsledku ukázalo jako nepraktické pro tuto fázi vytváření slovníku. Lepší je tohoto využít již při generování kandidátů ze zdrojového korpusu, což nebylo obsahem této práce. Proto tato funkčnost nebyla implementována. Místo toho byla aplikace rozšířena tak, aby umožňovala zpětnou vazbu mezi administrátorem a řešitelem v případě chybně vyplněných dat.

V poslední části práce byl vytvořen algoritmus v jazyce Perl, který umožňuje nalezení reprezentativního okolí daných kandidátů v rámci zdrojového textového korpusu. Při práci na tomto skriptu muselo být řešeno to, že zpracovávaná data jsou hodně rozsáhlá. Funkčnímu řešení tedy předcházelo několik nefunkčních, resp.

nepoužitelných. Toto charakteristické okolí je poté, mimo jiné, vstupem vlastní aplikace.

Použité zdroje J

Related documents