KWT-2024/lab/lab_02.ipynb

12 KiB

Logo 1

Komputerowe wspomaganie tłumaczenia

2. Zaawansowane użycie pamięci tłumaczeń [laboratoria]

Rafał Jaworski (2021)

Logo 2

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.

Ć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.

Odpowiedź:

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.

Rozważmy przykładową pamięć tłumaczeń z poprzednich zajęć (można do niej dorzucić kilka przykładów):

translation_memory = [
                      ('Wciśnij przycisk Enter', 'Press the ENTER button'), 
                      ('Sprawdź ustawienia sieciowe', 'Check the network settings'),
                      ('Drukarka jest wyłączona', 'The printer is switched off'),
                      ('Wymagane ponowne uruchomienie komputera', 'System restart required')
                     ]

Ć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).

def ice_lookup(sentence, prev_sentence, next_sentence):
    return []

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.

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:

  1. $\forall_{x,y} d(x,y)\geqslant 0$
  2. $\forall_{x,y} d(x,y)=0 \Leftrightarrow x=y$
  3. $\forall_{x,y} d(x,y)=d(y,x)$
  4. $\forall_{x,y,z} d(x,y) + d(y,z)\geqslant d(x,z)$

Rozważmy następującą funkcję:

def sentence_distance(x,y):
    return abs(len(y) - len(x))

Ćwiczenie 3: Czy to jest poprawna funkcja dystansu? Które warunki spełnia?

Odpowiedź:

A teraz spójrzmy na taką funkcję:

def sentence_distance(x,y):
    if (x == y):
        return 0
    else:
        return 3

Ćwiczenie 4: Czy to jest poprawna funkcja dystansu? Które warunki spełnia?

Odpowiedź:

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:

  • dodanie znaku
  • usunięcie znaku
  • zamiana znaku na inny

Ćwiczenie 5: Czy dystans Levenshteina jest poprawną funkcją dystansu? Uzasadnij krótko swoją odpowiedź sprawdzając każdy z warunków.

Odpowiedź:

W Pythonie dostępna jest biblioteka zawierająca implementację dystansu Levenshteina. Zainstaluj ją w swoim systemie przy użyciu polecenia:

pip3 install python-Levenshtein

I wypróbuj:

from Levenshtein import distance as levenshtein_distance

levenshtein_distance("kotek", "kotki")
3

Funkcja ta daje nam możliwość zdefiniowania podobieństwa pomiędzy zdaniami:

def levenshtein_similarity(x,y):
    return 1 - levenshtein_distance(x,y) / max(len(x), len(y))

Przetestujmy ją!

levenshtein_similarity('Program jest uruchomiony', 'Program jest uruchamiany')
0.9166666666666666
levenshtein_similarity('Spróbuj wyłączyć i włączyć komputer', 'Spróbuj włączyć i wyłączyć komputer')
0.9428571428571428
levenshtein_similarity('Spróbuj wyłączyć i włączyć komputer', 'Nie próbuj wyłączać i włączać drukarki')
0.631578947368421

Ć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.

#!pip3 install python-Levenshtein
from Levenshtein import distance as levenshtein_distance

translation_memory = [
                      ('Wciśnij przycisk Enter', 'Press the ENTER button'),
                      ('Wciśnij przycisk ENTER', 'Press the ENTER button'), 
                      ('Wciśnij przycisk Enter!', 'Press the ENTER button!'), 
                      ('Wciśnij przycisk', 'Press the button'), 
                      ('Wciśnij Enter', 'Press the ENTER'), 
                      ('Sprawdź ustawienia sieciowe', 'Check the network settings'),
                      ('Drukarka jest wyłączona', 'The printer is switched off'),
                      ('Wymagane ponowne uruchomienie komputera', 'System restart required')
                     ]

def levenshtein_similarity(x,y):
    return 1 - levenshtein_distance(x,y) / max(len(x), len(y))

def fuzzy_lookup(sentence, threshold):
    for entry in translation_memory:
        part1 = entry[0]
        score = levenshtein_similarity(sentence, part1)
        if score >= threshold:
            print(sentence + ' -> ' + part1 + ' [ SCORE = ' + str(score) + ' ]')

fuzzy_lookup('Wciśnij przycisk Enter', 0.8)
Wciśnij przycisk Enter -> Wciśnij przycisk Enter [ SCORE = 1.0 ]
Wciśnij przycisk Enter -> Wciśnij przycisk ENTER [ SCORE = 0.8181818181818181 ]
Wciśnij przycisk Enter -> Wciśnij przycisk Enter! [ SCORE = 0.9565217391304348 ]