KWT-2024/lab/lab_03.ipynb
2024-04-15 21:15:24 +02:00

18 KiB

Logo 1

Komputerowe wspomaganie tłumaczenia

3. Terminologia [laboratoria]

Rafał Jaworski (2021)

Logo 2

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.

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:

  • Teksty o tematyce ogólnej są tłumaczone dość rzadko (nikt nie tłumaczy pocztówek z pozdrowieniami z wakacji...)
  • Te same słowa mogą mieć zarówno znaczenie ogólne, jak i bardzo specjalistyczne (np. "dziedziczenie" w kontekście prawnym lub informatycznym)
  • Klient używa nazw lub słów wymyślonych przez siebie, np. na potrzeby marketingowe.

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

Brzmi prosto? Spróbujmy wykonać ręcznie tę drugą operację.

Ćwiczenie 1: Podaj tłumaczenie terminu "prowadnice szaf metalowych" na język angielski. Opisz, z jakich narzędzi skorzystałaś/eś.

Odpowiedź: metal cabinet guides lub metal cabinet slides. Skorzystalem z dwoch slownikow oraz duzego modelu jezykowego.

W dalszych ćwiczeniach skupimy się jednak na odszukaniu terminu specjalistycznego w tekście. W tym celu będą potrzebne dwie operacje:

  1. Przygotowanie słownika specjalistycznego.
  2. Detekcja terminologii przy użyciu przygotowanego słownika specjalistycznego.

Zajmijmy się najpierw krokiem nr 2 (gdyż jest prostszy). Rozważmy następujący tekst:

text = " For all Java programmers:"
text += " This section explains how to compile and run a Swing application from the command line."
text += " For information on compiling and running a Swing application using NetBeans IDE,"
text += " see Running Tutorial Examples in NetBeans IDE. The compilation instructions work for all Swing programs"
text += " — applets, as well as applications. Here are the steps you need to follow:"
text += " Install the latest release of the Java SE platform, if you haven't already done so."
text += " Create a program that uses Swing components. Compile the program. Run the program."

Załóżmy, że posiadamy następujący słownik:

dictionary = ['program', 'application', 'applet', 'compile']

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

import re

def terminology_lookup(txt, labels):
    results = []

    for label in labels:
        results.append((
            label,
             [(m.start(), m.end() - 1) for m in re.finditer(label, txt)]
        ))

    return results
terminology_lookup(text, dictionary)
[('program', [(14, 20), (291, 297), (468, 474), (516, 522), (533, 539)]),
 ('application', [(80, 90), (164, 174), (322, 332)]),
 ('applet', [(302, 307)]),
 ('compile', [(56, 62)])]

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.

Żeby poradzić sobie z tymi problemami, musimy wykorzystać techniki przetwarzania języka naturalnego. Wypróbujmy pakiet spaCy:

pip3 install spacy

oraz

python3 -m spacy download en_core_web_sm

import spacy
nlp = spacy.load("en_core_web_sm")

doc = nlp(text)

for token in doc:
    print(token, token.lemma_, token.idx)
    0
For for 1
all all 5
Java Java 9
programmers programmer 14
: : 25
This this 27
section section 32
explains explain 40
how how 49
to to 53
compile compile 56
and and 64
run run 68
a a 72
Swing swing 74
application application 80
from from 92
the the 97
command command 101
line line 109
. . 113
For for 115
information information 119
on on 131
compiling compile 134
and and 144
running run 148
a a 156
Swing swing 158
application application 164
using use 176
NetBeans NetBeans 182
IDE IDE 191
, , 194
see see 196
Running run 200
Tutorial Tutorial 208
Examples Examples 217
in in 226
NetBeans NetBeans 229
IDE IDE 238
. . 241
The the 243
compilation compilation 247
instructions instruction 259
work work 272
for for 277
all all 281
Swing Swing 285
programs program 291
— — 300
applets applet 302
, , 309
as as 311
well well 314
as as 319
applications application 322
. . 334
Here here 336
are be 341
the the 345
steps step 349
you you 355
need need 359
to to 364
follow follow 367
: : 373
Install install 375
the the 383
latest late 387
release release 394
of of 402
the the 405
Java Java 409
SE SE 414
platform platform 417
, , 425
if if 427
you you 430
have have 434
n't not 438
already already 442
done do 450
so so 455
. . 457
Create create 459
a a 466
program program 468
that that 476
uses use 481
Swing swing 486
components component 492
. . 502
Compile compile 504
the the 512
program program 516
. . 523
Run run 525
the the 529
program program 533
. . 540

