= Zpracování metainformací = #Zpracov.2BAOE-n.2BAO0_metainformac.2BAO0- [[BR]] Tento článek popisuje využití metainformací. Ty jsou využitelné pro zjištění statistik o korpusových datech a pro vytváření specializovaných korpusů. == Co je cílem == #Co_je_c.2BAO0-lem Naším primárním cílem je z vertikálního textu vytvořit korpus. Pokud vytváříme specializovaný korpus (např. dokumenty jen z oblasti ekonomie), využíváme metainformace, kde jsou vyznačeny potřebné údaje. Metainformace jsou uloženy jako textové soubory ve stejném adresáři jako vertikál. Pokud chceme s nimi pracovat nabízejí se nám tyto možnosti: programy typu textutils - grep, sort, cut, ... anebo SQL databáze. == Metainformace jako textová databáze == #Metainformace_jako_textov.2BAOE_datab.2BAOE-ze Pro využití nástrojů ze sady textutils je vhodné metainformace trochu přeskupit - a to tak aby jeden řádek odpovídal jednomu dokumentu. V praxi použitý program make_doc_list pro každý soubor s metainformacemi vytiskne na jeden řádek dvojtečkou oddělené atributy !Signatura:Size:Lemmat:Offset:Doc_id:Vertikal:T_Main:T_Sub {{{ A3B7550:3614:52%;10%:19446,23372:S/NWS/1992/lnfi9210/011:cnk25/LNFI/lnfi9210.vert:MIX:MIX AAAA366E:400:96%;84%:9751,2827:S/NWS/1996/ln96238p/006:cnktag/LN/1996/ln96238p.vert:sci2:pol }}} V adresáři /nlp/corpora/vertical/INFO_O_DUPLICITACH/ je několik souboru *.list, které byly vytvořeny vždy jako textová databáze metainformací pro každý korpus a to takto: {{{ $ cd korpus $ traverse_dir meta make_doc_list > korpus.list }}} Viz také /nlp/corpora/vertical/INFO_O_DUPLICITACH/Makefile. Pokud chceme tedy vytvořit ekonomický korpus ze všech zdrojů, které jsou k dispozici tak zadáme: {{{ $ cat /nlp/corpora/vertical/INFO_O_DUPLICITACH/vertikal.list \ | egrep ':eco:eco$' \ #vybereme radky odpovidajici dokumentum z ekonomiky | cut -d: -f4-6 \ #vybereme udaje pro program list2vert | list2vert #ze seznamu dokumentu vytvorime vertikalni text }}} == Metainformace jako SQL databáze == #Metainformace_jako_SQL_datab.2BAOE-ze Metainformace jsou uloženy v SQL databázi MySQL na stroji faunus. Tato forma uložení poskytuje oproti textové databázi mocnější dotazovací prostředek a u netriviaálních dotazů mnohem rychlejší vyhodnocení. === Struktura SQL databáze === #Struktura_SQL_datab.2BAOE-ze Jsou vytvořeny dvě tabulky: {{{ tabulka vertical 25 sloupců - primární klíč doc }}} {{{ tabulka vertical_M 4 sloupce mysql> explain vertical_M; +--------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+---------------------+------+-----+---------+-------+ | Doc | varchar(255) binary | | MUL | | | | M_Auth | varchar(255) | YES | | NULL | | | M_Date | date | YES | | NULL | | | M_Desc | varchar(255) | YES | | NULL | | +--------+---------------------+------+-----+---------+-------+ }}} Rozložení do dvou tabulek je nutné, protože atributy typu M_Auth se mohou pro jeden dokument opakovat. Takže dotazy na atributy typu M_Auth se pak musí provádět přes spojení tabulek: {{{ SELECT size FROM vertical NATURAL LEFT JOIN vertical_M; }}} === Založení SQL databáze v MySQL === #Zalo.2BAX4-en.2BAO0_SQL_datab.2BAOE-ze_v_MySQL Tento krok je samozřejmě v ideálním případě provést třeba jen jednou. V případě, že se databáze nějak pokazí (a u tak velké databáze, kdy každá operace trvá dlouho je mnohem pravděpodobnější, že dojde k nějakému nedokončení opearce a tím k nekonzistenci DB) je nejjednodušší ji smazat a založit znovu. Pro tento účel máme připravený skript: {{{ $ cat /nlp/corpora/vertical/BIN/sql-init CREATE DATABASE IF NOT EXISTS metainfo; use metainfo; DROP TABLE IF EXISTS vertical_M; CREATE TABLE vertical_M ( Doc varchar(255) binary NOT NULL, M_Auth varchar(255), M_Date date, M_Desc varchar(255), KEY (Doc) ); DROP TABLE IF EXISTS vertical; CREATE TABLE vertical ( Auth_N varchar(255) NOT NULL, Auth_S enum('m','f','n','t','X','Y','NA','MIX','ALT'), Avail varchar(255), D_Publ date DEFAULT '0000-00-00' NOT NULL, Date date, Doc varchar(255) binary NOT NULL, Doc_source varchar(255) NOT NULL, F_Publ date, Form enum('txb','enc','pop','cri','adv','X','Y','NA','MIX','ALT'), Lang enum('aa','ab','af','am','ar','as','ay','az','ba','be','bg','bh','bi','bn','bo','br','ca','co','cs','cy','da','de','dz','el','en','eo','es','et','eu','fa','fi','fj','fo','fr','fy','ga','gd','gl','gn','gu','ha','hi','hr','hu','hy','ia','ie','ik','in','is','it','iw','ja','ji','jw','ka','kk','kl','km','kn','ko','ks','ku','ky','la','ln','lo','lt','lv','mg','mi','mk','ml','mn','mo','mr','ms','mt','my','na','ne','nl','no','oc','om','or','pa','pl','ps','pt','qu','rm','rn','ro','ru','rw','sa','sd','sg','sh','si','sk','sl','sm','sn','so','sq','sr','ss','st','su','sv','sw','ta','te','tg','th','ti','tk','tl','tn','to','tr','ts','tt','tw','uk','ur','uz','vi','vo','wo','xh','yo','zh','zu','X','Y','NA','MIX','ALT'), Lemmat1 int(11) DEFAULT '0' NOT NULL, Lemmat2 int(11) DEFAULT '0' NOT NULL, Medium enum('b','nws','j','scr','net','oc','cdrom','X','Y','NA','MIX','ALT'), Position_offset int, Position_length int, S_Lang enum('aa','ab','af','am','ar','as','ay','az','ba','be','bg','bh','bi','bn','bo','br','ca','co','cs','cy','da','de','dz','el','en','eo','es','et','eu','fa','fi','fj','fo','fr','fy','ga','gd','gl','gn','gu','ha','hi','hr','hu','hy','ia','ie','ik','in','is','it','iw','ja','ji','jw','ka','kk','kl','km','kn','ko','ks','ku','ky','la','ln','lo','lt','lv','mg','mi','mk','ml','mn','mo','mr','ms','mt','my','na','ne','nl','no','oc','om','or','pa','pl','ps','pt','qu','rm','rn','ro','ru','rw','sa','sd','sg','sh','si','sk','sl','sm','sn','so','sq','sr','ss','st','su','sv','sw','ta','te','tg','th','ti','tk','tl','tn','to','tr','ts','tt','tw','uk','ur','uz','vi','vo','wo','xh','yo','zh','zu','X','Y','NA','MIX','ALT'), Signat varchar(8), Size int(11) DEFAULT '0' NOT NULL, T_Main enum('cnk_nove','eco','lit','sci1','sci2','sct','sport','X','Y','NA','MIX','ALT') DEFAULT 'sci1' NOT NULL, T_Orig varchar(255), T_Sub enum('arc','ars','ast','bot','bui','cin','com','ene','env','let','lif','man','mem','mer','min','nat','reg','scf','sec','tec','trv','zoo','eco','ind','adm','son','ver','nov','crm','sci','adv','ero','bio','tra','tab','fab','hum','jun','ess','chr','exc','inf','phy','geo','ggr','mat','che','bio','med','agr','eth','lin','lit','pol','art','soc','psy','edu','phi','mil','jur','his','rel','sct','amu','hou','tvf','the','mus','dra','spo','X','Y','NA','MIX','ALT') DEFAULT 'inf' NOT NULL, Title varchar(255) NOT NULL, Tran_N varchar(255), Tran_S enum('m','f','n','t','X','Y','NA','MIX','ALT'), Vertikal varchar(255), PRIMARY KEY (Doc), KEY D_Publ (D_Publ), KEY T_Sub (T_Sub), KEY T_Main (T_Main), KEY Lemmat1 (Lemmat1), KEY Lemmat2 (Lemmat2), KEY Size (Size) ); }}} Takže pro založení databáze zadáme: {{{ $ mysql -uroot -p mysql < /nlp/corpora/vertical/BIN/sql-init #bude to chtit heslo spravce databaze }}} Založení uživatele, který bude spravovat DB metainfo: {{{ $ mysql -uroot -p mysql -e "GRANT ALL ON metainfo.* TO mi_user@localhost IDENTIFIED BY 'heslo';" $ mysql -uroot -p mysql -e "GRANT ALL ON metainfo.* TO mi_user@% IDENTIFIED BY 'heslo';" }}} A aby uživatel mohl pracovat se soubory, tak mu nastavíme práva: {{{ $ mysql -uroot -p mysql -e "update user SET File_priv='Y' where User='mi_user'; " }}} A na závěr musíme dát reload, aby jsme změny uvedli v platnost: {{{ $ mysqlacces -uroot -p reload; }}} === Import dat do SQL databáze === #Import_dat_do_SQL_datab.2BAOE-ze Vzhledem k tomu, že současné vertikály obsahují více než milion dokumentů je i SQL databáze s více než milionem záznamů obrovská. Proto je třeba při práci používat co nejrychlejších prostředků. To nabízí program mysqlimport. Ten očekává, že data pro jednu tabulku (např. vertical) budou uložena ve stejnojmenném souboru, jeden řádek tabulky bude reprezentován jedním řádkem souboru, oddělovačem sloupců je znak tabulátor, hodnota NULL se reprezentuje pomocí sekvence 2 znaků "\N". Ukázka 2 řádků tabulky: {{{ $ head -2 /nlp/corpora/vertical/SQL_DATA/vertical Y Y \N 1998-01-01 \N S/J/1998/150/001 150 hori 1998-01-01 \N cs 99 88 j 101 5373 \N 6F59FE5D 695 cnk_nove \N sec Y \N \N cnk/150hori/150.vert Y Y \N 1998-01-01 \N S/J/1998/150/003 150 hori 1998-01-01 \N cs 94 69 j 7858 4463 \N 5E84F5FB 662 cnk_nove \N sec Y \N \N cnk/150hori/150.vert }}} Převod z metainformací do tohoto formátu provede program meta2sql, který jako svůj vstup očekává jméno souboru a vytvoří dva soubory s koncovkami .sql1 a .sql2. Takže použití: {{{ $ cd /nlp/corpora/vertical $ traverse_dir meta meta2sql $ traverse_dir sql1 cat > vertical $ traverse_dir sql2 cat > vertical_M }}} Import dat do databáze se pak provede takto: {{{ $ cd /nlp/corpora/vertical $ mysqlimport -umi_user -pheslo metainfo vertical $ mysqlimport -umi_user -pheslo metainfo vertical_M }}} === Použití SQL databáze pro vytvoření korpusu === #Pou.2BAX4-it.2BAO0_SQL_datab.2BAOE-ze_pro_vytvo.2BAVk-en.2BAO0_korpusu Tak jako v případě textové databáze použijeme program list2vert, kterému předáme na vstup seznam dokumentů ve formátu: {{{ Offset,Length:Doc:Vertikal }}} Tento formát vytvoříme vhodným dotazem, např. dotaz {{{ SELECT CONCAT(Position_offset,',',Position_length,':',Doc,':',Vertikal) from vertical where T_Sub='eco' AND Size BETWEEN 2000 AND 2010; +------------------------------------------------------------------+ | CONCAT(Position_offset,',',Position_length,':',Doc,':',Vertikal) | +------------------------------------------------------------------+ | 5231183,14467:S/NWS/1995/hnb5/1994:cnk/HN/hnb5.vert | | 4645,15025:S/NWS/1999/ln99086e/003:cnk/LN/1999/ln99086e.vert | +------------------------------------------------------------------+ 2 rows in set (0.07 sec) }}} vybral dokumenty, pro které je T_Sub='eco' a jejich velikost se pohybuje od 2000 do 2010 pozic. Výstup si uložíme do souboru nejlépe takto: {{{ $ mysql -umi_reader -pmr metainfo \ -e "SELECT CONCAT(Position_offset,',',Position_length,':',Doc,':',Vertikal) \ from vertical where T_Sub='eco' AND Size BETWEEN 2000 AND 2010;" \ > seznam $ list2vert < seznam | encode }}}