Traduciendo con Joshua! Necesitamos:
Corpus paralelo bilingual alineado a nivel de sentencias.
El corpus tiene que estar dividido en 3 partes una parte para entrenamiento (training), una pequeña parte para development (para optimización de los parametros), y una parte para testing (test)
normalmente el trainig es como 80% y las otras 2 partes 10% cada una, o un poco menos.
Estas tres partes tienen que ser disjuntas entre sí.
Supongamos que tenemos training.es, training.en dev.es, dev.en test.es, test.en como el coprpus bilingual alineado del español-inglés
Pasos:
- Tokenización:
Esto por lo general es simplemente dividir las palabras de los signos de puntuación,(en español, o en inglés, no en chino) pero puede llegar a hacer algo un poco más complejo, como ser dejar las siglas, etc.
Luego de ejecutar la tokenización sobre training.es y training.en, tendremos training.es.tok y training.en.tok
Ejecutandolo en dev y test obtenemos dev.es.tok, dev.en.tok test.es.tok, test.en.tok
- Normalización:
Es pasar a minúscula en los casos del español e inglés, también puede identificar las abreviaciones.
Guardamos las normalizaciones en training.es.tok.lc y training.en.tok.lc (lc=lower case)
Ejecutandolo en dev y test obtenemos dev.es.tok.lc, dev.en.tok.lc test.es.tok.lc, test.en.tok.lc
- Alineamientos de palabras:
Los alineamientos de palabras se pueden crear con Giza, con Berkeley aligner entre otros, aquí mostraremos con berkeleyAligner, ya que es una de las herramientas que hemos mostrado su instalación en la sección instalación.
suponga que el corpus de entrenamiento esta en es-en/training
cd es-en/training/
mkdir -p example/test (esto es porque berkeleyAligner lo requiere, aunque no tengamos datos adentro, es necesario crear la carpeta)
y luego haga:
nohup java -d64 -Xmx10g -jar $BERKELEYALIGNER/berkeleyaligner.jar ++word-align.conf &
NOTA: ponemos nohup porque esto puede tardar mucho, por ejemplo para el europarl tardó casi 2 días, también hay que notar que estamos asignando 10g, si usted dispone de más memoria puede reducir el tiempo de procesamiento, note tambié que ahí dice "-d64", si su máquina fuera de 32 bits, deberá poner "-d32"
donde $BERKELEYALIGNER es una variable de sesión donde esta el directorio donde instaló el alineador de Berkeley
export BERKELEYALIGNER=/home/usuario/berkeleyaligner
y el archivo word-align.conf es el siguiente:
click para ver word-align.conf
## word-align.conf
## ----------------------
## This is an example training script for the Berkeley
## word aligner. In this configuration it uses two HMM
## alignment models trained jointly and then decoded
## using the competitive thresholding heuristic.
##########################################
# Training: Defines the training regimen
##########################################
forwardModels MODEL1 HMM
reverseModels MODEL1 HMM
mode JOINT JOINT
iters 5 5
###############################################
# Execution: Controls output and program flow
###############################################
execDir alignments
create
saveParams true
numThreads 1
msPerLine 10000
alignTraining
#################
# Language/Data
#################
foreignSuffix es.tok.lc
englishSuffix en.tok.lc
# Choose the training sources, which can either be directories or files that list files/directories
trainSources training/
sentences MAX
#################
# 1-best output
#################
competitiveThresholding
- Entrenar el modelo del lenguaje destino (target) con srilm (también se puede entrenar con irstlm)
Para hacer esto necesitamos un corpus del lenguaje destino, aunque también podemos usar la parte del lenguaje destino de training del corpus bilingual alineado que tenemos
Necesitamos tener instalado SRILM (si no lo tiene instalado vea la página instalando srilm), y seteada la variable de entorno, para verificar si la tiene:
echo $SRILM
si no aparece nada
export SRILM=/home/usuario/srilm (es el path donde tiene instalado SRILM)
mkdir -p model/lm
$SRILM/bin/i686-m64depend/ngram-count -order 3 -unk -kndiscount1 -kndiscount2 -kndiscount3 -text training/training.en.tok.lc -lm model/lm/europarl.en.trigram.lm
i686-m64depend puede variar en su instalación, fíjese donde esta ngram-count en su instalación de srilm.
- Extraer la gramática de traducción
Para crear la gramática, antes necesitamos crear un vector de índices de sufijos (suffix array index) de la siguiente manera
java -Xmx10g -cp $JOSHUA/bin/ joshua.corpus.suffix_array.Compile training/europarl.es.tok.lc training/europarl.en.tok.lc aligments/training.en.tok.lc-es.tok.lc.align model
La salida va a ir al directorio model
ahora extraemos las reglas de la gramática del corpus dev
creamos el directorio mert dentro del directorio es-en
mkdir mert
java -Dfile.encoding=UTF8 -Xmx10g -cp $JOSHUA/bin joshua.prefix_tree.ExtractRules ./model mert/news-dev2009.es.tok.lc.grammar.raw dev/news-dev2009.es.tok.lc &
Luego ordenamos las reglas que acabamos de crear con
sort -u mert/news-dev2009.es.tok.lc.grammar.raw -o mert/news-dev2009.es.tok.lc.grammar
y creamos una (glue grammar) gramática que sirva de pegamento :) con el siguiente texto
hiero.glue (click para mostrar):
[S] ||| [X,1] ||| [X,1] ||| 0 0 0
[S] ||| [S,1] [X,2] ||| [S,1] [X,2] ||| 0.434294482 0 0
y la guardamos en model
- Ejecutar MERT (minimizar el error y maximizar la calidad de la traducción)
MERT usa bleu para optimizar en el corpus de dev
Para usar MERT necesitamos
- Un archivo de configuración para MERT
guardado en mert y con nombre mert.config
(click para mostrar):
### MERT parameters
# target sentences file name (in this case, file name prefix)
-r dev/news-dev2009.en.tok.lc
-rps 1 # references per sentence
-p mert/params.txt # parameter file
-m BLEU 4 closest # evaluation metric and its options
-maxIt 10 # maximum MERT iterations
-ipi 20 # number of intermediate initial points per iteration
-cmd mert/decoder_command # file containing commands to run decoder
-decOut mert/news-dev2009.output.nbest # file prodcued by decoder
-dcfg mert/joshua.config # decoder config file
-N 300 # size of N-best list
-v 1 # verbosity level (0-2; higher value => more verbose)
-seed 12341234 # random number generator seed
- Un archivo con la lista de razgos de las funciones usadas en el modelo con los posibles rangos
y guardelo en mert con el nombre params.txt
(click para mostrar):
lm ||| 1.000000 Opt 0.1 +Inf +0.5 +1.5
phrasemodel pt 0 ||| 1.066893 Opt -Inf +Inf -1 +1
phrasemodel pt 1 ||| 0.752247 Opt -Inf +Inf -1 +1
phrasemodel pt 2 ||| 0.589793 Opt -Inf +Inf -1 +1
wordpenalty ||| -2.844814 Opt -Inf +Inf -5 0
normalization = absval 1 lm
- Un archivo ejecutable conteniendo el comando para ejecutar el decoder
guárdelo en la carpeta mert y llámelo decoder_command
(click para mostrar):
java -Xmx1g -cp $JOSHUA/bin/ -Djava.library.path=$JOSHUA/lib -Dfile.encoding=utf8 \
joshua.decoder.JoshuaDecoder \
mert/joshua.config \
dev/news-dev2009.es.tok.lc \
mert/news-dev2009.output.nbest
- Un archivo con la configuración de Joshua
guárdelo en la carpeta mert con nombre joshua.config
(click to display):
lm_file=model/lm/europarl.en.trigram.lm
tm_file=mert/news-dev2009.es.tok.lc.grammar
tm_format=hiero
glue_file=model/hiero.glue
glue_format=hiero
#lm config
use_srilm=true
lm_ceiling_cost=100
use_left_equivalent_state=false
use_right_equivalent_state=false
order=3
#tm config
span_limit=10
phrase_owner=pt
mono_owner=mono
begin_mono_owner=begin_mono
default_non_terminal=X
goalSymbol=S
#pruning config
fuzz1=0.1
fuzz2=0.1
max_n_items=30
relative_threshold=10.0
max_n_rules=50
rule_relative_threshold=10.0
#nbest config
use_unique_nbest=true
use_tree_nbest=false
add_combined_cost=true
top_n=300
#remote lm server config, we should first prepare remote_symbol_tbl before starting any jobs
use_remote_lm_server=false
remote_symbol_tbl=./voc.remote.sym
num_remote_lm_servers=4
f_remote_server_list=./remote.lm.server.list
remote_lm_server_port=9000
#parallel deocoder: it cannot be used together with remote lm
num_parallel_decoders=1
parallel_files_prefix=/tmp/
###### model weights
#lm order weight
lm 1.0
#phrasemodel owner column(0-indexed) weight
phrasemodel pt 0 1.4037585111897322
phrasemodel pt 1 0.38379188013385945
phrasemodel pt 2 0.47752204361625605
#arityphrasepenalty owner start_arity end_arity weight
#arityphrasepenalty pt 0 0 1.0
#arityphrasepenalty pt 1 2 -1.0
#phrasemodel mono 0 0.5
#wordpenalty weight
wordpenalty -2.721711092619053
Luego ejecute el comando para iniciar MERT
nohup java -cp $JOSHUA/bin joshua.zmert.ZMERT -maxMem 1500 mert/mert.config &
- Decodificar el corpus de test
Cuando MERT finalice habrá creado un archivo joshua.config.ZMERT.final en la carpeta mert, este archivo contiene los nuevos pesos aprendidos, copie este archivo y úselo para decodificar el corpus de test.
Primero extraiga la gramática del corpus de test
java -Dfile.encoding=UTF8 -Xmx1g -cp $JOSHUA/bin joshua.prefix_tree.ExtractRules ./model test/newstest2009.es.tok.lc.grammar.raw test/newstest2009.es.tok.lc &
ordénela con
sort -u test/newstest2009.es.tok.lc.grammar.raw /o test/newstest2009.es.tok.lc.grammar
cp mert/joshua.config.ZMERT.final test/joshua.config
Reemplace tm_file=mert/mert/news-dev2009.es.tok.lc.grammar con tm_file=test/newstest2009.es.tok.lc.grammar
java -Xmx1g -cp $JOSHUA/bin/ -Djava.library.path=$JOSHUA/lib -Dfile.encoding=utf8 joshua.decoder.JoshuaDecoder test/joshua.config test/newstest2009.es.tok.lc test/newstest2009.output.nbest
java -cp $JOSHUA/bin -Dfile.encoding=utf8 joshua.util.ExtractTopCand test/newstest2009.output.nbest test/newstest2009.output.1best
- Restaure mayúsculas y la tokenización
$SRILM/bin/i386-m64depend/ngram-count -unk -order 5 -kndiscount1 -kndiscount2 -kndiscount3 -kndiscount4 -kndiscount5 -text training/training.en.tok -lm model/lm/training.TrueCase.5gram.lm
#!/usr/bin/perl
#
# truecase-map.perl
# -----------------
# This script outputs alternate capitalizations
%map = ();
while($line = <>) {
@words = split(/\s+/, $line);
foreach $word (@words) {
$key = lc($word);
$map{$key}{$word} = 1;
}
}
foreach $key (sort keys %map) {
@words = keys %{$map{$key}};
if(scalar(@words) > 1 || !($words[0] eq $key)) {
print $key;
foreach $word (sort @words) {
print " $word";
}
print "\n";
}
}
cat training/training.en.tok | perl truecase-map.perl > model/lm/true-case.map
$SRILM/bin/macosx/disambig -lm model/lm/training.TrueCase.5gram.lm -keep-unk -order 5 -map model/lm/true-case.map -text test/mt09.output.1best | perl strip-sent-tags.perl> test/mt09.output.1best.recased
while($line = <>) {
$line =~ s/^\s*< s>\s*//g;
$line =~ s/\s*<\ /s>\s*$//g;
print $line . "\n";
}
- Ordene según score las traducciones
java -cp $JOSHUA/bin -Djava.library.path=lib -Xmx1000m -Xms1000m -Djava.util.logging.config.file=logging.properties joshua.util.JoshuaEval -cand dev/dev2006.en.output -ref dev/dev2006.en.small -m BLEU 4 closest
|
|