Version 2 (modified by 9 years ago) (diff) | ,
---|
Jak vytvořit korpus
Tento článek slouží jako průvodce při vytváření korpusu. Je určen pro studenty a další zájemce, kteří chtějí pořizovat a převádět data pro potřeby korpusů. Za prvé popisuje strukturu korpusů, s využitím odkazů na příslušné normy. Za druhé popisuje možnosti kontroly správnosti korpusových dat. A za třetí podává návod, jak vytvářet korpusy převodem z HTML stránek.
Úvod
Co jsou to korpusy
Obecně - počítačový korpus je rozsáhlý, vnitřně strukturovaný a ucelený soubor textů daného jazyka, elektronicky uložený a zpracovávaný. Práci s korpusovými daty zprostředkovává program nazývaný korpusový manažer.
Aby mohl být určitý text do korpusu zařazen, musí být připravena dvojice textových souborů - tzv. vertikální text (zkráceně vertikál) a metainformace. Vertikál obsahuje samotná korpusová data, metainformace obsahují doplňující údaje o těchto datech. V tomto textu bude množina takových dvojic souborů označována zjednodušeně jako korpus (viz dále).
Struktura korpusových dat
Jak jsou korpusy uloženy
Korpusy jsou uloženy jako textové soubory. Korpus je jednoznačně určen jménem adresáře. Všechny soubory, které končí .vert (vertikály) a .meta (metainformace) a které jsou obsaženy v tomto adresáři a všech jeho podadresářích, tvoří korpus.
Struktura vertikálů
Strukturu vertikálů popisuje norma pro vertikály Popis vertikálů .
Struktura metainformací
Strukturu metainformací popisuje norma pro metainformace Popis metainformací .
Vazby mezi vertikály a metainformacemi
- V každém adresáři či podadresáři si musejí co do počtu i do jmen (až na příponu) tyto odpovídat.
- Každý z dvojice (vertikál, metainformace) obsahuje dokumenty stejných jmen ve stejném pořadí. Příklad:
- mf-1999-05-17.vert obsahuje dokumenty "<doc mf/1999/05/17/1>" až "<doc mf/1999/05/17/159>"
- mf-1999-05-17.meta obsahuje dokumenty "Doc : mf/1999/05/17/1" až "Doc : mf/1999/05/17/159"
Nástroje pro kontrolu správnosti korpusových dat
Dají se rozdělit na tři skupiny:
- kontrola konzistence mezi vertikály a metainformacemi
- kontrola vertikálů
- kontrola metainformací
Všechny jsou dostupné po přidání modulu:
$ module add corpus
na strojích aurora (Linux), aisa (IRIX) a oreias (SunOS).
Pomocné programy
Většina programů pracuje se standardním vstupem a výstupem. To znamená, že kontrolní program nezná jméno souboru, jehož obsah mu byl přesměrován na jeho standardní vstup. Proto je tu program check_file
. Použití:
check_file [-l číslo -s -S] program file $ check_file -l 20 meta_check neco.meta
Jako argumenty mu dáme jméno kontrolního programu a souboru, který chceme zkontrolovat. Jeho výstup obsahuje jméno kontrolovaného souboru a výstup kontrolního programu. Volby:
- -l číslo ... výstup kontrolního programu se ořeže na 'číslo' řádek
- -s ... totéž co -l 0
- -S ... pokud kontrola byla bez chyby, potlačí všechen výstup
Další pomocný program je traverse_dir
, který je vystavěn na programu find
. Použití:
traverse_dir [-v] suffix program [argumenty pro program] $ traverse_dir vert check_file -S xml_check
Suffix je buď vert
nebo meta
. Program vyhledá všechny soubory s příponou suffix a provede volání specifikovaného programu s jeho argumenty a jako poslední argument přidá jméno nalezeného souboru. Takže v ukázkovém případu se volá check_file -S xml_check neco.vert
. Volba -v
provede navíc výpis těchto volání.
Kontrola konzistence mezi vertikály a metainformacemi
Kontroluje se, jestli si odpovídají soubory .vert a .meta:
$ v2m_files
Dále se kontrolují seznamy jmen dokumentů - program v2m_docs
. Kontrola jedné dvojice souborů .meta a .vert:
$ v2m_docs soubor.meta #Zadám jen jméno metainformací
Kontrola celého korpusu:
$ traverse_dir meta v2m_docs
Kontrola vertikálů a metainformací
K dispozici jsou tyto programy:
il2_check
Určeno pro: *.vert, *.meta. Kontroluje kódování češtiny. Ohlásí podezřelé znaky. Je nutno zvážit, zda se jedná o skutečnou chybu nebo ne.tags_check
Určeno pro: *.vert. Kontroluje, zda řádky, které vypadají jako značky, jsou ze seznamu povolených značek.pozice_check
Určeno pro: *.vert. Kontroluje, zda řádky, které nejsou značkami, jsou dále nedělitelné pomocí funkce Corpus::split().heuristic_check
Určeno pro: *.vert. Kontrola pozic, zda neobsahují řídící a značkovací řetězce originálního textu. Hledá HTML značky a příkazy LATEXu.xml_check
Určeno pro: *.vert. Kontrola struktury vertikálů.meta_check
Určeno pro: *.meta. Kontrola struktury metainformací.
Všechny tyto programy jsou filtry. Proto je používáme jedním z těchto tří způsobů:
$ xml_check < soubor.vert > zde_je_vystup 2>&1
nebo:
$ check_file xml_check soubor.vert > zde_je_vystup
nebo:
$ cd adresar_s_daty $ traverse_dir vert check_file xml_check > zde_je_vystup
Všechny kontroly se dají spustit pomocí dávky check_all
:
$ check_all > zde_je_vystup 2>&1
Jak číst výstupy kontrolních programů
v2m_files, v2m_docs
Oba programy používají při hlášení rozdílů v seznamech jmen (v2m_files
- jmen souborů av2m_docs
- jmen dokumentů) standardní programcomm
s parametrem-3
. Ten uvede rozdíly ve dvou tabulátorem odsazených sloupcích. Viz takéman comm
.
il2_check, tags_check, pozice_check, heuristic_check, meta_check
Tyto programy mají snadno čitelný výstup, a není tedy nutno jej zde dále komentovat.
xml_check
Programxml_check
je založen na volání xml-parserurxp
. Jen je proveden určitý preprocessing - viz kapitola Rozdíly mezi vertikálem a jeho DTD definicí
Výstup programu bude vyložen na několika příkladech:
VSTUP č.1: <?xml version="1.0"?> <!DOCTYPE vertical SYSTEM "/net/aisa/corpus/vertical.dtd"> <vertical> </vertical> VÝSTUP: Warning: Content model for vertical does not allow it to end here in unnamed entity at line 4 char 11 of <stdin> VYSVĚTLENÍ: Vertikál neobsahoval žádný dokument, ale párová značka <vertical> nesmí být prázdná. ---------- VSTUP č.2: (jen jeho relevantní část) <doc id="neco"> Ahoj <head> Jaroslav VÝSTUP: Warning: Content model for doc does not allow element z here in unnamed entity at line 5 char 3 of <stdin> VYSVĚTLENÍ: Po značce <doc> musí bezprostředně následovat npaříklad <head> nebo <p> a nikoli pozice (element z označuje pozici Ahoj). --------- VSTUP č.3: (jen jeho relevantní část) <p> <head> V zázemí </head> blabla </p> VÝSTUP: Content model for p does not allow element head here in unnamed entity at line 6 char 6 of <stdin> VYSVĚTLENÍ: V <p> nesmí být zanořen <head> --------- VSTUP č.4: (jen jeho relevantní část) <doc id="a"> <p> V <p> A </doc> VÝSTUP: Warning: Content model for p does not allow element p here in unnamed entity at line 7 char 3 of <stdin> Error: Mismatched end tag: expected </p>, got </doc> in unnamed entity at line 9 char 6 of <stdin> VYSVĚTLENÍ: Neuzavřené značky <p>. --------- VSTUP č.5: (jen jeho relevantní část) <p> <g/> konec VÝSTUP: Warning: Content model for p does not allow element g here in unnamed entity at line 6 char 3 of <stdin> VYSVĚTLENÍ: Značka <g/> zde nemůže být, protože musí být vždy z obou stran obklopena pozicemi, které spojuje a zde je nad ní nikoli pozice, ale značka <p>. Tato chyba nemůže vzniknout, pokud se použije na "rozsekání" textu funkce Corpus::split nebo program corus_split.
Převod HTML stránek na vertikální tvar
Pokud si jako zdroj zvolíme webovské HTML stránky, potom jsou zde k dispozici nástroje pro převod do vertikálu. Jsou založeny na perlovském modulu HTML::Parser (man HTML::Parser
) a na funkci Corpus::split.
HTML stránky obsahují kromě značek také ještě posloupnosti znaků zvané entity, například & nebo anebo °. Tyto entity je třeba převést na odpovídající znaky. K tomu je k dipsozici filtr nazvaný html
. Dokumenty jsou často v jiném kódování (1250), v tom případě je třeba použít filtr cstocs 1250 il2
a to až po aplikaci filtru html
(jinak by došlo k chybnému převodu entit typu °).
Pomocný program vert2xml
vznikl k překlenutí rozdílů mezi starší a novější definicí struktury vertikálu. Pracuje jako filtr, který přidá ke svému vstupu hlavičku vertikálu (první tři řádky), opraví tvar některých značek a přidá na konec řádek </vertical>. Programy dále popsané dávají výstup ve starším formátu, proto jako postprocessing je vhodné zařadit filtr vert2xml
.
Vzhledem k tomu, že struktura HTML dokumentů je celkem volná, pouhým překladem značek nedospějeme ke dobře utvořenému vertikálu. Proto jsou dále popsány prográmky na úpravu některých neduhů - provádějí párování, rušení nebo vkládání značek. Několik programů je spojeno do dávky tags_all
, kterou je možné použít jako poslední postprocessing.
Příklad 1. - nejjednodušší použití
Je implementováno v programu html2vert.1 . Program funguje jako filtr. Použití:
html < muj.html | html2vert.1 |vert2xml | tags_all > muj.vert
Výpis programu:
BEGIN {push @INC , #Do seznamu cest modulu pridej "/usr/local/lib/perl5/site_perl/5.005", #Cestu k modulu HTML::Parser "/packages/share/corpus/lib" #Cestu k modulu Corpus }; use Corpus; #Vyzada si balik Corpus require HTML::Parser; #Vyzada si balik HTML::Parser package Muj_Parser; #Odtud zacne balik Muj_Parser #Nastavuje dedicnost @ISA=qw(HTML::Parser); sub start {} #vola se, kdyz je rozpoznana nekoncova znacka, zatim nedela nic sub end {} #vola se, kdyz je rozpoznana koncova znacka, zatim nedela nic #Tato procedura se vola vzdy, kdyz je rozpozan nejaky text sub text { my($self, $text) = @_; #do $self, $text si ulozim parametry return unless $text; #pokud $text je prazdny, vrat se my $t=(Corpus::split($text)); #do $t uloz rozdeleny text print $t unless $t =~ /^$/; #tiskni $t, pokud neni prazdny } $p = Muj_Parser->new; #Vytvorim novy objekt tridy Muj_Parser $p->parse_file(\*STDIN); #Volam parsovani standardniho vstupu
Program převede entity, vypustí všechny HTML značky a text "rozseká" pomocí funkce Corpus::split na pozice. Proto jediná značka ve výstupu bude <g>.
Program funguje takto:
Metoda parse_file postupně zpracovává STDIN a vždy, když rozpozná nějakou značku, zavolá proceduru start, případně end, a tuto značku, převedenou na malá písmena a zbavenou atributů, předá jako druhý argument. Text mezi značkami je předán proceduře text.
Příklad 2. - přidání některých značek
Je k dispozici v souboru html2vert.2 . Pokud budeme chtít, aby se ve výsledném vertikálu objevily značky <doc>, resp. <p>, tehdy, když ve zdroji byly značky <HTML>, resp. <p>, změníme definici procedur start a end tak, aby tiskly značky, když se rozpoznají jejich HTML ekvivalenty. Navíc do značky <doc> se přidá jako atribut jméno, které je prvním argumentem programu. Použití :
html < muj.html | html2vert.2 blabla | vert2xml | tags_all > muj.vert
Změněné procedury:
sub start { my($self, $tag) = @_; if ($tag eq "html") {print "<doc $ARGV[0]>\n"}; if ($tag eq "p") {print "<p>\n"}; } sub end { my($self, $tag) = @_; if ($tag eq "html") {print "</doc>\n"}; }
Příklad 3. - pokročilejší značení
Je k dispozici v souboru html2vert.3 . Testovací soubor lidových novin je v souboru ln-1999-11-10.all? . Použití:
html < ln-1999-11-10.all | html2vert.3 l n | vert2xml | tags_all > muj.vert
Předpokládejme strukturu HTML dokumentu reprezentovanou těmito zanořenými značkami (text byl vypuštěn - viz html_pp):
<HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> </SCRIPT> </HEAD> <BODY> <P ALIGN="center"> <DIV CLASS="vlclanek"> <P ALIGN="right"> <B> <I> </I> </B> </DIV> <HR ALIGN="center" NOSHADE SIZE=2 WIDTH="30%"> <DIV CLASS="vlclanek"> <P ALIGN="right"> <B> <I> </I> </B> </DIV> </BODY> </HTML>
Toto je zjednodušená struktura HTML souborů na serveru www.trafika.cz (dnes již na noviny.trafika.cz deníky Lidové noviny, Mladá fronta Dnes a Právo nenajdete). Jeden soubor bude převeden na vertikál s několika dokumenty. Jeden dokument odpovídá kontejneru značek <div> a </div>. Proto do vertikálu pustíme jen text z těchto oblastí. Navíc víme, že text zanořený ve značkách <b> a <i> je tučnou kurzívou vysázené jméno autora, které chceme mít ve vertikálu mezi značkami <sign> a </sign>. Dále budeme jednotlivé dokumenty číslovat, dvanáctý dokument Lidových novin bude <doc ln/12>.
Předefinujeme procedury start, end a text:
sub start { my($self, $tag) = @_; if ($tag eq "div") {$self->{"poradi"}++; #zvysim si pocitadlo print "<doc $ARGV[0]/$self->{poradi}>\n"; #tisknu <doc jm/cislo> $self->{"div"}=1; #indikuju oblast div } elsif ($tag eq "p") {print "<p>\n" if $self->{"div"}; } #tisknu <p>, pokud je div elsif ($tag eq "b") {$self->{"b"}=1} #indikuju b elsif ($tag eq "i") {$self->{"i"}=1; #indikuju i print "<sign>\n" if $self->{"b"}; #tisknu <sign>, pokud je b } } sub end { my($self, $tag) = @_; if ($tag eq "b") {$self->{"b"} =0} #konci b elsif ($tag eq "i") {$self->{"i"} =0; #konci i print "</sign>\n" if $self->{"b"}; #tisknu </sign>, je-li b } elsif ($tag eq "div") {$self->{"div"} =0; #konci div print "</doc>\n"; #tisknu </doc> } } sub text { my($self, $text) = @_; #do $self, $text si ulozim parametry return unless $self->{"div"}; #Pokud neni v mezich div, tak netiskni return unless $text; #pokud $text je prazdny, vrat se my $t = (Corpus::split($text)); #do $t uloz rozdeleny text print $t unless $t =~ /^$/; #tiskni $t, pokud neni prazdny }
Objekt $p si nese informaci, ve kterém zanoření zrovna je, a to pomocí ukazatele $self na hash. Například $self->{"div"} =1;
signalizuje, že jsme vstoupili do div kontejneru.
Příklad č.4 - program používaný pro převod periodik z www.trafika.cz (dnes noviny.trafika.cz)
Je k dispozici bez dalších komentářů v souboru html2corpora .
Pomocný nástroj pro analýzu struktury HTML - html_pp (pp - pretty printer)
Program slouží k tomu, aby bylo snadnější nahlédnout strukturu konkrétního HTML dokumentu. Ponechá pouze značky a odsadí je podle zanoření pomocí tabulátorů. Struktura v předchozím příkladu byla vygenerována právě pomocí html_pp. Použití:
cat ln-1999-11-10.all | html_pp
K běhu potřebuje perlovský modul HTML::TreeBuilder?.
Programy na opravu častých chyb
Pro vertikály
Všechny jsou dostupné po přidání modulu:
$ module add corpus
na strojích aurora (Linux), aisa (IRIX) a oreias (SunOS). Jsou to:
- tags_pair_doc
Páruje značku <doc>. - tags_rm_bad_glue
Maže značku <g/>, pokud není "obalena" pozicemi. - tags_rm_multi
Maže opakující se značky (nechá jen první výskyt z posloupnosti). - tags_pair_item
Páruje značku <item>. - tags_rm_empty
Maže počáteční a koncovou značku, pokud jsou bezprostředně za sebou. - tags_insert_p
Vkládá značku <p> před pozici tam, kde by tato pozice byla zahnízděná přímo v kontejneru značky <doc>. - tags_pair_p
Páruje značku <p>. - tags_all
Dávka, která kombinuje některé výše uvedené programy.
Použití: všechny programy pracují jako filtry, takže se dají přidat na konec kolony, která produkuje vertikál. Na už vygenerovaný vertikál je vhodné je spustit pomocí pomocného programu apply_filter:
úprava jednoho souboru:
$ apply_filter tags_all vertikal.vert
úprava všech vertikálů v korpusu:
$ cd korpus $ traverse_dir vert apply_filter tags_all
Pro metainformace
atrib_insert_povinne
- program, který doplní neuvedené povinné atributy a nastaví jim hodnotu Y (nezjistitelné). Je to také filtr, takže použití vypadá takto:
úprava jednoho souboru:
$ apply_filter atrib_insert_povinne vertikal.meta
úprava všech metainformací v korpusu:
$ cd korpus $ traverse_dir meta apply_filter atrib_insert_povinne
Vložení dalších atributů zajišťují programy:
- atrib_insert_offset
- atrib_insert_size
- atrib_insert_lemmat
- atrib_insert_signat (běží zatím je na auroře)
Všechny programy očekávají jako svůj jediný argument jméno souboru s metainformacemi.
Použití: Úprava jednoho souboru:
$ atrib_insert_size vertikal.meta
úprava všech metainformací v korpusu:
$ cd korpus $ traverse_dir meta atrib_insert_size
Doplňkové programy
- vert2xml
Program vhodný pro transformaci starého formátu vertikálů na nový. Filtr, který vkládá tyto 3 řádky před svůj vstup:<?xml version="1.0"?> <!DOCTYPE vertical SYSTEM "/net/aisa/corpus/vertical.dtd"> <vertical>
a tento za svůj vstup:
</vertical>
a provádí změnu u značek <doc> , <pre> a <g>.
- cisti_corpus
Najde soubory, které nekončí .vert nebo .meta (lze je potom smazat). Použití:$ cd korpus $ cisti_corpus #vypis $ cisti_corpus | xargs rm -f #smazani
- docs2meta
Přejmenuje .docs soubory na .meta (docs - starší, již nepoužívaná koncovka pro metainformace). Použití:
$ cd korpus $ docs2meta
- corpus_size
Zjistí velikost korpusu. Na výstup dá počet pozic korpusu.
$ cd korpus $ corpus_size