Closed stranak closed 2 years ago
Některé výstupy OCR jsou momentálně ve fromátu prostého textu, některé jsou ve formátu ALTO.
V případě jednotného postupu by bylo možné i prostý text nejprve převésto do TEI (byť bez vazby na obrazovou předlohu) a následně TEI předat na jazykovou analýzu.
Problém s ALTO bývá, že za jeden token považuje slovo + interpunkci (viz např. <w xml:id="e108" facs="#f108">zapsati,</w>
), přičemž pro jazykovou analýzu jde o tokeny 2. Vznikne tak nesoulad v počtu "tokenů", který se bude muset vyřešit (nejspíš restrukturalizací TEI při zanášení výsledků jazykové analýzy).
Dobrá poznámka a docela problém, pokud bychom chtěli jak udělat správnou tokenizaci (tedy oddělit interpunkci od slov), tak zachovat odkazy na koordináty tokenu na stránce. Možná by ale stačilo jednoduché řešení, jako třeba ALTO "token" zapsati,
rozdělit na dva v TEI a oba mohou odkazovat na stejné koordináty.
Pokud by se tedy použilo TEI s elementy facs
jako v tomto převodu z ALTO
...
<tei:zone type="String" xml:id="f446" ulx="1803" uly="1213" lrx="1982" lry="1255"/>
...
<w xml:id="e446" facs="#f446">pokladně,</w>
...
tak by se <w xml:id="e446" facs="#f446">pokladně,</w>
mohl rozdělit na 2 elementy <w>
, které by ale oba odkazovaly na facs="#f446"
.
Na poslednej schôdzke 15.1 sme sa teda zhodli na tom, že vstupom bude stále ALTO formát, takže na toto sa teda budeme spoliehať. Je otázne, ako by mal vyzerať vstup do TEI Converteru, aby z neho bol converter schopný vyskladať TEI formát. Akým spôsobom mu budú predávané dáta + metadáta, aby vedel, ako ich poskladať do TEI?
Mne príde ako veľmi príjemné riešenie posielanie práve ukladanej stromovej štruktúry do vstupu TEI Converteru. Stromová štruktúra je veľmi prirodzená pre prevod do XML formátu a bolo by jednoznačné, ako má výsledné XML (TEI) vyzerať. Preto by som navrhoval nasledovný flow:
ALTO -> vybudovanie základného stromu z ALTO metadát -> obohatenie stromu UdPipeom -> obohatenie stromu NameTagom -> prevod stromu do TEI
Keďže by sme metadáta ukladali ako strom, mohli by sme tento strom v hociktorom kroku poslať do TEI converteru a pracoval by s ním stále rovnakým spôsobom, a zároveň by takmer ani nezáležalo, ako ten strom vyzerá, mohli by sme ho ľubovoľne obohatiť a TEI Converter by s ním stále pracoval rovnako, ideálne by nebolo nutné robiť žiadne prográmatorské zásahy do TEI Converteru pri novom type obohatenia.
Problém s tokenizáciou v ALTO by sa mohol riešiť v prvom kroku - pri budovaní stromu. Ak by sa detekovalo, že ide o slovo ktoré je potrebné rozdeliť na dve tokeny, vytvorili by sa dva listy pre daný token s rovnakými atribútmi prevzanými z ALTO(pozície). Takisto by sme tu mohli riešiť rozdelenie slova - ak sa detekuje, že ide o rozdelené slovo na dva riadky, ako Content
pre daný list by sa mohlo uložiť celé slovo. Tu je otázka, či nebude problém pri prevode do TEI, že by sa tieto slový vyskytovali duplikovane(celé slovo z predchádzajúcej strany + celé slovo z nasledujúcej strany), no myslím si, že aj toto by sme mohli nejakým spôsobom pomerne jednoducho vyriešiť.
Zaujímalo by ma ešte, či toto je jediný prípad kedy sa tokenizácia z ALTO nezhoduje so správnou tokenizáciou pri jazykovej analýze. Momentálne ma napadá napríklad tokenizácia pri slovách spojených spojovníkom (čierno-biely), alebo bodka pri skracovaní slov (napr. napr.
).
Zaujímalo by ma ešte, či toto je jediný prípad kedy sa tokenizácia z ALTO nezhoduje so správnou tokenizáciou pri jazykovej analýze. Momentálne ma napadá napríklad tokenizácia pri slovách spojených spojovníkom (čierno-biely), alebo bodka pri skracovaní slov (napr. napr.).
Jsou i další případy a jsou různé v různých jazycích. Za robustnější řešení považuji nezkoušet tokenizaci vylepšit ručně, tokeny pospojovat do řetězce a nechat tokenizaci udělat UDPipe. Čili bych z ALTO vzal jen informaci o spojení rozděleného tokenu, pak nechal UDPipe udělat tokenizaci a tu použil pro TEI a namapoval na původní tokeny ALTO. To mapování bude trošku těžší, ale bude to robustnější workflow. Hlavní je, že výsledná tokenizace bude správně pro jazykovou analýzu (která by se měla pustit asi rovnou zároveň).
Prosím ještě pamatujte na rozdělená slova na konci řádku. Pokud je to v rámci jedné stránky, tak nověji dělané OCR už obsahuje korektně otagované dělení slov. U těch starších to může vypadat i takto (slovo "povídá"):
<String CONTENT="poví" HEIGHT="63" WIDTH="116" VPOS="1031" HPOS="1834"/>
<SP WIDTH="20" VPOS="1048" HPOS="533"/>
<SP WIDTH="24" VPOS="1031" HPOS="728"/>
<SP WIDTH="24" VPOS="1068" HPOS="949"/>
<SP WIDTH="23" VPOS="1039" HPOS="1136"/>
<SP WIDTH="19" VPOS="1029" HPOS="1211"/>
<SP WIDTH="19" VPOS="1046" HPOS="1366"/>
<SP WIDTH="20" VPOS="1030" HPOS="1510"/>
<SP WIDTH="22" VPOS="1037" HPOS="1811"/>
<HYP CONTENT="172"/>
</TextLine>
<TextLine HEIGHT="72" WIDTH="1487" VPOS="1106" HPOS="483">
<String CONTENT="dá" HEIGHT="48" WIDTH="65" VPOS="1109" HPOS="483"/>
u novějších
<String CONTENT="poví" HEIGHT="64" HPOS="1774" SUBS_CONTENT="povídá" SUBS_TYPE="HypPart1" VPOS="958" WIDTH="115"/>
<SP HPOS="496" VPOS="974" WIDTH="19"/>
<SP HPOS="690" VPOS="958" WIDTH="18"/>
<SP HPOS="903" VPOS="996" WIDTH="24"/>
<SP HPOS="1087" VPOS="967" WIDTH="17"/>
<SP HPOS="1155" VPOS="957" WIDTH="22"/>
<SP HPOS="1311" VPOS="975" WIDTH="22"/>
<SP HPOS="1457" VPOS="957" WIDTH="23"/>
<SP HPOS="1752" VPOS="964" WIDTH="21"/>
<HYP CONTENT=""/>
</TextLine>
<TextLine BASELINE="1081" HEIGHT="67" HPOS="446" VPOS="1034" WIDTH="1463">
<String CONTENT="dá" HEIGHT="46" HPOS="446" SUBS_CONTENT="povídá" SUBS_TYPE="HypPart2" VPOS="1034" WIDTH="63"/>
Na konci stránky pak bývá jen něco jako
<String CONTENT="do-" HEIGHT="46" WIDTH="83" VPOS="2374" HPOS="1857"/>
Protože ocr se dělá bez kontextu souvisejících stránek. Ale tam je aspoň rozdělovník.
Pôvodný návrh so stromovou štruktúrou je momentálne neaktuálny, pretože by priniesol zbytočnú zložitosť pri práci so stromom. Vraciame sa teda k ukladaniu obsahu stránky publikácie ako pole tokenov, kde každý token obsahuje metadáta ktoré sa k nemu viažu.
Ideálne by sme chceli, aby prevod do formátu TEI a obohacovanie metadátami boli dva oddelené, navzájom nezávislé procesy. Nerád by som to miešal a snažil sa implementovať obohacovanie metadátami, kde vstupom do obohacovacieho procesu môže byť aj TEI formát, aj plain textový formát. Metadáta získané k jednotlivým tokenom z externých nástrojov(udPipe, nameTag), prípadne iných formátov zápisu(ALTO) budeme musieť nejakým spôsobom(iným než TEI formát) ukladať do primárnej databázy a následne predávať do TEI Convertoru, takže výstup z obohacovacieho procesu vo formáte TEI a následné spracovanie TEI do nejakého univerzálneho formátu, v ktorom budeme ukladať do DB, by bolo dosť nepraktické. Navyše pokiaľ správnu tokenizáciu(ako to bolo spomenuté vyššie) ktorá bude základom obohacovania, má zaisťovať nástroj UdPipe, bude musieť toto obohatenie prebehnúť v prvom kroku. Následne by sa tým pádom aj v TEI formáte označovali jednotlivé slová nie podľa ALTO formátu, ale podľa tokenizácie z UdPipe.
Preto by som teda preferoval druhú možnosť, ktorú som pre naše interné účely rozpísal trochu detailnejšie a tento popis prikladám nižšie.
Za robustnější řešení považuji nezkoušet tokenizaci vylepšit ručně, tokeny pospojovat do řetězce a nechat tokenizaci udělat UDPipe. Čili bych z ALTO vzal jen informaci o spojení rozděleného tokenu, pak nechal UDPipe udělat tokenizaci a tu použil pro TEI a namapoval na původní tokeny ALTO.
Držal by som sa teda práve tohto. Dôležité v popise vyššie sú hlavne situácie, ktoré môžu nastať, ak sa tokenizácia pomocou UdPipe nezhoduje s ALTO rozdelením na slová. Tu som definoval tri možnosti, ktoré môžu nastať(ak som na nejaký zabudol, prosím doplňte ma) a ako ich budeme riešiť. Prosím tiež o doplnenie, ako by sa rozdelené slová mali reprezentovať v TEI - viaceré <w>
tagy, jeden tag s viacerými odkazmi na polohy z ALTO, ...?
Zdá sa Vám tento postup vhodný?
Prosíme o vyjádření. @stranak @zabak
Pokud budeme chtít zachovat vazbu na pozice v ALTO, lze v TEI požít konstrukci typu
<w xml:id="w-2" next="#w-3">poví</w><w xml:id="w-3" prev="#w-2">dá</w>
.
Konverze ALTO na TEI https://github.com/cneud/ocr-conversion
Zdá sa Vám tento postup vhodný? Ano, mně to připadá dobré. Jen pár poznámek:
- počítal bych s tokenizací a obohacením plaintextu – tedy i lematizace – jak 2 procesy. Nejprve tokenizace, potom metadata k tokenu, např. to lemma. I pokud to teď bude dělat stejná služba, počítal bych se 2 nezávislými voláními.
- jednak i v UDPipe se může hodit použít různé modely (různá volání) pro tokenizaci a lematizaci, jednak to dovolí případně vyměnit tokenizer a lemmatizer nezávisle.
- plaintext se z ALTO musí extrahovat správně. Existují na to nějaké nástroje, ale netuším, jestli třeba to spojení rozdělených slov umění vyřešit správně (navíc když jsou na to 2 způsoby, jak popsal @zabak).
- @daliboris Jak se to rozdělené slovo reprezentuje v TEI? Konvertor ALTO>>TEI, co jsem našel dříve, tu informaci zahazuje.
- existují taky hotové projekty pro práci s ALTO. Třeba se něco z toho může hodit. https://github.com/altoxml/documentation/wiki/Software#tools-for-transforming-alto-or-other-formats-into-alto
- např. extrakce dat a metadat: https://github.com/cneud/alto-tools
- ruční opravy OCR přímo v ALTO XML: https://github.com/renevanderark/altoedit-2.0 (http://renevanderark.github.io/altoedit-2.0/) aj.
Pro srovnání, zajímavě vypadá taky toto obohacování o metadata: https://github.com/altomator/EN-data_mining
Dobrý deň,
z dôvodu prác na spracovávaní ALTO formátu by som rád znovuotvoril toto issue, najmä z dôvodu spomenutom v druhom bode tejto odpovede.
počítal bych s tokenizací a obohacením plaintextu – tedy i lematizace – jak 2 procesy
Tento postup by bol možný, ale treba brať do úvahy, že to v praxi znamená o jeden request na externý server viac. Momentálne každá stránka potrebuje 3 requesty (jeden pre získanie obsahu, jeden pre tokenizáciu a lematizáciu UDPipom a jeden pre obohatenie NameTagom), a keďže úzke hrdlo rýchlosti obohacovania je práve dotazovanie sa na externé služby, dĺžka obohacovacieho procesu by sa zvýšila približne o tretinu.
plaintext se z ALTO musí extrahovat správně. Existují na to nějaké nástroje, ale netuším, jestli třeba to spojení rozdělených slov umění vyřešit správně (navíc když jsou na to 2 způsoby, jak popsal @zabak).
Pôvodne pracoval systém Kramerius+ s textami stránok získaných z OCR streamu, t.j. plaintextom. Plaintext získaný z API krameria obsahoval aj znaky "-" a znaky nového riadku, čiže text presne odpovedal svojej fyzickej podobe. Pre spájanie slov na konci riadkov som používal veľmi jednoduchý regex pre nahradzovanie znakov
Tento postup bol síce veľmi triviálny, ale zdal sa byť pomerne efektívny.
S príchodom ALTO formátu sme plánovali plaintext vyťahovať z ALTO. Už pri prvotnej diskusii sme ale narazili na 2 rôzne spôsoby, akým môže byť rozdelené slovo na konci riadka zapísané(staršie vs novšie OCR). Teraz som narazil ešte na tretí spôsob, kedy rozdelené slovo nie je vôbec nijako označené za rozdelené.
Nabízí se tedy otázka, či má vôbec zmysel snažiť sa vymyslieť nejaký sofistikovanejší spôsob spájania slov než pôvodný "algoritmus", ktorý pracoval s plaintextom a jednoducho iba nahradzoval dvojice znakov na kocni riadka za prázdny znak.
Tým pádom by sme si mohli uľahčiť proces obohacovania o časť extrakcie plaintextu z ALTO(bolo by to menej pracné, proces obohacovania by bol rýchlejší a menej náchylný na programátorske chyby) a namiesto toho využiť už existujúci plaintext uložený v Krameriovi. Pre získanie metadát z ALTO formátu (poloha tokenu na stránke, šírka, výška) by sme museli namapovať existujúce tokeny na slová v ALTO, čo by sme ale museli aj pri extrakcii plaintextu z ALTO, takže tento krok je nevyhnutný v oboch prípadoch.
úzke hrdlo rýchlosti obohacovania je práve dotazovanie sa na externé služby
Podle repozitáře UDPipe is available as a binary for Linux/Windows/OS X, as a library for C++, Python, Perl, Java, C# (binárky jsou zde). Pokud by měla být tokenizace úzké hrdlo, možná by binární knihovna pomohla. Bylo by potřeba mít k dispozici aktuální verze modelů.
plaintext se z ALTO musí extrahovat správně. Existují na to nějaké nástroje
Zveřejnil jsem na svém forku DL4DH program v XProc, který data/texty Krameria extrahuje a obohacuje.
Pro získání textu nejprve transformuju ALTO na TEI pomocí šablony alto2tei.xsl; převzato odsud. Následně používám vlastní šablonu tei2text.xsl, která převede TEI na prostý text (včetně dvou prázdných odstavců pro oddělení původních odstavců).
jednoduchý regex pre nahradzovanie znakov
Nejspíš to opravdu pokryje většinu případů. Ještě mě napadá, že by se v některých textech mohl rozpoznat delší spojovník jako pomlčka (–, —).
Pomocí Alta možná budeme moci odlišit živé záhlaví, popř. zápatí, které by se mělo zpracovávat nezávisle na ostatním textu stránky.
Je třeba počítat s tím, že v některých případech se spojovník při OCR nerozpozná správně, případně se z pomlčky na konci řádku stane spojovník, což je časté v lingvistických textech, kde se pomlčka používá k označení zbytku slova (např. předpony od-, do-, při-).
V obou zmiňovaných případech bych to považoval za chybu externích nástrojů, kterou nebudeme opravovat. Pokud bychom ale objevili nějaký jednoduchý a 100% platný princip, který by část chyb eliminoval, tak bych nějakou opravu zavedl.
Já v tom nejsem žádný expert, ale intuitivně bych se přikláněl k tezi, že v průměrném textu bude většinou spojovník na konci řádku značit rozdělení slova na dva řádky a zmiňovaných regex tak, aspoň u většiny textů, víc chyb odfiltruje než jich vyrobí. Vzhledem k tomu, že zdaleka největší vliv na kvalitu bude mít OCR, bylo by kontraproduktivní vymýšlet nějaké složité pravidlové systémy. Za sebe bych šel po lince ALTO->regex->UDPipe a NameTag z plaintextu -> lemmatizovaný a obohacený text konvertovat do Kramerius+ v tabulkové nebo JSON formě a tentýž text konvertovat do TEI. TEI a tabulky by na sebe měly lícovat, což půjde zajistit jen tak, že TEI konverze bude posledním krokem.
ParagraphStyle
a o kousek dál elementy TextBlock
, které hodnotou atributu STYLEREFS
odkazují na ty odstavcové styly. Tak bych řekl, že to jsou odstavce. Zase to nemusí být ideální, ale než bych psal vlastní pravidla, která nejspíš rozbije upgrade OCRka, tak bych asi spíš doufal – aspoň prozatím – že to to OCR bude dělat slušně a nebo se zlepší časem a pustíme ho znovu. Koukám na ALTO z ABBYY Recognition Serveru 4, zpracováno 2020-02-13. Omlouvám se, ale k dalším bodům se mohu vyjádřit až v září.
Já v tom nejsem žádný expert, ale intuitivně bych se přikláněl k tezi, že v průměrném textu bude většinou spojovník na konci řádku značit rozdělení slova na dva řádky a zmiňovaných regex tak, aspoň u většiny textů, víc chyb odfiltruje než jich vyrobí. Vzhledem k tomu, že zdaleka největší vliv na kvalitu bude mít OCR, bylo by kontraproduktivní vymýšlet nějaké složité pravidlové systémy. Za sebe bych šel po lince ALTO->regex->UDPipe a NameTag z plaintextu -> lemmatizovaný a obohacený text konvertovat do Kramerius+ v tabulkové nebo JSON formě a tentýž text konvertovat do TEI. TEI a tabulky by na sebe měly lícovat, což půjde zajistit jen tak, že TEI konverze bude posledním krokem.
Přidal bych ještě to, že spojovník na konci řádku, před kterým není mezera ale písmeno znamená rozdělení slova.
Za sebe bych šel po lince ALTO->regex->UDPipe a NameTag z plaintextu -> lemmatizovaný a obohacený text konvertovat do Kramerius+ v tabulkové nebo JSON formě a tentýž text konvertovat do TEI. TEI a tabulky by na sebe měly lícovat, což půjde zajistit jen tak, že TEI konverze bude posledním krokem.
Z Krameria mame ale k dispozicii aj priamo plaintext, takze linka ALTO->regex pre získanie plaintextu je zbytočne komplikovaná. Preto navrhujem skôr nasledovny postup: PlainText + regex -> UDPipe a NameTag z plaintextu -> lemmatizovane a obohacene tokeny obohatit este o metadata z ALTO -> ulozit do DB (JSON) -> konvertovat do TEI
nepsal bych nic složitého, co bude třeba udržovat. Spojení slov bych klidně bral jen to, kde je indikované v ALTO, tedy kde to rozpoznal již ten OCR server, jak jsme řešili výše. Pokud to konvertor nezachová správně, tak bych udělal opravu do toho konvertoru (a pull request do původního projektu)
Ako bolo spomenute vyssie, zdroj plaintextu nemusi byt ALTO, usetrilo by nam to cas, ak by sme vychadzali uz z existujuceho plaintextu z Krameria. Z ALTO by sme nasledne iba vyextrahovali potrebne metadata pre jednotlive tokeny (pozicia na strane, pripadne rozdelenie strany na bloky textu a pod.)
Odstavce taky detekuje již OCR v ALTO. Nejsem na to žádný expert, ale když do ALTO souboru z knihovny kouknu, vidím tam elementy ParagraphStyle a o kousek dál elementy TextBlock, které hodnotou atributu STYLEREFS odkazují na ty odstavcové styly. Tak bych řekl, že to jsou odstavce. Zase to nemusí být ideální, ale než bych psal vlastní pravidla, která nejspíš rozbije upgrade OCRka, tak bych asi spíš doufal – aspoň prozatím – že to to OCR bude dělat slušně a nebo se zlepší časem a pustíme ho znovu. Koukám na ALTO z ABBYY Recognition Serveru 4, zpracováno 2020-02-13.
Elementy TextBlock označujú blok textu, nie však priamo odstavce. Napríklad tato strana je v ALTO rozdelena na bloky nasledovne:
a táto stránka s viacerými odstavcami je v alto ako jeden TextBlock. Ide o ABBYY Recognition Server 4.0 z 19.01.2021
Jenom upozorňuju, že zpracování formátu ALTO na TEI se nelze vyhnout, protože jenom díky tomuto převodu bude zachována informace o tom, kde na stránce/obrázku se daný token nachází. Ale je pravda, že by takovou transformaci šlo provádět paralelně, pokud by pro NameTag a UDPipe sloužil jako základ výstup OCR v prostém textu.
K identifikaci odstavců v ALTO viz též můj komentář k LIBCAS/DL4DH-TEI-Converter#5.
Pokud není problém obohacené tokeny spárovat s metadaty z ALTO a navíc je to efektivnější, tak jsem za všemi deseti. Více ve LIBCAS/DL4DH-TEI-Converter#5.
Mám trochu obavu, zda ale bude PlainText přímo z Krameria a PlainText generovaný přes ALTO z Krameria totéž. Není to produkt jiného OCR mechanismu a výsledky tedy budou jiné = nemůže to jít přesně napárovat? (@MLhotak, @zabak)
Aby nám to nepřineslo víc komplikací, než užitku...
zda ale bude PlainText přímo z Krameria a PlainText generovaný přes ALTO z Krameria totéž
Prostý text z Krameria (tj. dostupný přes rozhraní .../streams/TEXT_OCR) a text z ALTO (dostupný přes rozhraní .../strams/ALTO) převedený na TEI a následně na prostý text může být identický. V rámci konverze na TEI dochází totiž ke slučování slov rozdělených spojovníkem do jednoho tokenu, pokud je v ALTO naznačeno, že jde o rozdělené slovo. U výstupů typu TEXT_OCR to teď kolegové řeší pomocí regulárních výrazů.
Problém je v tom, že v ALTO není rozdělení slov pomocí spojovníku zachyceno důsledně: v ukázce, kterou jsme zpracovávali, je např. problém u slova Schwarzenbergů, které se při převodu z ALTO > TEI realizuje jako 3 tokeny: Schwarzen, - a bergů, zatímco při použití regulárních výrazů z toho vznikne jedno slovo.
Pokud při manipulaci s TEI zavedeme další podobné úpravy jako u prostého textu z OCR, mohli bychom se dostat ke shodnému výstupu z obou formátů.
Úpravy prostého textu pomocí regulárních výrazů mohou dát lepší výsledky (lepší podklady pro jazykovou analýzu); jak jsem ale upozorňoval v komentáři, u některých (hlavně asi lingvistických) textů to může zase vést k horším výsledkům.
@daliboris Já jsem to spíš myslel tak, zda nebyl pro generování PlainText OCR použit jiný nástroj, než pro ALTO. To by se pak mohlo lišit i více (kvalitou rozpoznání atd.). Možná to tak není a problém zde nebude, raději jsem to ale chtěl ověřit.
Většinou se obojí generuje stejným nástrojem. Raději ale prověřím reálnou praxi při některých specifických dodatečných úpravách existujících dat.
Výstupy morfologické analýzy z UDPipe se liší na základě použitého jazykového modelu. Německá slova rozpoznaná s použitím modelu pro češtinu se sice považují za cizí/nečeský text (Foreign=Yes
), ale rozpoznání morfologických kategorií a lemmatu selhává (např. u němekého zuführen
: lemma zuführený
, Gender=Masc|Number=Sing|Polarity=Pos|Variant=Short|VerbForm=Part|Voice=Pass
. Při použití odpovídajícího jazykového modelu jsou výsledky adekvátní: lemma zuführen
, VerbForm=Inf
.
Ve formátu ALTO lze ve verzi 2.1, která je základem výstupů v Krameriovi, identifikovat jazyk rozpoznaného textu pomocí atributu @LANG
na úrovni elementů <String>
, <TextLine>
a <TextBlock>
. Kódy pro jazyky jsou stejné jako u @xml:lang
, takže podle Tags for Identifying Languages (BCP47): cs
pro češtinu, de
pro němčinu atp.
ALTO v Krameriovi atribut pro jazyk neobsahují (otestováno na 4 publikacíh, českých a německých). Odtud tedy nelze údaj o jazyce dokumentu přebírat. Otázka na digitalizační pracoviště: proč v ALTO není jazyk uveden? Je to velká škoda, protože v případě vícejazyných publikací se můžou jazyky jednotlivých úseků (oddílů, stran, odstavců) lišit.
Identifikace jazyka celého dokumentu se nachází v metadatech typu MODS
, konkrétně v elementu /mods:modsCollection/mods:mods/mods:language/mods:languageTerm
. Pro označení jazyka se používají trojpísmené zkratky podle normy ISO 639-2, popř. asi jiné normy identifikované v atributu @authority
.
<mods:language>
<mods:languageTerm authority="iso639-2b" type="code">ger</mods:languageTerm>
</mods:language>
<mods:language>
<mods:languageTerm authority="iso639-2b" type="code">cze</mods:languageTerm>
</mods:language>
<mods:language>
<mods:languageTerm authority="iso639-2b" type="code">ger</mods:languageTerm>
</mods:language>
Kniha v němčině; vznikla překladem z češtiny, český text ale neobsahuje
<mods:language>
<mods:languageTerm authority="iso639-2b" type="code">ger</mods:languageTerm>
</mods:language>
<mods:language objectPart="translation">
<mods:languageTerm authority="iso639-2b" type="code">cze</mods:languageTerm>
</mods:language>
Při jazykovém zpracování využít údaj o jazyce, který se nachází v metadatech /mods:modsCollection/mods:mods/mods:language/mods:languageTerm
; přebírat údaje pouze z elementů, jejichž rodičkovský prvek nemá atribut @objectPart
.
Volat službu UDPipe, popř. NameTag s parametrem, který aplikuje správný jazykový model. Co dělat v případě, že publikace obsahuje jazyk, který UDPipe nebo NameTag nedokáže zpracovat? Existují 3 možnosti:
Vzhledem k tomu, jaké je zastoupení jazyků podle metadat má asi smysl použít variantu 2, snad s výjimkou nejčastějších jazyků, kde by se mohla hodit varianta 3. Které z níže uvedených jazyků nejsou těmi nástroji podporovány (a museli bychom hledat pro ně speciální nástroj)?
Čeština 197647 Němčina 26964 Angličtina 14701 Latina 6170 Francouzština 5284 Slovenština 3942 Ruština 3593 Italština 1890 Polština 1388 Maďarština 1123 Nizozemština 1079 Ukrajinština 1005 Španělština 423 Slovinština 387 Rumunština 356
23. 9. 2021 v 22:52, Petr Žabička @.***>: Vzhledem k tomu, jaké je zastoupení jazyků podle metadat má asi smysl použít variantu 2, snad s výjimkou nejčastějších jazyků, kde by se mohla hodit varianta 3. Které z níže uvedených jazyků nejsou těmi nástroji podporovány (a museli bychom hledat pro ně speciální nástroj)?
Já jsem Borisův příspěvek pochopil tak, že by chtěl správně zpracovat hlavně smíšený text, kde se třeba v českém textu objeví německé slovo. To je ale poměrně těžké. My zatím službu identifikace jazyka nemáme, ale i když ji plánujeme, pochybuji, že toto půjde. Obecně identifikace jazyka potřebuje delší kus textu. Pokud se jazyky střídají třeba po odstavci, to už by šlo (identifikace převažujícího jazyka odstavce). Teoreticky by to OCR služba dělat mohla, souhlasím, ale zjevně to nedělá.
Pokud by daná funkce byla důležitá – takové texty se často objevují – je možno zapojit existující službu na identifikaci jazyka jako Apache Tikka apod., nebo počkat, až bude dostupná od nás jako součást API UDPipe, NameTagu aj. Ale jak říkám, nečekejte, že to bude správně identifikovat jazyk jednoho cizího slova ve větě.
Čeština 197647 Němčina 26964 Angličtina 14701 Latina 6170 Francouzština 5284 Slovenština 3942 Ruština 3593 Italština 1890 Polština 1388 Maďarština 1123 Nizozemština 1079 Ukrajinština 1005 Španělština 423 Slovinština 387 Rumunština 356
Pokud jde jen o to říci, že celý titul (celá strana ALTO) je v daném jazyce, tak UDPipe má modely pro všechny tyto jazyky a mnoho dalších. Ne všechny jsou ale ze stejně velkých trénovacích dat, takže některé mají o dost menší úspěšnost. Pouštět to ale jde i nyní a nic tomu nebrání. Jen ve volání parametrem zvolíte buď jazyk, nebo přímo konkrétní model.
NameTag má těch modelů pak podstatně méně: z výše uvedených první tři, nizozemštinu a španělštinu.
Já jsem Borisův příspěvek pochopil tak, že by chtěl správně zpracovat hlavně smíšený text, kde se třeba v českém textu objeví německé slovo....
Nemyslel jsem to tak, neboť jsem pochopil, že v aktuálních datech Krameria v ALTO jazyk označen není, takže se musíme orientovat podle jazyka celé publikace.
Samozřejmě by bylo výhodnější získat informaci o jazyce pro jednotlivé odstavce/strany a podle toho usměrňovat obohacování o jazykovou analýzu.
Pokud by daná funkce byla důležitá – takové texty se často objevují – je možno zapojit existující službu na identifikaci jazyka jako Apache Tikka apod., nebo počkat, až bude dostupná od nás jako součást API UDPipe, NameTagu aj.
Je fakt, že jsem se zatím díval na volně dostupná díla, ale např. v novějších a zejména v odborných pracích nebude prolínání výjimkou. Např. sborníky nebo časopisy s různojazyčnými příspěvky. To už může mít na analýzu těchto typů dokumentů velký dopad, nemyslíte?
U sborníků (a předpokládám i časopisů) jsem narazil na to, že informace o jazyce jsou uvedený pro celé periodikum, nikoli pro jednotlivá vydání (ročníky, čísla), viz např. Laser 2018. Předpokládám ale, že složení jazyků v různých ročnících může být proměnlivé.
Jazykovou analýzu lze pustit buď na plaintextu a nebo na text převedený už do TEI: vyextrahuje se z něj plaintext, pustí analýza a vloží se zpět do TEI.
Viz také LIBCAS/DL4DH#1: toto rozhodnutí silně ovlivní, jak bude výsledné TEI vypadat.
Takto, až v TEI, pouštíme analýzu, když děláme parlamentní TEI dokumenty:
volání udpipe:
https://github.com/ufal/ParCzech/blob/master/src/run_parczech.sh#L402 volá tento skript: https://github.com/ufal/ParCzech/blob/master/src/udpipe2/udpipe2.pl
volání nametag:
https://github.com/ufal/ParCzech/blob/master/src/run_parczech.sh#L421 volá skript: https://github.com/ufal/ParCzech/blob/master/src/nametag2/nametag2.pl
Má to smysl řešit, pokud na začátku jako výsledek OCR máme ALTO, které obsahuje dost informací vč. pozic na stránce. Pokud chceme tyto informace zachovat i na výstupu do TEI, tak je asi nejsnazší TEI generovat přímo z ALTO. Zde je ukázka TEI z ALTO: https://cunicz-my.sharepoint.com/:f:/g/personal/51291532_cuni_cz/EjADq5FS0URHkvlkWlGpVmkBNLGfIisuJ6S55wfB10xMaw?e=LG8pgL
Druhá možnost je v současném schématu: ALTO >> plain text >> NLP analýza (+ přidat k tokenům koordináty z ALTO) >> TEI