Versuch 3: Lösungen

Aufgabe 3.1 a):

 

Frage: Kann die Wortakkuratheit negativ werden? Kann sie einen Wert über 100% annehmen? Wenn ja, geben Sie je einen Beispielfall an.

 

Antwort: Klar kann sie negativ werden, wenn mehr Fehler gemacht werden als Worte zu erkennen sind (d.h. daß mindestens ein Einfügefehler gemacht wird). Z.B. zu erkennen: Hello World, erkannt one two three, das sind drei Fehler, bei zwei zu erkennenden Wötern, also eine Fehlerrate von 150% und somit eine Wortakkuratheit von 100% - 150% = -50%.

Die Wortakkuratheit kann nie mehr als 100% sein, besser als alles richtig erkennen, kann man es nicht machen.

 

Aufgabe 3.1 b):

Frage: Kann bei einem Satz/Hypothese-Paar, die minimale Wortfehlerrate auf verschiedene Arten (verschiedene Zusammensetzung der Fehlerarten) entstehen?

 

Antwort: Ja, das kann schon sein. Wenn jeder Fehler gleich viel zählt, dann kann z.B. immer wenn die Fehlerfolge "Vertauschung, Einfügung" auch "Einfügung, Vertauschung" gewält werden.

Auch andere Varianten sind machbar, die Anteile der einzelnen Fehlerrarten an der minimalen Wortfehlerrate bleibt aber gleich.

 

Aufgabe 3.1 c):

Schreiben Sie ein Tcl-Script align.tcl, das als Eingabe zwei Listen (erste Liste ist die zu erkennende Wortfolge, zweite Liste ist die erkannte Wortfolge) erhält und als Ausgabe die Wortfehlerrate angibt.

 

Antwort: Schöne Lösung einer Gruppe aus einem der vorherigen Jahrgänge:

#=======================================================================
#  JANUS-SR   Janus Speech Recognition Toolkit
# ----------------------------------------------------------
#  Author  :  Matthias und Roald: Gruppe 3
#  Module  :  align.tcl
#  Date    :  30.10.97
#
#  Remarks :  Script for exercise 3.1c.
#             Computes word error rate of a hypothesis against a
#             reference utterance, using DTW (Viterbi) algorithm.
#
#======================================================================

# The return value is a list of the following form:
#   {errorRate numErrors alignList errorList}
# errorList contains for every word of the hypothesis the error(s)
# detected between this word and its predecessor:
#   d# : # deletions
#   i  : insertion
#   s  : substitution
#   -  : no error
# Note that d# may be combined with s,-: d#s => # deletions, followed by a
# subst. d#- => # deletions, followed by correct word.
# Note that there may be more than one possible best alignments, but  
# only
# one of these is returned.
# Note that the reference as well as the hypothesis must contain at least
# one word!

proc wordErrorRate {reference hypothesis} {
    ;# note that START and END also belong to reference and hypothesis
    set reference [linsert $reference 0 "..START.."]
    lappend reference "..END.."
    set reflen [llength \$reference]
    set index 0
    ;# indexing reference words
    foreach elem $reference {
        set refarray([expr \$reflen - 1 - \$index]) \$elem
        incr index
    }
    ;# Initialize actual vector (diagram column)
    set hypword [lindex \$hypothesis 0]
    set colnum [llength \$hypothesis]
    for {set index 0} {\$index < (\$reflen - 1)} {incr index} {
        set value [expr \$reflen - 2 - \$index]
        set actvec(\$index) \$value
        if {\$value > 0} {
            set eType "d\$value"
        } else {set eType ""}
        set refword $refarray(\$index)
        if {[string compare \$refword \$hypword]} {
            incr actvec(\$index)
            append eType s
        } else {append eType -}
        set backtrack(\$colnum,\$index) [expr \$reflen - 1]
        set errorType(\$colnum,\$index) \$eType
    }
    set index [expr \$reflen - 1]
    set actvec(\$index) 1
    set backtrack(\$colnum,\$index) \$index
    set errorType(\$colnum,\$index) i
    incr colnum -1
    ;# main loop: steps through hypothesis list

    foreach hypword [lreplace \$hypothesis 0 0] {
        for {set index 0} {\$index < \$reflen} {incr index} {
            set minvalue [expr \$actvec(\$index) + 1]
            set minindex \$index
            set mineType i
            if {[string compare \$refarray(\$index) \$hypword]} {
                set offset 1
            } else {
                set offset 0
            }
            for {set j [expr \$index + 1]} {\$j < $reflen} {incr j} {
                set delet [expr \$j - \$index - 1]
                set value [expr \$actvec(\$j) + \$offset + \$delet]
                if {\$value < \$minvalue} {
                    set minvalue \$value
                    set minindex \$j
                    if {\$delet > 0} {set mineType d\$delet} else {
                        set mineType ""
                    }
                    if {\$offset == 1} {append mineType s} else {
                        append mineType -
                    }
                }
            }
            set actvec(\$index) \$minvalue
            set backtrack(\$colnum,\$index) \$minindex  ;# backtrack. link
            set errorType(\$colnum,\$index) \$mineType
        }
        incr colnum -1
    }
    ;# last step
    set minvalue [expr \$actvec(0) + 1]
    set minindex 0
    for {set j 1} {\$j < \$reflen} {incr j} {
        set value [expr \$actvec(\$j) + \$j - 1]
        set delet [expr \$j - 1]
        if {\$value < \$minvalue} {
            set minvalue \$value
            set minindex \$j
            if {\$delet > 0} {set mineType d\$delet} else {
                set mineType ""
            }
        }
    }
    ;# backtracking
    set alignlist {}
    if {[string length \$mineType] > 0} {
        set errorlist [list \$mineType]
    } else {set errorlist {}}
    for {set colnum 1} {\$colnum <= [llength \$hypothesis]} {incr colnum} {
        set alignlist [linsert \$alignlist 0 \$refarray(\$minindex)]
        set mineType \$errorType(\$colnum,\$minindex)
        set errorlist [linsert \$errorlist 0 \$mineType]
        set minindex \$backtrack(\$colnum,\$minindex)
    }
    return [list [expr 1.00*\$minvalue/(\$reflen-2)] \$minvalue \$alignlist \$errorlist]
}

