{ "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", "
\n", "

Komputerowe wspomaganie tłumaczenia

\n", "

1. Podstawowe techniki wspomagania tłumaczenia [laboratoria]

\n", "

Rafał Jaworski (2021)

\n", "
\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": 2, "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": 3, "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": 4, "id": "compact-trinidad", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Press the ENTER button']" ] }, "execution_count": 4, "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": 5, "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": 6, "id": "serial-velvet", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Press the ENTER button', 'Press the ENTER key']" ] }, "execution_count": 6, "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": 9, "id": "every-gibson", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 9, "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": 11, "id": "protected-rings", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Press the ENTER button', 'Press the ENTER key']" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def tm_lookup(sentence):\n", " return [entry[1] for entry in translation_memory if entry[0].lower() == sentence.lower()]\n", "\n", "tm_lookup('Wciśnij przycisk ENTER')" ] }, { "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": 8, "id": "severe-alloy", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 8, "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": 16, "id": "structural-diesel", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Press the ENTER button', 'Press the ENTER key']" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import string\n", "\n", "def tm_lookup(sentence):\n", " sentence = sentence.translate(str.maketrans('', '', string.punctuation))\n", " return [entry[1] for entry in translation_memory if entry[0].lower() == sentence.lower()]\n", "\n", "tm_lookup('Wciśnij przycisk [ENTER]')" ] }, { "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": 17, "id": "brief-senegal", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 17, "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": 26, "id": "mathematical-customs", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Suggestion:\n" ] }, { "data": { "text/plain": [ "['System restart required']" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def differenceThanNotBiggerThanOneElement(firstSentence, secondSentence):\n", " firstSentenceList = firstSentence.lower().split()\n", " secondSentenceList = secondSentence.lower().split()\n", "\n", " diffNumber = 0\n", "\n", " for i in range(len(firstSentenceList)):\n", " if(firstSentenceList[i] != secondSentenceList[i]):\n", " diffNumber=diffNumber+1\n", " if(diffNumber > 2):\n", " return False\n", "\n", " return True\n", "\n", "def tm_lookup(sentence):\n", " sentence = sentence.translate(str.maketrans('', '', string.punctuation))\n", "\n", " exactMatchList = [entry[1] for entry in translation_memory if entry[0].lower() == sentence.lower()]\n", "\n", " if(len(exactMatchList) == 0):\n", " diffMatchList = [entry[1] for entry in translation_memory if differenceThanNotBiggerThanOneElement(entry[0], sentence)]\n", "\n", " if(len(diffMatchList) > 0):\n", " print('Suggestion:')\n", " return diffMatchList\n", "\n", " else:\n", " return exactMatchList\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", "\n", "tm_lookup('Wymagane ponowne uruchomienie maszyny')" ] }, { "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": 27, "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": 28, "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": 29, "id": "advised-casting", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('przycisk', 'button'), ('drukarka', 'printer')]" ] }, "execution_count": 29, "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ź: O(n * m)" ] }, { "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": 34, "id": "original-tunisia", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def glossary_lookup(sentence):\n", " sentence_words = sentence.lower().split()\n", " return [entry for entry in glossary if entry[0] in sentence_words]\n", "\n", "glossary_lookup('Każda Drukarka posiada Przycisk wznowienia drukowania')" ] }, { "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": 35, "id": "adolescent-semiconductor", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('przycisk', 'button'), ('drukarka', 'printer')]" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def glossary_lookup(sentence):\n", " sentence_words = set(sentence.lower().split())\n", " return [entry for entry in glossary if entry[0] in sentence_words]\n", "\n", "glossary_lookup('Każda Drukarka posiada Przycisk wznowienia drukowania')" ] } ], "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.11.7" }, "subtitle": "1. Podstawowe techniki wspomagania tłumaczenia", "title": "Komputerowe wspomaganie tłumaczenia", "year": "2021" }, "nbformat": 4, "nbformat_minor": 5 }