398 lines
15 KiB
Plaintext
398 lines
15 KiB
Plaintext
{
|
|
"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": 2,
|
|
"id": "d4f068df",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/opt/anaconda3/lib/python3.11/site-packages/nltk/translate/bleu_score.py:552: UserWarning: \n",
|
|
"The hypothesis contains 0 counts of 3-gram overlaps.\n",
|
|
"Therefore the BLEU score evaluates to 0, independently of\n",
|
|
"how many N-gram overlaps of lower order it contains.\n",
|
|
"Consider using lower n-gram order or use SmoothingFunction()\n",
|
|
" warnings.warn(_msg)\n",
|
|
"/opt/anaconda3/lib/python3.11/site-packages/nltk/translate/bleu_score.py:552: UserWarning: \n",
|
|
"The hypothesis contains 0 counts of 4-gram overlaps.\n",
|
|
"Therefore the BLEU score evaluates to 0, independently of\n",
|
|
"how many N-gram overlaps of lower order it contains.\n",
|
|
"Consider using lower n-gram order or use SmoothingFunction()\n",
|
|
" warnings.warn(_msg)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"3.984587822441638e-156"
|
|
]
|
|
},
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"import zipfile\n",
|
|
"import nltk.translate.bleu_score as bleu\n",
|
|
"import string\n",
|
|
"\n",
|
|
"def remove_punctuation(text):\n",
|
|
" text_without_punctuations = text.translate(str.maketrans('', '', string.punctuation))\n",
|
|
" sentences = text_without_punctuations.split('\\n')\n",
|
|
" return [[word.lower() for word in sentence.split()] for sentence in sentences if sentence != '']\n",
|
|
"\n",
|
|
"def calculate_bleu():\n",
|
|
" zip = zipfile.ZipFile('data/corpus_corrected.zip')\n",
|
|
" files = {name: remove_punctuation(zip.read(name).decode('utf-8'))\n",
|
|
" for name in zip.namelist()}\n",
|
|
" \n",
|
|
" corpus_de_human, corpus_de_nmt = files['corpus_de_human.txt'], files['corpus_de_nmt.txt']\n",
|
|
" \n",
|
|
" return bleu.corpus_bleu(corpus_de_human, corpus_de_nmt)\n",
|
|
"\n",
|
|
"calculate_bleu()"
|
|
]
|
|
},
|
|
{
|
|
"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": 3,
|
|
"id": "lasting-rolling",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"0 to 100 - 4.97555004481153e-232\n",
|
|
"500 to 600 - 5.956707985683837e-232\n",
|
|
"800 to 900 - 4.774461089627919e-232\n",
|
|
"200 to 300 - 5.56331772444502e-232\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/opt/anaconda3/lib/python3.11/site-packages/nltk/translate/bleu_score.py:552: UserWarning: \n",
|
|
"The hypothesis contains 0 counts of 2-gram overlaps.\n",
|
|
"Therefore the BLEU score evaluates to 0, independently of\n",
|
|
"how many N-gram overlaps of lower order it contains.\n",
|
|
"Consider using lower n-gram order or use SmoothingFunction()\n",
|
|
" warnings.warn(_msg)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"\n",
|
|
"def analyze_bleu(start_sentence_index, finish_sentence_index):\n",
|
|
" zip = zipfile.ZipFile('data/corpus_corrected.zip')\n",
|
|
" files = {name: remove_punctuation(zip.read(name).decode('utf-8'))\n",
|
|
" for name in zip.namelist()}\n",
|
|
" \n",
|
|
" corpus_de_human, corpus_de_nmt = files['corpus_de_human.txt'][start_sentence_index:finish_sentence_index], files['corpus_de_nmt.txt'][start_sentence_index:finish_sentence_index]\n",
|
|
" \n",
|
|
" return bleu.corpus_bleu(corpus_de_human, corpus_de_nmt)\n",
|
|
"\n",
|
|
"\n",
|
|
"print(\"0 to 100 - \"+str(analyze_bleu(0, 100)))\n",
|
|
"print(\"500 to 600 - \"+str(analyze_bleu(500, 600)))\n",
|
|
"print(\"800 to 900 - \"+str(analyze_bleu(800, 900)))\n",
|
|
"print(\"200 to 300 - \"+str(analyze_bleu(200, 300)))\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"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": "fb4f02ae",
|
|
"metadata": {},
|
|
"source": []
|
|
},
|
|
{
|
|
"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": 25,
|
|
"id": "occupied-swing",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0.17355216569308377"
|
|
]
|
|
},
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from jiwer import wer\n",
|
|
"import zipfile\n",
|
|
"\n",
|
|
"def calculate_wer():\n",
|
|
" ourZip = zipfile.ZipFile('data/corpus_corrected.zip')\n",
|
|
" files = {name: remove_punctuation(ourZip.read(name).decode('utf-8'))\n",
|
|
" for name in ourZip.namelist()}\n",
|
|
" \n",
|
|
" corpus_de_human, corpus_de_nmt = files['corpus_de_human.txt'], files['corpus_de_nmt.txt']\n",
|
|
"\n",
|
|
" sum_wer = 0\n",
|
|
" for human_sent, nmt_sent in zip(corpus_de_human, corpus_de_nmt):\n",
|
|
" sum_wer+= wer(\" \".join(human_sent), \" \".join(nmt_sent))\n",
|
|
"\n",
|
|
" return sum_wer/(len(corpus_de_human))\n",
|
|
"\n",
|
|
"calculate_wer()"
|
|
]
|
|
},
|
|
{
|
|
"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": 35,
|
|
"id": "immediate-element",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"2.653"
|
|
]
|
|
},
|
|
"execution_count": 35,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"import Levenshtein\n",
|
|
"\n",
|
|
"def calculate_levenshtein():\n",
|
|
" ourZip = zipfile.ZipFile('data/corpus_corrected.zip')\n",
|
|
" files = {name: remove_punctuation(ourZip.read(name).decode('utf-8'))\n",
|
|
" for name in ourZip.namelist()}\n",
|
|
" \n",
|
|
" corpus_de_human, corpus_de_nmt = files['corpus_de_human.txt'], files['corpus_de_nmt.txt']\n",
|
|
"\n",
|
|
" sum_disatnce = 0\n",
|
|
" for human_element, nmt_element in zip(corpus_de_human, corpus_de_nmt):\n",
|
|
" sum_disatnce+= Levenshtein.distance(human_element, nmt_element)\n",
|
|
"\n",
|
|
" return sum_disatnce/(len(corpus_de_human))\n",
|
|
"\n",
|
|
"calculate_levenshtein()\n"
|
|
]
|
|
},
|
|
{
|
|
"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": 4,
|
|
"id": "descending-easter",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from PyDictionary import PyDictionary\n",
|
|
"import zipfile\n",
|
|
"import re\n",
|
|
"\n",
|
|
"def transalate(word_list):\n",
|
|
" transalted_words = {}\n",
|
|
" for word in word_list:\n",
|
|
" try:\n",
|
|
" translation = PyDictionary().translate(word, 'German')\n",
|
|
" if translation:\n",
|
|
" transalted_words[word] = translation\n",
|
|
" except Exception as e:\n",
|
|
" print('Exception')\n",
|
|
"\n",
|
|
" return transalted_words\n",
|
|
"\n",
|
|
"def analyze_translations():\n",
|
|
" ourZip = zipfile.ZipFile('data/corpus_corrected.zip')\n",
|
|
" files = {name: remove_punctuation(ourZip.read(name).decode('utf-8'))\n",
|
|
" for name in ourZip.namelist()}\n",
|
|
" \n",
|
|
" corpus_de_human, corpus_de_nmt, corpus_en = files['corpus_de_human.txt'], files['corpus_de_nmt.txt'], files['corpus_en.txt']\n",
|
|
"\n",
|
|
" nmt_sum = 0\n",
|
|
" human_sum = 0\n",
|
|
"\n",
|
|
" for human_element, nmt_element, element in zip(corpus_de_human, corpus_de_nmt, corpus_en):\n",
|
|
" transalted_words = transalate(element)\n",
|
|
"\n",
|
|
" nmt_sum += sum(1 for word in nmt_element if transalted_words.get(word.lower()))\n",
|
|
"\n",
|
|
" human_sum += sum(1 for word in human_element if transalted_words.get(word.lower()))\n",
|
|
"\n",
|
|
"\n",
|
|
" print(nmt_sum)\n",
|
|
" print(human_sum)\n",
|
|
"\n",
|
|
"#I think the PyDictionary mode doesn't work, the info from https://github.com/geekpradd/PyDictionary\n",
|
|
"#NOTE: Mainintaing this module requires constantly changing the scrapping endpoints which unfortunately I no longer have the bandwidth to do so, so this module is DEPRECATED. Kindly use other substitutes available on PyPI. Thanks!\n",
|
|
"#PyDictionary is a Dictionary Module for Python 2/3 to get meanings, translations, synonyms and Antonyms of words. It uses WordNet for getting meanings, Google for translations, and synonym.com for getting synonyms and antonyms.\n",
|
|
"#This module uses Python Requests, BeautifulSoup4 and goslate as dependencies\n",
|
|
" \n"
|
|
]
|
|
}
|
|
],
|
|
"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": "8. Wykorzystanie tłumaczenia automatycznego we wspomaganiu tłumaczenia",
|
|
"title": "Komputerowe wspomaganie tłumaczenia",
|
|
"year": "2021"
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|