# Test

set reference {Guten Morgen es ist viertel vor sechs}
set hypothesis {Puten Morgen ist vierte vor sie sechs}
puts "Reference: \$reference\nHypothesis: \$hypothesis"
set res [wordErrorRate \$reference \$hypothesis]
puts "Word error rate = [lindex \$res 0] ([lindex \$res 1] errors)."
puts "Reached with alignment: [lindex \$res 2]"
puts "Corr. error sequence: [lindex \$res 3]"

Aufgabe 3.2:

 

Erzeugen Sie eine Janus Datenbasis, die für jeden Satz einen Eintrag enthält ...

Antwort: (wieder von einer Gruppe aus den Vorjahren)

 

#=======================================================================

#  JANUS-SR   Janus Speech Recognition Toolkit
# -----------------------------------------------------------
#  Author  :  Matthias und Roald: Gruppe 3
#  Module  :  makeDBase.tcl
#  Date    :  2.11.97
#
#  Remarks :  ---
#
#=======================================================================
# arbeitet auf Datei vormots im Homeverzeichnis
# diese wurde wie folgt erstellt: tr -d '.,\!?"' | tr 'A-Z' 'a-z'
# < ..bref/cprompts.iso > vormots


if { \$argc != 1 || [lindex \$argv 1] == "-help"} {
      puts stderr "USAGE: \$argv0 'textfile'"
      exit
}
set filename [lindex \$argv 0]
if [catch {open \$filename r} inputfile] {
    puts stderr "Datei nicht gefunden."
    exit
}

# ---------------------
#  DBase-Objekt anlegen
# ---------------------

DBase db
db open db.dat db.idx -mode rwc

while {[gets \$inputfile line]>=0} {
    set eintrag {}
    set id [lindex \$line [expr [llength \$line] -1]]
    set speaker "spk "
    lappend speaker [string range \$id 1 2]
    lappend eintrag \$speaker
    set sex "sex "
    lappend sex [string range \$id 3 3]
    lappend eintrag \$sex
    set typ "type "
    lappend typ [string range \$id 4 4]
    lappend eintrag \$typ
    set num "num "
    lappend num [string range \$id 5 8]
    lappend eintrag \$num
    set aussage "text "
    for { set i 0} {\$i<[expr [llength \$line]-1] } {incr i 1} {
        lappend aussage [lindex \$line \$i]
    }
    lappend eintrag \$aussage
   
    # Eintrag in die DBase
    db add \$id \$eintrag
        
}
db close
close \$inputfile

exit


Aufgabe 3.3: Entwerfen Sie für die 30 am häufigsten vorkommenden Wörter, die nicht im Aussprachelexikon stehen, eine Phonemsequenz.

 

Antwort: Darüber, wie ein Wort richtig ausgesprochen wird, läßt sich streiten (sogar unter Franzosen). Z.B. so:

ans             o^
autres          o>tre
avait           av&
c'est           s{t
d'autres        do>tre
d'un            dy^
d'une           dyn
dit             di
faut            fo>
font            fo^
france          fra^s
grande          gra^de
grands          gra^
j'ai            j&
jours           Jur
mr              me/sjEU
n'a             na
n'est           n{t
ont             o^
paris           pari
peut            pEU
premiere        premj&re
qu'il           kil
quelques        k{lke
s'est           s{t
seront          sero^
sont            so^
veut            vEU
itaient         {t&
itait           {t&