====== 5. lekce: Dotazovací jazyk CQL. Pokročilé dotazy. ====== V páté lekci se zaměříme na klíčovou dovednost, která teprve umožní plně využívat všechny možnosti nabízené naším [[kontext|rozhraním KonText]]. Jde o ovládnutí dotazovacího jazyka CQL, který úzce souvisí se zvládnutím tzv. [[pojmy:regularni_vyrazy|regulárních výrazů]], s nimiž jsme se seznámili v předešlé lekci. Korpusový [[pojmy:dotazovaci_jazyk|dotazovací jazyk]] (CQL, Corpus Query Language) je formální jazyk, který slouží k vyhledávání v korpusu. Budete-li chtít formulovat dotaz přímo v CQL, je nutné v KonTextu nad vyhledávacím okénkem aktivovat přepínač **Pokročilý dotaz**. CQL slouží jak k zadávání velmi složitých dotazů (např. vyhledej všechny výskyty adjektiv v superlativu v jiném pádě než nominativ, po nichž v textu nenásleduje substantivum ani interpunkce), tak i k zadávání dotazů jednoduchých (např. najdi výskyty lemmatu //oko//). Právě v možnosti vyhledávat pomocí velmi sofistikovaných kritérií tkví základní kvalitativní rozdíl mezi korpusovým vyhledávačem a běžným fulltextovým hledáním, které využíváme např. při práci s Googlem. ===== Základní formát CQL dotazu ===== Dotazy v CQL mají specifický formát. Základem je zápis pro jednu [[pojmy:pozice|textovou pozici]], který má následující formu: **''[atribut=%%"hodnota"%%]''** kde atributem může být buď [[kurz:zobrazeni_dotazu#word_lemma_tag|lemma, slovní tvar (čili word) a tag]], případně jakékoli jiné [[pojmy:atributy_pozicni|poziční atributy]], např. pos (part-of-speech, slovní druh) nebo [[seznamy:afun|afun]] (syntaktická funkce dané pozice, např. v [[cnk:syn2015|SYN2015]]). Následující tabulka přehledně uvádí příklady dotazů, v nichž se užívají různé atributy: ^ atribut ^ grafická podoba dotazu ^ výsledek ^ | **lemma** | ''[lemma=%%"kočka"%%]'' | všechny výskyty všech slovních tvarů lemmatu //kočka// | | **slovní tvar** | ''[word=%%"uviděly"%%]'' | všechny výskyty slovního tvaru //uviděly// | | **tag** | ''[tag=%%"D.*"%%]'' | všechny výskyty všech adverbií (viz [[seznamy:tagy|morfologické značky]]) | | **slovní druh** | ''[pos=%%"D"%%]'' | všechny výskyty všech adverbií (viz [[seznamy:tagy|morfologické značky]]) | | **pád** | ''[case=%%"7"%%]'' | všechny výskyty slov v instrumentálu (viz [[seznamy:tagy|morfologické značky]]) | Hodnota, která je v rámci CQL uvedena v uvozovkách, se zapisuje a vyhodnocuje jako regulární výraz, což je dobře vidět na použití sekvence ''.*'' v případě dotazu na tag. ==== Hlavní rysy CQL ==== * Jedné [[pojmy:pozice|pozici]] v korpusu odpovídá jeden výraz ve tvaru ''[atribut="hodnota"]'' v hranatých závorkách; pokud nechceme specifikovat ani atribut, ani jeho hodnotu, můžeme nechat hranaté závorky prázdné ''[]'' a dotaz bude odpovídat jedné libovolné pozici * Na jedné pozici můžeme za pomoci [[kurz:pokrocile_dotazy#kombinace_podminek_v_ramci_jedne_pozice|logických operátorů]] zkombinovat více atributů: např. ''[word="kolem" & pos="N"]'' (vyhledá všechny výskyty tvaru substantiva //kolo//, a nikoli výskyty předložky //kolem//). * Pomocí CQL lze vyhledat i libovolné množství textových pozic následujících za sebou, každá z nich bude mít vlastní výraz v hranatých závorkách, např. ''[lemma="mít"][lemma="červený"][lemma="tvář"]'' (výsledkem jsou varianty víceslovného výrazu //měla červené tváře//). ===== Logické operátory: Kombinace podmínek v rámci jedné pozice ===== V rámci jedné pozice lze kombinovat nejrůznější podmínky, je tedy možné specifikovat hodnotu dvou i více atributů: Hledáme například předložku //s//, ale požadujeme jen slabičné tvary //se// -- pokud bude CQL dotaz mít formu ''[word="se"]'', vyhledají se i tvary zájmena //se//. Proto je třeba zadat dotaz např. v podobě: ''%%[lemma="s" & word="se"]%%''. Chceme-li kombinovat podmínky, musíme se nejprve seznámit s tzv. **logickými operátory**: ^ název ^ znak ^ co zastupuje ^ další informace ^ příklad dotazu ^ popis dotazu ^ | **ampersand** | ''&'' | a zároveň (AND) | platí všechny podmínky zároveň | ''[lemma="jak" & pos="N"]'' | vyhledá výskyty substantiva //[[https://cs.wikipedia.org/wiki/Jak_domác%C3%AD|jak]]// (zástupce turů) | | **vykřičník** | ''!'' | negace (NOT) | neguje následující výraz | ''%%[lemma="stát" & pos!="N"]%%'' | vyhledá výskyty **ne**substantivního (tedy slovesného) lemmatu //stát// | | **svislá čára** | ''|'' | nebo (OR) | alespoň jedna možnost platí | ''[lemma="modrozelený" | lemma="zelenomodrý"]'' | vyhledá výskyty lemmat //modrozelený// a //zelenomodrý// | ===== Posloupnost pozic ===== Jedny hranaté závorky s atributem a jeho hodnotou odpovídají v CQL jedné pozici v textu. Pokud za sebou v CQL zapíšeme dvoje hranaté závorky za sebou, vyhledají se (samozřejmě podle zadaných podmínek) dvě pozice v textu bezprostředně následující za sebou. Můžeme například vyhledat spojení //zelené jablko//, a to prostřednictvím dotazu ''[word="zelené"][word="jablko"]''. Podobně můžeme vyhledat i větší množství slov následujících za sebou v textu, např. dotaz ''[lemma="od"][lemma="ráno"][lemma="do"][lemma="večer"]'' v korpusu [[cnk:syn2020|SYN2020]] vyhledá [[https://www.korpus.cz/kontext/view?viewmode=kwic&pagesize=50&attrs=word&attrs=verbtag&attr_vmode=visible-kwic&base_viewattr=word&refs=%3Ddoc.title&refs=%3Ddoc.txtype&q=~jG2yEO4SqMks&cutoff=0|415 výskytů]] fráze //od/Od rána do večera//, dotaz ''[lemma="rozhodnout"][lemma="se"][lemma=","][lemma="že"]'' [[https://www.korpus.cz/kontext/view?viewmode=kwic&pagesize=50&attrs=word&attrs=verbtag&attr_vmode=visible-kwic&base_viewattr=word&refs=%3Ddoc.title&refs=%3Ddoc.txtype&q=~Nw2kemaeAoUY&cutoff=0|přes 1100 výskytů]] spojení slov //rozhodnout se, že// v různých tvarech. Atributy v jednotlivých pozicích se samozřejmě můžou lišit, např. dotaz ''[pos="V"][word=","][lemma="že"]'' vyhledá slovesa, která předcházejí spojce //že//. Nyní si ukážeme počítání pozic **včetně interpunkce** (i ta tvoří v korpusech samostatné pozice) ještě na konkrétním dotazu, v němž jde o publicistické užití a aktualizace přísloví //vlk se nažral a koza zůstala celá//: * Vyberte korpus [[cnk:syn2009pub|SYN2009PUB]], přepněte na pokročilý dotaz * Zadejte dotaz: ''[lemma="vlk"][]{1,5}[lemma="koza"][]{1,3}[lemma="celý"]''\\ Pro konstrukci dotazu jsme použili jednak CQL dotazy se specifikovanou hodnotou, tak libovolné pozice ''[]'', které se opakují (intervalový zápis pomocí složených závorek ''{1,5}'') * Z 287 výsledků vyberte aktualizace daného frazému, např. //Kavčí hory dumají, kterak vlka státotvorné povinnosti nakrmit, aby koza divákova zájmu zůstala celá.// Jak může vypadat podrobný rozpis pozic v jedné realizaci dotazu ''[lemma="vlk"][]{1,5}[lemma="koza"][]{1,3}[lemma="celý"]''shrnuje následující tabulka. Číselný údaj odkazující k jednotlivým pozicím se může měnit v závislosti na tom, zda pozici nula přiřadíme pravému či levému okraji KWICu. ^ slovní tvar | kterak | vlka | státotvorné | povinnosti | nakrmit | , | aby | koza | divákova | zájmu | zůstala | celá | . | ^ pozice od začátku (levé strany) KWICu | 1L | 0 | 1P | 2P | 3P | 4P | 5P | 6P | 7P | 8P | 9P | 10P | 11P | ^ pozice od začátku (pravé strany) KWICu | 11L | 10L | 9L | 8L | 7L | 6L | 5L | 4L | 3L | 2L | 1L | 0 | 1P | ^ | levý kontext | KWIC ||||||||||| pravý kontext | KWIC je vše, co je v dotazu specifikováno, tedy od levé strany, kde je lemma //vlk//, až po stranu pravou, kde je lemma //celý//. Také proto se celá struktura zobrazí červeně. Vidíme, že //vlka// a //kozu// dělí přesně 5 pozic (což je maximum umožněné naším dotazem), a stejně tak byl maximální rozptyl uplatněn i mezi lemmaty //koza// a //celý//. A abyste nemohli říkat: "Vlk slibů, že tento kurz bude podrobný, se nažral, a koza zatajování znalostí zůstala celá", zkusme si společně ještě rozšířit počet pozic v dotazu -- otázkou je, jestli už náhodou nedostaneme takové doklady, které nebudou obměnou zkoumaného přísloví: ''[lemma="vlk"][]{1,7}[lemma="koza"][]{1,5}[lemma="celý"]'' A podíváme se na výsledky: je jich [[https://kontext.korpus.cz/view?q=~X0mNKAcd&attr_allpos=kw&attrs=word&corpname=syn2009pub&ctxattrs=word&pagesize=30&refs=%3Dopus.nazev&structs=p%2Cg%2Cerr%2Ccorr&viewmode=kwic&|298]]. Jak si zobrazit těch 11 nových? Pro část z nich (7) stačí specifikovat dotaz takto: ''([lemma="vlk"][]{6,7}[lemma="koza"][]{1,5}[lemma="celý"])|([lemma="vlk"][]{1,7}[lemma="koza"][]{4,5}[lemma="celý"])'' a hned vidíme, že mezi oněmi novými možnostmi přibyl např. tento doklad: | jak | nakrmit | vlka | ( | liberalizovaný | trh | ) | a | zachovat | kozu | ( | soudržnou | společnost | ) | celou | | 2L | 1L | vlka | 1. | 2. | 3. | 4. | 5. | 6. | kozu | 1. | 2. | 3. | 4. | celou | Další možností je počet pozic nijak přesně nespecifikovat: ''[lemma="vlk"][]+[lemma="koza"][]+[lemma="celý"]''. Výsledků je 383, některé jsou pro náš výzkum zcela nepodstatné (//vlky nechali postřílet //[...]// pastevci se zase strachují o své ovce a kozy. "Komplex Červené Karkulky je evidentní – lidé z vlků mají strach. Přitom jsou v celé// [...]//"//), jiné se výrazně liší od výchozího výrazu, ale můžeme se rozhodnout je do výzkumu zahrnout. ===== Velikost písmen v CQL ===== Pro práci s velikostí písmen slouží v CQL specifická sekvence znaků ''(?i)''. Pokud ji použijeme hned za uvozovkami, bude celý dotaz vyhodnocen jako [[pojmy:case-sensitive|case-insensitive]], tedy bez ohledu na velikost písmen. ^ Dotaz ^ Co mu odpovídá ^ | ''%%[word="pes"]%%'' | //pes// | | ''%%[word="(?i)pes"]%%'' | //pes, Pes, peS, PES// | | ''%%[word="(?i)PES"]%%'' | //pes, Pes, peS, PES// | Ke stejným výsledkům bychom dospěli i za použití regulárních výrazů, např. dotaz ''%%[word="[Hh][Rr][Aa][Dd]"]%%'' je ekvivalentní s ''%%[word="(?i)hrad"]%%''. Zápis ''(?i)'' je ovšem zřetelně ekonomičtější. ===== Hledání v rámci jedné věty ===== V [[zobrazeni_dotazu|druhé lekci]] jsme se naučili, jak v konkordanci zobrazit [[pojmy:atributy_strukturni|strukturní značky]]. Pokud povolíme zobrazování značek označujících začátky a konce vět (''[[pojmy:s|]]'' a ''''), můžeme si snadno ověřit, jestli funguje hledání slov vyskytujících se na začátku nebo na konci vět: ^ značka ^ význam ^ výzkumná otázka ^ příklad dotazu ^ výsledek pro SYN2020 ^ | '''' | začátek věty | Vyskytují se věty začínající interpunkcí? | '' [tag= "Z.*"]'' | [[https://www.korpus.cz/kontext/view?maincorp=syn2020&viewmode=kwic&pagesize=40&attrs=word%2Clemma%2Ctag%2Cverbtag&attr_vmode=mouseover&base_viewattr=word&structs=s&refs=%3Ddoc.title&q=~9OWOMGQUogY8|Převažují přímé řeči]] | | '''' | konec věty | Jaké typy vět končí sekvencí tří interpunkčních pozic? | ''%%[pos="Z"]{3}%% '' | [[https://www.korpus.cz/kontext/view?maincorp=syn2020&viewmode=kwic&pagesize=40&attrs=word%2Clemma%2Ctag%2Cverbtag&attr_vmode=mouseover&base_viewattr=word&structs=s&refs=%3Ddoc.title&q=~TCCwUquwAukE|Různé kombinace interpunkčních znamínek]] | Chceme-li hledat v rámci jedné věty, máme dvě možnosti. Buď položíme dotaz pomocí ''[[pojmy:within|within]]'' ("v rámci, uvnitř"), nebo za pomoci výrazu ''[[pojmy:containing|containing]]'' ("obsahuje"). Oba příkazy umožňují využívat informace ze strukturních atributů v rámci CQL dotazu a mají následující obecnou podobu: ''DOTAZ within STRUKTURA'' ''STRUKTURA containing DOTAZ'' V rámci této lekce je budeme využívat pouze k hledání v rámci věty, jejich aplikace je ale širší a další možnosti si ukážeme v lekci o [[kurz:subkorpusy|subkorpusech]]. Nenechte se splést tím, že konec věty '''' má velmi podobnou značku jako její obsah ''''. ^ příkaz ^ výzkumná otázka ^ příklad dotazu ^ výsledek pro SYN2015 ^ | ''within '' | Jaké věty obsahují zároveň citoslovce a slovesa (v libovolném pořadí)? | ''[tag=%%"I.*"][]*[tag="V.*"]|[tag="V.*"][]*[tag="I.*"%%] within '' | Např.: //Hele, já vím, jaký to je.// nebo //Sakra, někdo tam je!// | | '' containing'' | Jaké věty obsahují posloupnost čtyř substantiv? | '' containing %%[tag="N.*"]%%{4}'' | Např.: //Oběžník vyvolá v Oddělení verifikace faktů pobavení.// | Rozdíl mezi příkazy ''within'' a ''containing'' je pouze v podobě [[pojmy:kwic|KWICu]]. Vyhodnocení dotazu s příkazem ''within'' označí za KWIC pouze specifikovanou sekvenci (např. sloveso, citoslovce a vše mezi nimi), kdežto dotaz s příkazem ''containing'' označí za KWIC celou strukturu (v našem případě větu), která odpovídá specifikované podmínce. V korpusu SYN2009PUB zadejte dotaz ''%%[lemma="vlk"][]+[lemma="koza"][]+[lemma="celý"]%% within '' a porovnejte přesnost vyhledávání s pečlivě specifikovanými počty pozic. Výskytů je oproti předchozím dotazům o něco více, [[https://kontext.korpus.cz/view?q=~HBFbCLdp&attr_allpos=kw&attrs=word&corpname=syn2009pub&ctxattrs=word&pagesize=30&refs=%3Dopus.nazev&structs=p%2Cg%2Cerr%2Ccorr&viewmode=kwic&|celkem 312]] V těch nových figuruje např. věta //Vlk by měl předstírat, že žere, a koza rozhodně musí zůstat celá.// Mezi klíčovými slovy //vlk// a //koza// je, včetně samostatně počítané interpunkce, dohromady 8 pozic, ve větě //%%...%% uzná sice obžalované vinnými (takže vlk se nažere), ale zároveň poukáže na to, že dosud nebyli trestáni a žili řádným občanským životem (koza zůstane celá) -- takže mohou domů.// dokonce 20. Všechny nově nalezené případy jsou aktualizacemi námi hledaného frazému, v tomto případě se tudíž jako nejpřesnější jeví použití podmínky within. ==== Automaticky vložená podmínka within ==== Rozhraní KonText uživatelům umožňuje vložit do CQL dotazu formulář podmínky pomocí klikatelné nabídky. V rámci jedné věty lze díky tomu vyhledávat i pomocí automaticky vložené podmínky ''within '' (lze interpretovat takto: hledej v rámci jedné //libovolné// věty). [{{:kurz:vetybezsloves.png?direct&500|Within vkládané přímo v rozhraní KonText }}] ===== Shoda (a neshoda) atributů ===== V CQL lze využít také dotaz na shodu či neshodu atributů dvou nebo více tokenů; jejich hodnoty přitom nemusejí být jinak stanoveny. Je však nejprve potřeba označit pozice, u kterých chceme shodu testovat, a to uvedením čísla a **dvojtečky** v dotazu před hranatou závorku. Například dotazem '' %%1:[pos="N"] [word="a"] 2:[pos="N"]%% '' hledáme sekvenci třÍ tokenů, z nichž první je substantivum označené jako 1, následuje slovní tvar //a// a po něm další substantivum označené jako 2. Shodu pak testujeme jako součást tzv. globální podmínky uvedené za znakem **&**, která je vždy až na konci celého dotazu. Samotný test shody se skládá z číselného odkazu na označenou pozici, **tečky** a názvu atributu, který se má shodovat, např. takto: '' %%1:[pos="N"] [word="a"] 2:[pos="N"] & 1.lemma = 2.lemma%% '' najde sekvenci substantivum, slovní tvar //a// a substantivum, přičemž lemmata obou substantiv jsou shodná. Chceme-li najít po sobě následující adjektivum a substantivum, které se shodují v pádě, zadáme dotaz:\\ '' %%1:[pos="A"] 2:[pos="N"] & 1.case = 2.case%% '' Analogicky lze testovat neshodu, jen místo rovnítka %%(=)%% použijeme vykřičník a rovnítko %%(!=)%%, například takto:\\ '' %%1:[pos="N"] [word="a"] 2:[pos="N"] & 1.case != 2.case%% '' (dotaz najde dvě substantiva oddělená slovem //a//, která se **ne**shodují v pádě). Podmínky lze také kombinovat, tj. uvést jich více oddělených znakem &:\\ '' %%1:[pos="N"] 2:[pos="A"] 3:[pos="N"] & 1.case = 2.case & 2.case != 3.case%% '' (najde sekvenci substantivum - adjektivum - substantivum, ve které se adjektivum shoduje v pádě s prvním substantivem, ale ne s druhým). Podmínky lze aplikovat pouze na celé atributy, ne na jejich části. Lze tak ověřovat shodu či neshodu celých slovních tvarů, lemmat nebo morfologických značek, ne však už například shodu v rodě nebo čísle (nemají-li samostatný atribut). ===== Vyzkoušejte si na závěr ===== Pravda, tato lekce byla poněkud náročná, doufejme však, že platí //těžko na cvičišti kurzu, lehko na bojišti praxe//. Nebo se nic podobného neříká? * Zkuste zformulovat dotaz, jímž ověříte ne/existující aktualizace přísloví //těžko na cvičišti, lehko na bojišti// v korpusech [[cnk:syn2020|SYN2020]] a [[cnk:syn2013pub|SYN2013PUB]]. * A z jiného soudku: Nadávek odvozených od německého //Herr Gott// je nemálo (např. //hergot//, //herdek//, //hernajs// a jistě vymyslíte další). Vyhledejte co nejvíc takovýchto odvozenin v korpusu [[cnk:oral2013|ORAL2013]] a zjistěte, zda se jejich užití liší podle regionů. Řešení naleznete opět na [[reseni_ukolu#lekce_5|zvláštní stránce]]. V [[hledani_kolokaci|následující lekci]], v pořadí již šesté, zaměříme svou pozornost na kolokace, tedy ustálená slovní spojení. Zároveň si v ní představíme zbylé dva příkazy CQL, o kterých jsme se v této sekci nestihli zmínit. ---- [[manualy:kontext:index|Manuál rozhraní KonText]] • [[cnk:uvod|Korpusy ČNK]] • [[zaciname|Jak začít pracovat s ČNK]] • [[pojmy:prehled_pojmu|Přehled pojmů korpusové lingvistiky]] • [[uvod#zaklady_prace_s_korpusem_v_7_lekcich|Základy práce s korpusem v 7 lekcích]] • [[prvni_dotaz|1. lekce]] • [[zobrazeni_dotazu|2. lekce]] • [[vyhodnoceni_dotazu|3. lekce]] • [[regularni_vyrazy|4. lekce]] • [[kurz:hledani_kolokaci|6. lekce]] • [[pojmy:regularni_vyrazy|Regulární výrazy]]