This commit is contained in:
Bartekfiolek 2024-04-13 08:20:53 +02:00
commit 71ca3b66ed
15 changed files with 3085 additions and 0 deletions

1
lab/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.ipynb_checkpoints/

Binary file not shown.

BIN
lab/data/hunspell_pl.zip Normal file

Binary file not shown.

BIN
lab/img/tagtransfer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

478
lab/lab_01.ipynb Normal file
View File

@ -0,0 +1,478 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "packed-oracle",
"metadata": {},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Komputerowe wspomaganie tłumaczenia </h1>\n",
"<h2> 1. <i>Podstawowe techniki wspomagania tłumaczenia</i> [laboratoria]</h2> \n",
"<h3>Rafał Jaworski (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"id": "aggregate-listing",
"metadata": {},
"source": [
"Podstawowy scenariusz - tłumacz otrzymuje **dokument** będący ciągiem **segmentów** w **języku źródłowym** . Zadaniem tłumacza jest przetłumaczenie wszystkich segmentów na **język docelowy**. Oznacza to, że został wykonany już szereg operacji technicznych, a w tym:\n",
"- przesłanie pliku do tłumaczenia\n",
"- ekstrakcja tekstu z dokumentu\n",
"- podział tekstu na segmenty.\n"
]
},
{
"cell_type": "markdown",
"id": "allied-gasoline",
"metadata": {},
"source": [
"Tłumacz tłumaczy jeden segment na raz. Widzi kilka poprzednich oraz kilka następnych segmentów, jednak jego uwaga powinna skupiać się na aktywnym, aktualnie tłumaczonym segmencie. Nie oznacza to jednak, że tłumacz jest pozbawiony pomocy. Ma możliwość korzystania z różnorakich technik **komputerowego wspomagania tłumaczenia**."
]
},
{
"cell_type": "markdown",
"id": "golden-turkish",
"metadata": {},
"source": [
"# Pamięć tłumaczeń"
]
},
{
"cell_type": "markdown",
"id": "retired-burke",
"metadata": {},
"source": [
"Najbardziej podstawową techniką wspomagania tłumaczenia jest **pamięć tłumaczeń**. Pamięć tłumaczeń stanowi zbiór wcześniej przetłumaczonych zdań:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "narrow-romantic",
"metadata": {},
"outputs": [],
"source": [
"translation_memory = [('Wciśnij przycisk Enter', 'Press the ENTER button'), \n",
" ('Sprawdź ustawienia sieciowe', 'Check the network settings')]"
]
},
{
"cell_type": "markdown",
"id": "tender-drunk",
"metadata": {},
"source": [
"Kiedy tłumacz pracuje nad kolejnym zdaniem, program automatycznie przeszukuje pamięć tłumaczeń. Jeśli okaże się, że zdanie zostało już przetłumaczone, automatycznie pobierane jest jego tłumaczenie z pamięci:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "indonesian-electron",
"metadata": {},
"outputs": [],
"source": [
"def tm_lookup(sentence):\n",
" return [entry[1] for entry in translation_memory if entry[0] == sentence]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "compact-trinidad",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Press the ENTER button']"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tm_lookup('Wciśnij przycisk Enter')"
]
},
{
"cell_type": "markdown",
"id": "legislative-portsmouth",
"metadata": {},
"source": [
"W takim przypadku tłumaczenie z pamięci jest najczęściej automatycznie wstawiane jako tłumaczenie segmentu źródłowego i tłumacz nie musi się już nim martwić (co więcej, nie dostaje za takie tłumaczenie zapłaty...)"
]
},
{
"cell_type": "markdown",
"id": "prepared-entry",
"metadata": {},
"source": [
"Tłumacz pracuje dalej i każde wykonane przez niego tłumaczenie trafia do pamięci tłumaczeń (oczywiście dzieje się to automatycznie):"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "exposed-daniel",
"metadata": {},
"outputs": [],
"source": [
"translation_memory.append(('Drukarka jest wyłączona', 'The printer is switched off'))\n",
"translation_memory.append(('Wymagane ponowne uruchomienie komputera', 'System restart required'))\n",
"translation_memory.append(('Wciśnij przycisk Enter', 'Press the ENTER key'))"
]
},
{
"cell_type": "markdown",
"id": "alert-cancellation",
"metadata": {},
"source": [
"Z całą pewnością tłumacz stara się przełożyć jakąś komputerową instrukcję. Po wielu godzinach pracy trafia na znane sobie zdanie \"Wciśnij przycisk Enter\". Następuje przeszukanie pamięci tłumaczeń:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "serial-velvet",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Press the ENTER button', 'Press the ENTER key']"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tm_lookup('Wciśnij przycisk Enter')"
]
},
{
"cell_type": "markdown",
"id": "meaning-breathing",
"metadata": {},
"source": [
"Jak widać, mamy w pamięci dwa tłumaczenia tego zdania. To tłumacz musi zadecydować, które tłumaczenie wybrać. O metodach wspomagania decyzji tłumacza w takich przypadkach będziemy jeszcze mówić."
]
},
{
"cell_type": "markdown",
"id": "miniature-interim",
"metadata": {},
"source": [
"Przeanalizujmy teraz następujący przypadek: do tłumaczenia trafia zdanie: \"Wciśnij przycisk ENTER\":"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "every-gibson",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tm_lookup('Wciśnij przycisk ENTER')"
]
},
{
"cell_type": "markdown",
"id": "restricted-oregon",
"metadata": {},
"source": [
"Tutaj tłumacz nie ma szczęścia - restrykcyjny mechanizm wyszukiwania nie podaje mu podpowiedzi. Możemy jednak sprawić, żeby przeszukiwanie pamięci tłumaczeń nie brało pod uwagę wielkości liter."
]
},
{
"cell_type": "markdown",
"id": "inclusive-bargain",
"metadata": {},
"source": [
"### Ćwiczenie 1: zmodyfikuj funkcję tm_lookup w taki sposób, aby nie brała pod uwagę wielkości liter. Przetestuj zmodyfikowaną funkcję."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "protected-rings",
"metadata": {},
"outputs": [],
"source": [
"def tm_lookup(sentence):\n",
" return ''"
]
},
{
"cell_type": "markdown",
"id": "dress-plymouth",
"metadata": {},
"source": [
"Nasz tłumacz powinien być teraz zadowolony. Jednak w dalszej części dokumentu pojawiło się inne podobne zdanie, dla którego nie było tłumaczenia:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "severe-alloy",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"''"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tm_lookup('Wciśnij przycisk [ENTER]')"
]
},
{
"cell_type": "markdown",
"id": "choice-committee",
"metadata": {},
"source": [
"### Ćwiczenie 2: zmodyfikuj funkcję tm_lookup w taki sposób, aby nie brała pod uwagę znaków interpunkcyjnych. Rada - zdefiniuj funkcję sentence_similar."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "structural-diesel",
"metadata": {},
"outputs": [],
"source": [
"def tm_lookup(sentence):\n",
" return ''"
]
},
{
"cell_type": "markdown",
"id": "physical-distribution",
"metadata": {},
"source": [
"Praca tłumacza oczywiście trwa nadal. Spróbujmy teraz zaradzić następującej sytuacji - tłumacz otrzymuje do tłumaczenia następujące zdanie:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "brief-senegal",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"''"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tm_lookup('Wymagane ponowne uruchomienie maszyny')"
]
},
{
"cell_type": "markdown",
"id": "guided-tutorial",
"metadata": {},
"source": [
"Znów nie otrzymuje od nas podpowiedzi i znów nic w tym dziwnego - w pamięci tłumaczeń nie znajduje się takie zdanie. Jest jednak zdanie podobne, różniące się jednym słowem."
]
},
{
"cell_type": "markdown",
"id": "laughing-preview",
"metadata": {},
"source": [
"### Ćwiczenie 3: zmodyfikuj funkcję tm_lookup w taki sposób, aby zwracała podpowiedzi także wtedy, gdy zdania różnią się tylko jednym słowem."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "mathematical-customs",
"metadata": {},
"outputs": [],
"source": [
"def tm_lookup(sentence):\n",
" return ''"
]
},
{
"cell_type": "markdown",
"id": "meaningful-virus",
"metadata": {},
"source": [
"# Słownik kontekstowy / glosariusz"
]
},
{
"cell_type": "markdown",
"id": "early-variety",
"metadata": {},
"source": [
"Inną podstawową pomocą dla naszego tłumacza jest słownik, zwany także glosariuszem. Stanowi on zbiór terminów w języku źródłowym wraz z ich tłumaczeniami na język docelowy:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "humanitarian-wrong",
"metadata": {},
"outputs": [],
"source": [
"glossary = [('komputer', 'computer'), ('przycisk', 'button'), ('drukarka', 'printer')]"
]
},
{
"cell_type": "markdown",
"id": "minimal-moral",
"metadata": {},
"source": [
"Podczas tłumaczenia, glosariusz jest przeszukiwany w celu znalezienia aktualnie tłumaczonych słów."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "located-perception",
"metadata": {},
"outputs": [],
"source": [
"def glossary_lookup(sentence):\n",
" sentence_words = sentence.split()\n",
" return [entry for entry in glossary if entry[0] in sentence_words]"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "advised-casting",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[('przycisk', 'button'), ('drukarka', 'printer')]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"glossary_lookup('Każda drukarka posiada przycisk wznowienia drukowania')"
]
},
{
"cell_type": "markdown",
"id": "blessed-gentleman",
"metadata": {},
"source": [
"### Ćwiczenie 4: (tym razem teoretyczne) Jaka jest złożoność obliczeniowa czasowa przedstawionego powyżej algorytmu względem liczby haseł w słowniku (n) oraz liczby słów w zdaniu do tłumaczenia (m)?"
]
},
{
"cell_type": "markdown",
"id": "defensive-fifteen",
"metadata": {},
"source": [
"Odpowiedź:"
]
},
{
"cell_type": "markdown",
"id": "objective-matthew",
"metadata": {},
"source": [
"### Ćwiczenie 5: zmodyfikuj funkcję glossary_lookup w taki sposób, aby nie brała pod uwagę wielkości liter."
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "original-tunisia",
"metadata": {},
"outputs": [],
"source": [
"def glossary_lookup(sentence):\n",
" return ''"
]
},
{
"cell_type": "markdown",
"id": "injured-hormone",
"metadata": {},
"source": [
"### Ćwiczenie 6: zmodyfikuj funkcję glossary_lookup w taki sposób, aby jej złożoność obliczeniowa była mniejsza."
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "adolescent-semiconductor",
"metadata": {},
"outputs": [],
"source": [
"def glossary_lookup(sentence):\n",
" return ''"
]
}
],
"metadata": {
"author": "Rafał Jaworski",
"email": "rjawor@amu.edu.pl",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"lang": "pl",
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"subtitle": "1. Podstawowe techniki wspomagania tłumaczenia",
"title": "Komputerowe wspomaganie tłumaczenia",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 5
}

384
lab/lab_02.ipynb Normal file
View File

@ -0,0 +1,384 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "continued-dinner",
"metadata": {},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Komputerowe wspomaganie tłumaczenia </h1>\n",
"<h2> 2. <i>Zaawansowane użycie pamięci tłumaczeń</i> [laboratoria]</h2> \n",
"<h3>Rafał Jaworski (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"id": "aggregate-listing",
"metadata": {},
"source": [
"Wiemy już, do czego służy pamięć tłumaczeń. Spróbujmy przeprowadzić mały research, którego celem będzie odkrycie, w jaki sposób do pamięci tłumaczeń podchodzą najwięksi producenci oprogramowania typu CAT.\n"
]
},
{
"cell_type": "markdown",
"id": "golden-turkish",
"metadata": {},
"source": [
"### Ćwiczenie 1: Wykonaj analizę funkcjonalności pamięci tłumaczeń w programach SDL Trados Studio 2021 oraz Kilgray memoQ. Dla obu programów wypisz funkcje, które są związane z TM oraz zaznacz, które funkcje są wspólne dla obu programów oraz których funkcji Tradosa brakuje w memoQ oraz odwrotnie."
]
},
{
"cell_type": "markdown",
"id": "retired-burke",
"metadata": {},
"source": [
"Odpowiedź:"
]
},
{
"cell_type": "markdown",
"id": "existing-approval",
"metadata": {},
"source": [
"Jedną z funkcji dostępnych we wszystkich większych programach do wspomagania tłumaczenia jest znajdowanie bardzo pewnych dopasowań w pamięci tłumaczeń. Są one zwane **ICE** (In-Context Exact match) lub 101% match. Są to takie dopasowania z pamięci tłumaczeń, dla których nie tylko zdanie źródłowe z TM jest identyczne z tłumaczonym, ale także poprzednie zdanie źródłowe z TM zgadza się z poprzednim zdaniem tłumaczonym oraz następne z TM z następnym tłumaczonym."
]
},
{
"cell_type": "markdown",
"id": "decimal-electricity",
"metadata": {},
"source": [
" Rozważmy przykładową pamięć tłumaczeń z poprzednich zajęć (można do niej dorzucić kilka przykładów):"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "confident-prison",
"metadata": {},
"outputs": [],
"source": [
"translation_memory = [\n",
" ('Wciśnij przycisk Enter', 'Press the ENTER button'), \n",
" ('Sprawdź ustawienia sieciowe', 'Check the network settings'),\n",
" ('Drukarka jest wyłączona', 'The printer is switched off'),\n",
" ('Wymagane ponowne uruchomienie komputera', 'System restart required')\n",
" ]"
]
},
{
"cell_type": "markdown",
"id": "informal-breakdown",
"metadata": {},
"source": [
"### Ćwiczenie 2: Zaimplementuj funkcję ice_lookup, przyjmującą trzy parametry: aktualnie tłumaczone zdanie, poprzednio tłumaczone zdanie, następne zdanie do tłumaczenia. Funkcja powinna zwracać dopasowania typu ICE. Nie pozwól, aby doszło do błędów podczas sprawdzania pierwszego i ostatniego przykładu w pamięci (ze względu na brak odpowiednio poprzedzającego oraz następującego przykładu)."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "continental-submission",
"metadata": {},
"outputs": [],
"source": [
"def ice_lookup(sentence, prev_sentence, next_sentence):\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "figured-server",
"metadata": {},
"source": [
"Inną powszechnie stosowaną techniką przeszukiwania pamięci tłumaczeń jest tzw. **fuzzy matching**. Technika ta polega na wyszukiwaniu zdań z pamięci, które są tylko podobne do zdania tłumaczonego. Na poprzednich zajęciach wykonywaliśmy funkcję tm_lookup, która pozwalała na różnicę jednego słowa."
]
},
{
"cell_type": "markdown",
"id": "beautiful-fancy",
"metadata": {},
"source": [
"Zazwyczaj jednak funkcje fuzzy match posiadają znacznie szersze możliwości. Ich działanie opiera się na zdefiniowaniu funkcji $d$ dystansu pomiędzy zdaniami $x$ i $y$. Matematycznie, funkcja dystansu posiada następujące właściwości:\n",
"1. $\\forall_{x,y} d(x,y)\\geqslant 0$\n",
"2. $\\forall_{x,y} d(x,y)=0 \\Leftrightarrow x=y$\n",
"3. $\\forall_{x,y} d(x,y)=d(y,x)$\n",
"4. $\\forall_{x,y,z} d(x,y) + d(y,z)\\geqslant d(x,z)$"
]
},
{
"cell_type": "markdown",
"id": "square-usage",
"metadata": {},
"source": [
"Rozważmy następującą funkcję:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "fourth-pillow",
"metadata": {},
"outputs": [],
"source": [
"def sentence_distance(x,y):\n",
" return abs(len(y) - len(x))"
]
},
{
"cell_type": "markdown",
"id": "mediterranean-cosmetic",
"metadata": {},
"source": [
"### Ćwiczenie 3: Czy to jest poprawna funkcja dystansu? Które warunki spełnia?"
]
},
{
"cell_type": "markdown",
"id": "graduate-theorem",
"metadata": {},
"source": [
"Odpowiedź:"
]
},
{
"cell_type": "markdown",
"id": "native-amber",
"metadata": {},
"source": [
"A teraz spójrzmy na taką funkcję:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "continued-christopher",
"metadata": {},
"outputs": [],
"source": [
"def sentence_distance(x,y):\n",
" if (x == y):\n",
" return 0\n",
" else:\n",
" return 3"
]
},
{
"cell_type": "markdown",
"id": "every-surveillance",
"metadata": {},
"source": [
"### Ćwiczenie 4: Czy to jest poprawna funkcja dystansu? Które warunki spełnia?"
]
},
{
"cell_type": "markdown",
"id": "metallic-leave",
"metadata": {},
"source": [
"Odpowiedź:"
]
},
{
"cell_type": "markdown",
"id": "executed-baptist",
"metadata": {},
"source": [
"Wprowadźmy jednak inną funkcję dystansu - dystans Levenshteina. Dystans Levenshteina pomiędzy dwoma łańcuchami znaków definiuje się jako minimalną liczbę operacji edycyjnych, które są potrzebne do przekształcenia jednego łańcucha znaków w drugi. Wyróżniamy trzy operacje edycyjne:\n",
"* dodanie znaku\n",
"* usunięcie znaku\n",
"* zamiana znaku na inny"
]
},
{
"cell_type": "markdown",
"id": "square-brown",
"metadata": {},
"source": [
"### Ćwiczenie 5: Czy dystans Levenshteina jest poprawną funkcją dystansu? Uzasadnij krótko swoją odpowiedź sprawdzając każdy z warunków."
]
},
{
"cell_type": "markdown",
"id": "bibliographic-stopping",
"metadata": {},
"source": [
"Odpowiedź:"
]
},
{
"cell_type": "markdown",
"id": "attended-channels",
"metadata": {},
"source": [
"W Pythonie dostępna jest biblioteka zawierająca implementację dystansu Levenshteina. Zainstaluj ją w swoim systemie przy użyciu polecenia:\n",
"\n",
"`pip3 install python-Levenshtein`\n",
"\n",
"I wypróbuj:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "secondary-wrist",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from Levenshtein import distance as levenshtein_distance\n",
"\n",
"levenshtein_distance(\"kotek\", \"kotki\")\n"
]
},
{
"cell_type": "markdown",
"id": "concrete-satellite",
"metadata": {},
"source": [
"Funkcja ta daje nam możliwość zdefiniowania podobieństwa pomiędzy zdaniami:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "associate-tuner",
"metadata": {},
"outputs": [],
"source": [
"def levenshtein_similarity(x,y):\n",
" return 1 - levenshtein_distance(x,y) / max(len(x), len(y))"
]
},
{
"cell_type": "markdown",
"id": "built-michael",
"metadata": {},
"source": [
"Przetestujmy ją!"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "focal-pathology",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9166666666666666"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"levenshtein_similarity('Program jest uruchomiony', 'Program jest uruchamiany')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "roman-ceiling",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9428571428571428"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"levenshtein_similarity('Spróbuj wyłączyć i włączyć komputer', 'Spróbuj włączyć i wyłączyć komputer')"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "invisible-cambodia",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.631578947368421"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"levenshtein_similarity('Spróbuj wyłączyć i włączyć komputer', 'Nie próbuj wyłączać i włączać drukarki')"
]
},
{
"cell_type": "markdown",
"id": "administrative-phoenix",
"metadata": {},
"source": [
"### Ćwiczenie 6: Napisz funkcję fuzzy_lookup, która wyszuka w pamięci tłumaczeń wszystkie zdania, których podobieństwo Levenshteina do zdania wyszukiwanego jest większe lub równe od ustalonego progu."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "genetic-cradle",
"metadata": {},
"outputs": [],
"source": [
"def fuzzy_lookup(sentence, threshold):\n",
" return []"
]
}
],
"metadata": {
"author": "Rafał Jaworski",
"email": "rjawor@amu.edu.pl",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"lang": "pl",
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"subtitle": "2. Zaawansowane użycie pamięci tłumaczeń",
"title": "Komputerowe wspomaganie tłumaczenia",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 5
}

433
lab/lab_03.ipynb Normal file
View File

@ -0,0 +1,433 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "coastal-lincoln",
"metadata": {},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Komputerowe wspomaganie tłumaczenia </h1>\n",
"<h2> 3. <i>Terminologia</i> [laboratoria]</h2> \n",
"<h3>Rafał Jaworski (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"id": "aggregate-listing",
"metadata": {},
"source": [
"Na dzisiejszych zajęciach zajmiemy się bliżej słownikami używanymi do wspomagania tłumaczenia. Oczywiście na rynku dostępnych jest bardzo wiele słowników w formacie elektronicznym. Wiele z nich jest gotowych do użycia w SDL Trados, memoQ i innych narzędziach CAT. Zawierają one setki tysięcy lub miliony haseł i oferują natychmiastową pomoc tłumaczowi."
]
},
{
"cell_type": "markdown",
"id": "israeli-excuse",
"metadata": {},
"source": [
"Problem jednak w tym, iż często nie zawierają odpowiedniej terminologii specjalistycznej - używanej przez klienta zamawiającego tłumaczenie. Terminy specjalistyczne są bardzo częste w tekstach tłumaczonych ze względu na następujące zjawiska:\n",
"- Teksty o tematyce ogólnej są tłumaczone dość rzadko (nikt nie tłumaczy pocztówek z pozdrowieniami z wakacji...)\n",
"- Te same słowa mogą mieć zarówno znaczenie ogólne, jak i bardzo specjalistyczne (np. \"dziedziczenie\" w kontekście prawnym lub informatycznym)\n",
"- Klient używa nazw lub słów wymyślonych przez siebie, np. na potrzeby marketingowe."
]
},
{
"cell_type": "markdown",
"id": "reflected-enforcement",
"metadata": {},
"source": [
"Nietrywialnymi zadaniami stają się: odnalezienie terminu specjalistycznego w tekście źródłowym oraz podanie prawidłowego tłumaczenia tego terminu na język docelowy"
]
},
{
"cell_type": "markdown",
"id": "statutory-florist",
"metadata": {},
"source": [
"Brzmi prosto? Spróbujmy wykonać ręcznie tę drugą operację."
]
},
{
"cell_type": "markdown",
"id": "danish-anchor",
"metadata": {},
"source": [
"### Ćwiczenie 1: Podaj tłumaczenie terminu \"prowadnice szaf metalowych\" na język angielski. Opisz, z jakich narzędzi skorzystałaś/eś."
]
},
{
"cell_type": "markdown",
"id": "diverse-sunglasses",
"metadata": {},
"source": [
"Odpowiedź:"
]
},
{
"cell_type": "markdown",
"id": "limited-waterproof",
"metadata": {},
"source": [
"W dalszych ćwiczeniach skupimy się jednak na odszukaniu terminu specjalistycznego w tekście. W tym celu będą potrzebne dwie operacje:\n",
"1. Przygotowanie słownika specjalistycznego.\n",
"2. Detekcja terminologii przy użyciu przygotowanego słownika specjalistycznego."
]
},
{
"cell_type": "markdown",
"id": "literary-blues",
"metadata": {},
"source": [
"Zajmijmy się najpierw krokiem nr 2 (gdyż jest prostszy). Rozważmy następujący tekst:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "loving-prince",
"metadata": {},
"outputs": [],
"source": [
"text = \" For all Java programmers:\"\n",
"text += \" This section explains how to compile and run a Swing application from the command line.\"\n",
"text += \" For information on compiling and running a Swing application using NetBeans IDE,\"\n",
"text += \" see Running Tutorial Examples in NetBeans IDE. The compilation instructions work for all Swing programs\"\n",
"text += \" — applets, as well as applications. Here are the steps you need to follow:\"\n",
"text += \" Install the latest release of the Java SE platform, if you haven't already done so.\"\n",
"text += \" Create a program that uses Swing components. Compile the program. Run the program.\""
]
},
{
"cell_type": "markdown",
"id": "extreme-cycling",
"metadata": {},
"source": [
"Załóżmy, że posiadamy następujący słownik:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "bound-auction",
"metadata": {},
"outputs": [],
"source": [
"dictionary = ['program', 'application', 'applet' 'compile']"
]
},
{
"cell_type": "markdown",
"id": "other-trinidad",
"metadata": {},
"source": [
"### Ćwiczenie 2: Napisz program, który wypisze pozycje wszystkich wystąpień poszczególnych terminów specjalistycznych. Dla każdego terminu należy wypisać listę par (pozycja_startowa, pozycja końcowa)."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "cognitive-cedar",
"metadata": {},
"outputs": [],
"source": [
"def terminology_lookup():\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "interior-things",
"metadata": {},
"source": [
"Zwykłe wyszukiwanie w tekście ma pewne wady. Na przykład, gdy szukaliśmy słowa \"program\", złapaliśmy przypadkiem słowo \"programmer\". Złapaliśmy także słowo \"programs\", co jest poprawne, ale niepoprawnie podaliśmy jego pozycję w tekście."
]
},
{
"cell_type": "markdown",
"id": "aggressive-plane",
"metadata": {},
"source": [
"Żeby poradzić sobie z tymi problemami, musimy wykorzystać techniki przetwarzania języka naturalnego. Wypróbujmy pakiet spaCy:\n",
"\n",
"`pip3 install spacy`\n",
"\n",
"oraz\n",
"\n",
"`python3 -m spacy download en_core_web_sm`"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "tribal-attention",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" \n",
"for\n",
"all\n",
"Java\n",
"programmer\n",
":\n",
"this\n",
"section\n",
"explain\n",
"how\n",
"to\n",
"compile\n",
"and\n",
"run\n",
"a\n",
"swing\n",
"application\n",
"from\n",
"the\n",
"command\n",
"line\n",
".\n",
"for\n",
"information\n",
"on\n",
"compile\n",
"and\n",
"run\n",
"a\n",
"swing\n",
"application\n",
"use\n",
"NetBeans\n",
"IDE\n",
",\n",
"see\n",
"Running\n",
"Tutorial\n",
"Examples\n",
"in\n",
"NetBeans\n",
"IDE\n",
".\n",
"the\n",
"compilation\n",
"instruction\n",
"work\n",
"for\n",
"all\n",
"swing\n",
"program\n",
"—\n",
"applet\n",
",\n",
"as\n",
"well\n",
"as\n",
"application\n",
".\n",
"here\n",
"be\n",
"the\n",
"step\n",
"-PRON-\n",
"need\n",
"to\n",
"follow\n",
":\n",
"install\n",
"the\n",
"late\n",
"release\n",
"of\n",
"the\n",
"Java\n",
"SE\n",
"platform\n",
",\n",
"if\n",
"-PRON-\n",
"have\n",
"not\n",
"already\n",
"do\n",
"so\n",
".\n",
"create\n",
"a\n",
"program\n",
"that\n",
"use\n",
"Swing\n",
"component\n",
".\n",
"compile\n",
"the\n",
"program\n",
".\n",
"run\n",
"the\n",
"program\n",
".\n"
]
}
],
"source": [
"import spacy\n",
"nlp = spacy.load(\"en_core_web_sm\")\n",
"\n",
"doc = nlp(text)\n",
"\n",
"for token in doc:\n",
" print(token.lemma_)"
]
},
{
"cell_type": "markdown",
"id": "regional-craft",
"metadata": {},
"source": [
"Sukces! Nastąpił podział tekstu na słowa (tokenizacja) oraz sprowadzenie do formy podstawowej każdego słowa (lematyzacja)."
]
},
{
"cell_type": "markdown",
"id": "toxic-subsection",
"metadata": {},
"source": [
"### Ćwiczenie 3: Zmodyfikuj program z ćwiczenia 2 tak, aby zwracał również odmienione słowa. Na przykład, dla słowa \"program\" powinien znaleźć również \"programs\", ustawiając pozycje w tekście odpowiednio dla słowa \"programs\". Wykorzystaj właściwość idx tokenu."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "surgical-demonstration",
"metadata": {},
"outputs": [],
"source": [
"def terminology_lookup():\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "straight-letter",
"metadata": {},
"source": [
"Teraz czas zająć się problemem przygotowania słownika specjalistycznego. W tym celu napiszemy nasz własny ekstraktor terminologii. Wejściem do ekstraktora będzie tekst zawierający specjalistyczną terminologię. Wyjściem - lista terminów."
]
},
{
"cell_type": "markdown",
"id": "nearby-frontier",
"metadata": {},
"source": [
"Przyjmijmy następujące podejście - terminami specjalistycznymi będą najcześćiej występujące rzeczowniki w tekście. Wykonajmy krok pierwszy:"
]
},
{
"cell_type": "markdown",
"id": "harmful-lightning",
"metadata": {},
"source": [
"### Ćwiczenie 4: Wypisz wszystkie rzeczowniki z tekstu. Wykorzystaj możliwości spaCy."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "superb-butterfly",
"metadata": {},
"outputs": [],
"source": [
"def get_nouns(text):\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "musical-creator",
"metadata": {},
"source": [
"Teraz czas na podliczenie wystąpień poszczególnych rzeczowników. Uwaga - różne formy tego samego słowa zliczamy razem jako wystąpienia tego słowa (np. \"program\" i \"programs\"). Najwygodniejszą metodą podliczania jest zastosowanie tzw. tally (po polsku \"zestawienie\"). Jest to słownik, którego kluczem jest słowo w formie podstawowej, a wartością liczba wystąpień tego słowa, wliczając słowa odmienione. Przykład gotowego tally:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "acting-tolerance",
"metadata": {},
"outputs": [],
"source": [
"tally = {\"program\" : 4, \"component\" : 1}"
]
},
{
"cell_type": "markdown",
"id": "vanilla-estimate",
"metadata": {},
"source": [
"### Ćwiczenie 5: Napisz program do ekstrakcji terminologii z tekstu według powyższych wytycznych."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "eight-redhead",
"metadata": {},
"outputs": [],
"source": [
"def extract_terms(text):\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "loaded-smell",
"metadata": {},
"source": [
"### Ćwiczenie 6: Rozszerz powyższy program o ekstrację czasowników i przymiotników."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "monetary-mambo",
"metadata": {},
"outputs": [],
"source": [
"def extract_terms(text):\n",
" return []"
]
}
],
"metadata": {
"author": "Rafał Jaworski",
"email": "rjawor@amu.edu.pl",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"lang": "pl",
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"subtitle": "3. Terminologia",
"title": "Komputerowe wspomaganie tłumaczenia",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 5
}

289
lab/lab_04-05.ipynb Normal file

File diff suppressed because one or more lines are too long

216
lab/lab_06-07.ipynb Normal file
View File

@ -0,0 +1,216 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "described-terrain",
"metadata": {},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Komputerowe wspomaganie tłumaczenia </h1>\n",
"<h2> 6,7. <i>Preprocessing i postprocessing</i> [laboratoria]</h2> \n",
"<h3>Rafał Jaworski (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"id": "colored-nothing",
"metadata": {},
"source": [
"Na dzisiejszych zajęciach zajmiemy się niezwykle przydatnymi narzędziami wspomagającymi pracę tłumacza. W odróżnieniu od dotychczas poznanych, nie są one oparte na pamięci tłumaczeń, ani na słownikach. Chodzi o techniki preprocessingu i postprocessingu."
]
},
{
"cell_type": "markdown",
"id": "atomic-rubber",
"metadata": {},
"source": [
"Proces tłumaczenia przeprowadzony w pełni profesjonalnie składa się z wielu faz, które angażują nie tylko tłumaczy, ale także kierowników projektu, analityków, czy korektorów. Każda z tych osób do swojej pracy może wykorzystywać system informatyczny, do którego na początku całego procesu trafiają pliki do tłumaczenia. Oznacza to, że zanim tekst źródłowy trafi do tłumacza, system ma jeszcze szansę coś w nim zmienić. A kiedy tłumacz wykona już swoją pracę, można uruchomić kolejny mechanizm, który zmodyfikuje tłumaczenie przed oddaniem go do zamawiającego. Jak się domyślamy, modyfikacje tekstu przed przekazaniem go do tłumacza nazywamy **preprocessingiem**, natomiast te dokonywane po wykonaniu tłumaczenia (ale przed zwróceniem go do klienta) nazywamy **postprocessingiem**. Terminy te, będące mało zgrabnymi kalkami z języka angielskiego, mają wersje prawdziwie polskie: przetwarzanie wstępne i końcowe. Wersje te są jednak stosowane na tyle rzadko, że mogą jedynie wprowadzić zamieszanie (co w gruncie rzeczy jest dość smutne)."
]
},
{
"cell_type": "markdown",
"id": "mature-republic",
"metadata": {},
"source": [
"Typowe operacje w fazie preprocessingu obejmują:\n",
"* identyfikację tagów xmlowych (które często są później wyświetlane w interfejsie CAT-a jako jeden niepodzielny znak)\n",
"* identyfikację segmentów, których nie należy tłumaczyć (na przykład składających się z samych liczb)\n",
"\n",
"* identyfikację dat i jednostek miary w tekście źródłowym\n",
"\n",
"We wszystkich tych operacjach niezwykle przydatne okazują się wyrażenia regularne."
]
},
{
"cell_type": "markdown",
"id": "southern-applicant",
"metadata": {},
"source": [
"### Ćwiczenie 1: Używając wyrażeń regularnych napisz funkcję do znajdowania wszystkich tagów XML w tekście. Funkcja powinna zwracać pozycje, na których znalazła tagi."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "documented-hacker",
"metadata": {},
"outputs": [],
"source": [
"def find_tags(text):\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "determined-utilization",
"metadata": {},
"source": [
"### Ćwiczenie 2: Używając wyrażeń regularnych napisz funkcję do identyfikacji segmentów, których nie należy tłumaczyć. Zastosuj wymyślone przez siebie kryteria. Funkcja is_translatable powinna zwracać True, jeśli segment powinien być przetłumaczony przez tłumacza (zwykłe zdanie). False powinno być zwrócone, kiedy segment jest nieprzetłumaczalny i powinien zostać skopiowany (np. 4.2.1.)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "unauthorized-study",
"metadata": {},
"outputs": [],
"source": [
"def is_translatable(text):\n",
" return True"
]
},
{
"cell_type": "markdown",
"id": "plastic-crown",
"metadata": {},
"source": [
"### Ćwiczenie 3: Używając wyrażeń regularnych napisz funkcję do identyfikacji i interpretacji 5 wybranych przez siebie formatów daty. Funkcja powinna zwracać pozycje, na których odnalazła daty oraz dzień, miesiąc i rok, które ta data reprezentuje."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "beautiful-mathematics",
"metadata": {},
"outputs": [],
"source": [
"def find_dates(text):\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "hourly-incentive",
"metadata": {},
"source": [
"Po preprocessingu i tłumaczeniu czas na postprocessing. Ponieważ wykonywany jest on na przetłumaczonym tekście, jego głównym zadaniem jest eliminacja błędów popełnionych przez tłumacza w fazie tłumaczenia. Podczas postprocessingu najczęściej wykonuje się:\n",
"* korektę pisowni dla języka docelowego\n",
"* usuwanie błędów typograficznych z tekstu (np. wielokrotne spacje, brak spacji po przecinku)\n",
"Stanowi to bardzo ważne wsparcie dla edytorów i korektorów, czyli osób sprawdzających pracę tłumacza.\n",
"\n",
"Jednak nowoczesne CAT-y potrafią coś jeszcze. Są w stanie w sprytny sposób wykorzystać kombinację pre- i postprocessingu do wyręczenia tłumacza w żmudnych i technicznych czynnościach. Wykonajmy następujące ćwiczenie:"
]
},
{
"cell_type": "markdown",
"id": "dental-combination",
"metadata": {},
"source": [
"### Ćwiczenie 4: Wykorzystując funkcję find_dates napisz funkcję do obsługi dat w tłumaczeniu. Wejściem jest segment źródłowy oraz docelowy, które zawierają daty, przy czym daty te mogą być w różnych formatach. Dodatkowym parametrem wejściowym jest nazwa oczekiwanego formatu daty w tłumaczeniu (np. \"Europe\", \"US\", \"digit-dot\". Funkcja najpierw sprawdza, czy liczba dat w tłumaczeniu zgadza się z liczbą dat w segmencie źródłowym oraz czy odpowiadające sobie daty wskazują na ten sam dzień. Jeśli nie, wypisywane jest stosowne ostrzeżenie. Oczekiwanym wyjściem jest segment docelowy, w którym wszystkie daty są w żądanym formacie. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "finished-essex",
"metadata": {},
"outputs": [],
"source": [
"def correct_dates(source_segment, target_segment, date_format):\n",
" return ''"
]
},
{
"cell_type": "markdown",
"id": "vertical-divide",
"metadata": {},
"source": [
"Co jeszcze można zrobić? Zajmijmy się tagami XML. Z punktu widzenia tłumacza najlepiej byłoby, gdyby mógł przetłumaczyć segment źródłowy zawierający tagi XML na język docelowy zupełnie ignorując te tagi. Ponieważ jednak tagi muszą jakoś znaleźć się w segmencie docelowym, przydałaby się jakaś \"magiczna różdżka\", która przeniosłaby wszystkie tagi ze źródła do tłumaczenia na mniej więcej dobre miejsca. Spełnijmy marzenie tłumacza!"
]
},
{
"cell_type": "markdown",
"id": "trained-trouble",
"metadata": {},
"source": [
"Rozważmy następujący algorytm: na wejściu mamy segment źródłowy zawierający tagi oraz segment docelowy bez tagów. Dokonujemy tokenizacji segmentu źródłowego tak, aby tagi były osobnymi tokenami. Następnie przeprowadźmy tokenizację segmentu docelowego. Gdy to jest gotowe, możemy zabrać się za przenoszenie (kopiowanie) tagów z segmentu źródłowego do docelowego."
]
},
{
"cell_type": "markdown",
"id": "damaged-simpson",
"metadata": {},
"source": [
"![Transfer tagów](img/tagtransfer.png)"
]
},
{
"cell_type": "markdown",
"id": "numerical-southeast",
"metadata": {},
"source": [
"Gdzie w segmencie docelowym powinien trafić tag? Przede wszystkim pomiędzy tokeny - nie chcemy rozbijać słów tagami. Pytanie tylko, pomiędzy które tokeny? Jeśli sytuacja jest taka, jak powyżej, kiedy segment źródłowy i docelowy mają taką samą liczbę słów nie będących tagami, przenosimy tagi na odpowiadające pozycje w tłumaczeniu. Natomiast jeśli długość tłumaczenia jest inna niż źródła, należy obliczać te pozycje w sposób proporcjonalny - jeśli np. mamy tag w źródle na pozycji 3, a tłumaczenie jest dwa razy dłuższe niż źródło, tag powinien być przeniesiony do tłumaczenia na pozycję 6. W przypadku niecałkowitych wartości proporcji stosujemy zaokrąglenia."
]
},
{
"cell_type": "markdown",
"id": "separated-socket",
"metadata": {},
"source": [
"### Ćwiczenie 5: Zaimplementuj opisany algorytm transferu tagów."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "romance-judge",
"metadata": {},
"outputs": [],
"source": [
"def transfer_tags(source_segment, target_segment):\n",
" return ''"
]
}
],
"metadata": {
"author": "Rafał Jaworski",
"email": "rjawor@amu.edu.pl",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"lang": "pl",
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"subtitle": "6,7. Preprocessing i postprocessing",
"title": "Komputerowe wspomaganie tłumaczenia",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 5
}

217
lab/lab_08.ipynb Normal file
View File

@ -0,0 +1,217 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "improved-register",
"metadata": {},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Komputerowe wspomaganie tłumaczenia </h1>\n",
"<h2> 8. <i>Wykorzystanie tłumaczenia automatycznego we wspomaganiu tłumaczenia</i> [laboratoria]</h2> \n",
"<h3>Rafał Jaworski (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"id": "hungarian-davis",
"metadata": {},
"source": [
"W dzisiejszych czasach, niezwykle ważną techniką wspomagania tłumaczenia jest użycie tłumaczenia maszynowego. Tekst źródłowy do tłumaczenia jest najpierw tłumaczony całkowicie autommatycznie, a następnie tłumacz ludzki dokonuje korekty wyniku. Technologia tłumaczenia maszynowego jest już na tyle dojrzała, że oferuje bardzo wysoką jakość wyników. Coraz częstsze stają się scenariusze, w których ludzka korekta to niemal całkowicie machinalne (sic!) zatwierdzanie wyników tłumaczenia maszynowego. Na dzisiejszych zajęciach poznamy techniki ewaluacji tłumaczenia maszynowego oraz sprawdzania jego przydatności w procesie wspomagania tłumaczenia ludzkiego."
]
},
{
"cell_type": "markdown",
"id": "posted-commons",
"metadata": {},
"source": [
"Jakość tłumaczenia maszynowego możemy oceniać na dwóch niezależnych płaszczyznach: dokładność i płynność. Płynność jest subiektywnie odbieranym odczuciem, że czytany tekst jest napisany językiem naturalnym i zrozumiałym. Systemy tłumaczenia maszynowego oparte na uczeniu głębokim z wykorzystaniem sieci neuronowych osiągają duży stopień płynności tłumaczenia. Niestety jednak ich dokładność nie zawsze jest równie wysoka."
]
},
{
"cell_type": "markdown",
"id": "referenced-implement",
"metadata": {},
"source": [
"Dokładność tłumaczenia maszynowego jest parametrem, który łatwiej zmierzyć. Wartość takich pomiarów daje obraz tego, jaka jest faktyczna jakość tłumaczenia maszynowego i jaka jest jego potencjalna przydatność we wspomaganiu tłumaczenia."
]
},
{
"cell_type": "markdown",
"id": "disturbed-january",
"metadata": {},
"source": [
"Najczęściej stosowaną techniką oceny tłumaczenia maszynowego jest ocena BLEU. Do obliczenia tej oceny potrzebny jest wynik tłumaczenia maszynowego oraz referencyjne tłumaczenie ludzkie wysokiej jakości."
]
},
{
"cell_type": "markdown",
"id": "dental-combination",
"metadata": {},
"source": [
"### Ćwiczenie 1: Zaimplementuj program do obliczania oceny BLEU dla korpusu w folderze data. Użyj implementacji BLEU z pakietu nltk. Dodatkowe wymaganie techniczne - napisz program tak, aby nie musiał rozpakwowywać pliku zip z korpusem na dysku."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "moving-clothing",
"metadata": {},
"outputs": [],
"source": [
"def calculate_bleu():\n",
" return 0"
]
},
{
"cell_type": "markdown",
"id": "jewish-ethics",
"metadata": {},
"source": [
"### Ćwiczenie 2: Oblicz wartość bleu na różnych fragmentach przykładowego korpusu (np. na pierwszych 100 zdaniach, zdaniach 500-600). Czy w jakimś fragmencie korpusu jakość tłumaczenia znacząco odbiega od średniej?"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "lasting-rolling",
"metadata": {},
"outputs": [],
"source": [
"def analyze_bleu():\n",
" return []"
]
},
{
"cell_type": "markdown",
"id": "listed-bikini",
"metadata": {},
"source": [
"Inną metodą oceny jakości tłumaczenia maszynowego jest parametr WER - Word Error Rate. Definiuje się on w następujący sposób:\n",
"\n",
"$WER = \\frac{S+D+I}{N}=\\frac{S+D+I}{S+D+C}$\n",
"\n",
"gdzie:\n",
" * S - liczba substytucji (słów)\n",
" * D - liczba usunięć\n",
" * I - liczba wstawień\n",
" * C - liczba poprawnych śłów\n",
" * N - liczba słów w tłumaczeniu referencyjnym (N=S+D+C)"
]
},
{
"cell_type": "markdown",
"id": "conscious-cookbook",
"metadata": {},
"source": [
"Miara ta jest zwykle używana w do oceny systemów automatycznego rozpoznawania mowy, jednak w kontekście wspomagania tłumaczenia może być rozumiana jako wielkość nakładu pracy tłumacza nad poprawieniem tłumaczenia maszynowego."
]
},
{
"cell_type": "markdown",
"id": "split-palace",
"metadata": {},
"source": [
"### Ćwiczenie 3: Oblicz wartość WER dla przykładowego korpusu. Skorzystaj z gotowej implementacji WER."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "occupied-swing",
"metadata": {},
"outputs": [],
"source": [
"def calculate_wer():\n",
" return 0"
]
},
{
"cell_type": "markdown",
"id": "stretch-wound",
"metadata": {},
"source": [
"Poza wymienionymi powyżej, stosować można jeszcze inne miary oparte na porównywaniu tłumaczenia maszynowego z ludzkim. Przypomnijmy sobie jedną, którą stosowaliśmy wcześniej."
]
},
{
"cell_type": "markdown",
"id": "abstract-wilderness",
"metadata": {},
"source": [
"### Ćwiczenie 4: Oblicz średnią wartość dystansu Levenshteina pomiędzy zdaniami przetłumaczonymi automatycznie oraz przez człowieka. Użyj implementacji z ćwiczeń nr 2."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "immediate-element",
"metadata": {},
"outputs": [],
"source": [
"def calculate_levenshtein():\n",
" return 0"
]
},
{
"cell_type": "markdown",
"id": "filled-burton",
"metadata": {},
"source": [
"A teraz sprawdźmy coś jeszcze. W danych przykładowego korpusu znajduje się także angielski tekst źródłowy. Teoretycznie, dobre tłumaczenie niemieckie powinno zawierać jak najwięcej słów z angielskiego źródła. Wykonajmy najstępujący eksperyment:"
]
},
{
"cell_type": "markdown",
"id": "grateful-recruitment",
"metadata": {},
"source": [
"### Ćwiczenie 5: Dla każdej trójki zdań z korpusu przykładowego wykonaj następujące kroki:\n",
" * Przetłumacz każde angielskie słowo na niemiecki przy użyciu modułu PyDictionary.\n",
" * Sprawdź, które z niemieckich tłumaczeń zawiera więcej spośród tych przetłumaczonych słów - automatyczne, czy ludzkie.\n",
"Następnie wypisz statystyki zbiorcze. Które tłumaczenie zawiera więcej słownikowych tłumaczeń słów ze źródła?"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "descending-easter",
"metadata": {},
"outputs": [],
"source": [
"def analyze_translations():\n",
" return []"
]
}
],
"metadata": {
"author": "Rafał Jaworski",
"email": "rjawor@amu.edu.pl",
"lang": "pl",
"subtitle": "8. Wykorzystanie tłumaczenia automatycznego we wspomaganiu tłumaczenia",
"title": "Komputerowe wspomaganie tłumaczenia",
"year": "2021",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

264
lab/lab_09-10.ipynb Normal file

File diff suppressed because one or more lines are too long

214
lab/lab_11.ipynb Normal file
View File

@ -0,0 +1,214 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "expanded-entrance",
"metadata": {},
"source": [
"# Komputerowe wspomaganie tłumaczenia"
]
},
{
"cell_type": "markdown",
"id": "atlantic-greenhouse",
"metadata": {},
"source": [
"# Zajęcia 11 - urównoleglanie"
]
},
{
"cell_type": "markdown",
"id": "hungarian-davis",
"metadata": {},
"source": [
"Na poprzednich zajęciach poznaliśmy techniki pozyskiwania tekstu z Internetu. Jeśli uda nam się w ten sposób pozyskać tekst w jednym języku oraz jego tłumaczenie na inny język, jesteśmy tylko o krok od uzyskania najbardziej przydatnego zasobu z punktu widzenia wspomagania tłumaczenia - pamięci tłumaczeń. Krokiem tym jest automatyczne urównoleglanie tekstu."
]
},
{
"cell_type": "markdown",
"id": "bronze-removal",
"metadata": {},
"source": [
"Automatyczne urównoleglanie tekstu składa się z dwóch kroków:\n",
"1. Podziału tekstu źródłowego oraz docelowego na zdania.\n",
"2. Dopasowaniu zdań źródłowych do docelowych."
]
},
{
"cell_type": "markdown",
"id": "junior-works",
"metadata": {},
"source": [
"Zdania, o których mowa w punkcie 1., powinniśmy rozumieć jako segmenty, tj. niekoniecznie kompletne zdania w sensie gramatycznym. Standardowym sposobem podziału tekstu na segmenty jest dzielenie po znaku nowej linii lub zaraz po kropce, o ile jest ona częścią sekwencji: \".[spacja][Wielka litera]\""
]
},
{
"cell_type": "markdown",
"id": "legitimate-corrections",
"metadata": {},
"source": [
"### Ćwiczenie 1: Zaimplementuj podstawowy algorytm segmentacji tekstu. Użyj odpowiedniego wyrażenia regularnego, łapiącego wielkie litery w dowolnym języku, np. \"Ż\" (użyj klasy unikodowej). Zwróć listę segmentów."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "german-dispute",
"metadata": {},
"outputs": [],
"source": [
"def sentence_split(text):\n",
" return []"
]
</