# -*- coding: UTF-8 -*-
def wer(ref, hyp ,debug=False):
r = ref.split()
h = hyp.split()
#costs will holds the costs, like in the Levenshtein distance algorithm
costs = [[0 for inner in range(len(h)+1)] for outer in range(len(r)+1)]
# backtrace will hold the operations we've done.
# so we could later backtrace, like the WER algorithm requires us to.
backtrace = [[0 for inner in range(len(h)+1)] for outer in range(len(r)+1)]
OP_OK = 0
OP_SUB = 1
OP_INS = 2
OP_DEL = 3
DEL_PENALTY=1 # Tact
INS_PENALTY=1 # Tact
SUB_PENALTY=1 # Tact
# First column represents the case where we achieve zero
# hypothesis words by deleting all reference words.
for i in range(1, len(r)+1):
costs[i][0] = DEL_PENALTY*i
backtrace[i][0] = OP_DEL
# First row represents the case where we achieve the hypothesis
# by inserting all hypothesis words into a zero-length reference.
for j in range(1, len(h) + 1):
costs[0][j] = INS_PENALTY * j
backtrace[0][j] = OP_INS
# computation
for i in range(1, len(r)+1):
for j in range(1, len(h)+1):
if r[i-1] == h[j-1]:
costs[i][j] = costs[i-1][j-1]
backtrace[i][j] = OP_OK
else:
substitutionCost = costs[i-1][j-1] + SUB_PENALTY # penalty is always 1
insertionCost = costs[i][j-1] + INS_PENALTY # penalty is always 1
deletionCost = costs[i-1][j] + DEL_PENALTY # penalty is always 1
costs[i][j] = min(substitutionCost, insertionCost, deletionCost)
if costs[i][j] == substitutionCost:
backtrace[i][j] = OP_SUB
elif costs[i][j] == insertionCost:
backtrace[i][j] = OP_INS
else:
backtrace[i][j] = OP_DEL
# back trace though the best route:
i = len(r)
j = len(h)
numSub = 0
numDel = 0
numIns = 0
numCor = 0
if debug:
print("OP\tREF\tHYP")
lines = []
while i > 0 or j > 0:
if backtrace[i][j] == OP_OK:
numCor += 1
i-=1
j-=1
if debug:
lines.append("OK\t" + r[i]+"\t"+h[j])
elif backtrace[i][j] == OP_SUB:
numSub +=1
i-=1
j-=1
if debug:
lines.append("SUB\t" + r[i]+"\t"+h[j])
elif backtrace[i][j] == OP_INS:
numIns += 1
j-=1
if debug:
lines.append("INS\t" + "****" + "\t" + h[j])
elif backtrace[i][j] == OP_DEL:
numDel += 1
i-=1
if debug:
lines.append("DEL\t" + r[i]+"\t"+"****")
if debug:
lines = reversed(lines)
for line in lines:
print(line)
print("Ncor " + str(numCor))
print("Nsub " + str(numSub))
print("Ndel " + str(numDel))
print("Nins " + str(numIns))
return (numSub + numDel + numIns) / (float) (len(r))
wer_result = round( (numSub + numDel + numIns) / (float) (len(r)), 3)
return {'WER':wer_result, 'Cor':numCor, 'Sub':numSub, 'Ins':numIns, 'Del':numDel}
ref= "Ja also bei uns ist dann auch ein Anliegen"
hyp= "Also, bei uns ist dann auch ein Anliegen"
wer(ref, hyp, debug=True)
该脚本有效,但不显示wer吗?你能帮我吗?
结果显示
OP REF HYP
DEL Ja ****
SUB also Also,
OK bei bei
OK uns uns
OK ist ist
OK dann dann
OK auch auch
OK ein ein
OK Anliegen Anliegen
Ncor 7
Nsub 1
Ndel 1
Nins 0
我真的不知道为什么wer_result不会出现在终端上,您能帮我解决一下吗?
答案 0 :(得分:2)
首先,在return
和print
之间有一个difference。就您的示例而言,最大的不同是print
的副作用是在控制台上显示其参数,而return
没有。
第二,您的函数中有两个return
调用。每当函数到达代码中的第一个return
时,函数都会终止。因此,以下两行将永远不会执行:
wer_result = round( (numSub + numDel + numIns) / (float) (len(r)), 3)
return {'WER':wer_result, 'Cor':numCor, 'Sub':numSub, 'Ins':numIns, 'Del':numDel}
您似乎想要做的就是完全删除第一个return
语句,然后将第二个return
更改为print()
。您是否真的要返回该值取决于您。