Sukces! Nastąpił podział tekstu na słowa (tokenizacja) oraz sprowadzenie do formy podstawowej każdego słowa (lematyzacja).

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

import spacy
nlp = spacy.load("en_core_web_sm")


def terminology_lookup(txt, labels):
    result = {};
    doc = nlp(txt)

    for token in doc:
        if token.lemma_ in labels: 
            if token.lemma_ not in result:
                result[token.lemma_] = []
            result[token.lemma_].append((token.idx, token.idx + len(token)))

    return result
terminology_lookup(text, dictionary)
{'compile': [(56, 63), (134, 143), (504, 511)],
 'application': [(80, 91), (164, 175), (322, 334)],
 'program': [(291, 299), (468, 475), (516, 523), (533, 540)],
 'applet': [(302, 309)]}

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.

Przyjmijmy następujące podejście - terminami specjalistycznymi będą najcześćiej występujące rzeczowniki w tekście. Wykonajmy krok pierwszy:

Ćwiczenie 4: Wypisz wszystkie rzeczowniki z tekstu. Wykorzystaj możliwości spaCy.

def get_nouns(text):
    doc = nlp(text)
    return [token.lemma_ for token in doc if token.pos_ == 'NOUN']
get_nouns(text)
['programmer',
 'section',
 'swing',
 'application',
 'command',
 'line',
 'information',
 'swing',
 'application',
 'compilation',
 'instruction',
 'program',
 'applet',
 'application',
 'step',
 'release',
 'platform',
 'program',
 'swing',
 'component',
 'program',
 'program']

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:

tally = {"program" : 4, "component" : 1}

Ćwiczenie 5: Napisz program do ekstrakcji terminologii z tekstu według powyższych wytycznych.

def count_words(words):
    word_count = {}
    for word in words:
        if word in word_count:
            word_count[word] += 1
        else:
            word_count[word] = 1
    return word_count

def extract_terms(text):
    return count_words(get_nouns(text))
extract_terms(text)
{'programmer': 1,
 'section': 1,
 'swing': 3,
 'application': 3,
 'command': 1,
 'line': 1,
 'information': 1,
 'compilation': 1,
 'instruction': 1,
 'program': 4,
 'applet': 1,
 'step': 1,
 'release': 1,
 'platform': 1,
 'component': 1}

Ćwiczenie 6: Rozszerz powyższy program o ekstrację czasowników i przymiotników.

def get_verbs(text):
    doc = nlp(text)
    return [token.lemma_ for token in doc if token.pos_ == 'VERB']

def get_adjectives(text):
    doc = nlp(text)
    return [token.lemma_ for token in doc if token.pos_ == 'ADJ']

def extract_terms(text):
    return {
        "nouns": get_nouns(text),
        "verbs": get_verbs(text),
        "adjectives": get_adjectives(text)
    }
extract_terms(text)
{'nouns': ['programmer',
  'section',
  'swing',
  'application',
  'command',
  'line',
  'information',
  'swing',
  'application',
  'compilation',
  'instruction',
  'program',
  'applet',
  'application',
  'step',
  'release',
  'platform',
  'program',
  'swing',
  'component',
  'program',
  'program'],
 'verbs': ['explain',
  'compile',
  'run',
  'compile',
  'run',
  'use',
  'see',
  'run',
  'work',
  'need',
  'follow',
  'install',
  'do',
  'create',
  'use',
  'compile',
  'run'],
 'adjectives': ['late']}