기록하는삶
[파이썬/Python] 한국어 STT, CER과 WER 계산 본문
728x90
반응형
음성 인식에서 WER과 CER은 정확도를 판별하는 지표이다. 계산 방법과 코드는 각각 아래와 같다.
① WER(Word Error Rate)
D : 음성 인식된 텍스트에 잘못 삭제된 단어 수
S : 음성 인식된 텍스트에 잘못 대체된 단어 수
I : 음성 인식된 텍스트에 잘못 추가된 단어 수
N : 정답 텍스트의 단어 수
단어 에러 비율(WER) = (S+D+I)/N
② CER(Chatacter Error Rate)
D : 음성 인식된 텍스트에 잘못 삭제된 음절 수
S : 음성 인식된 텍스트에 잘못 대체된 음절 수
I : 음성 인식된 텍스트에 잘못 추가된 음절 수
N : 정답 텍스트의 음절 수
음절 에러 비율(CER) = (S+D+I)/N
import Levenshtein as Lev
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 numCor, numSub, numDel, numIns, (numSub + numDel + numIns) / (float) (len(r))
# Run:
# ref='Tuan anh mot ha chin'
# hyp='tuan anh mot hai ba bon chin'
# wer(ref, hyp ,debug=True)
# OP REF HYP
# SUB Tuan tuan
# OK anh anh
# OK mot mot
# INS **** hai
# INS **** ba
# SUB ha bon
# OK chin chin
# Ncor 3
# Nsub 2
# Ndel 0
# Nins 2
# 0.8
def cer(ref, hyp):
ref = ref.replace(' ', '')
hyp = hyp.replace(' ', '')
dist = Lev.distance(hyp, ref)
length = len(ref)
return dist, length, dist/length
비율만 출력하려면 return 부분을 좀 손보면 된다.
728x90
반응형
'AI > kospeech(한국어 STT)' 카테고리의 다른 글
[파이썬/Python] 한국어 STT, kospeech 활용기(5) _ inference.py로 예측하기 (19) | 2022.01.04 |
---|---|
[파이썬/Python] 한국어 STT, kospeech 활용기(4) _ 코랩&구글 드라이브 활용해 모델 학습하기 (25) | 2021.12.31 |
[파이썬/Python] 한국어 STT, kospeech 활용기(3) _ 학습을 위한 코드 수정, configs 변경 (16) | 2021.12.28 |
[파이썬/Python] 한국어 STT, kospeech 활용기(2) _ 폴더 위치 변경 및 모듈 설치 (0) | 2021.12.28 |
[파이썬/Python] 한국어 STT, kospeech 활용기(1) _ 글자 사전 및 transcripts.txt 생성하기 (2) | 2021.12.20 |