# 背景 : 分析funasr识别结果中每个中文字的时间戳偏差情况
1.评价指标:
①偏差公式:
A=标注字的时间戳(帧长区间)
B=识别字的时间戳(帧长区间)
偏差=(AB的区间并集-AB的区间交际)
偏差百分比=(AB的区间并集-AB的区间交际)/(A的帧长)
def calculate_bias(lab_section, range2):
# 计算两个区间的交集
start = max(lab_section[0], range2[0])
end = min(lab_section[1], range2[1])
if start <= end:
intersection = end - start
else:
intersection = 0
#相交部分的概率
iou_pro=intersection/(lab_section[1] - lab_section[0])
# 计算两个区间的偏差=两个区间的并集-两个区间的交集
if intersection==0:
# return "不相交返回1"
# print("不相交返回1",)
return 1,0
#取两个区间的0并集
start = min(lab_section[0], range2[0])
end = max(lab_section[1], range2[1])
deviation_value=((end - start)-intersection)/(lab_section[1] - lab_section[0])
return deviation_value,iou_pro
②评估一个在大概在0.15左右,偏差在0.02没有太大影响,设定偏差阈值在30%以内可用(可以根据实际情况进行修改)
2.启动funasr引擎使用时间戳模型,建议把标点模型去掉,不要数字规整--use_itn设为0即可
3.整理fuansr识别结果
# -*- encoding: utf-8 -*-
import os
import re
def split_string(string):
chinese_pattern=r"([\u4e00-\u9fa5])"
chinese_text=re.sub(chinese_pattern,r"\n\1\n",string)
english_pattern=r"([\w's]+)"
english_text=re.sub(english_pattern,r"\1\n",chinese_text)
english_text = re.sub(r"\n+", "\n", english_text)
english_text = re.sub(r" |^\n+|$\n+", r"", english_text)
return english_text
def read_txt(file):
fr=open(file,"r",encoding="utf-8")
contents=fr.read().strip()
return contents.split("\t")
def read_scp(file):
fr = open(file, "r", encoding="utf-8")
contents = fr.readlines()
return [i.strip().split("/")[-1].replace(".wav","") for i in contents]
def is_english(unchar):
if (unchar >=u'\u0041' and unchar<=u'\u005a') or (unchar >=u'\u0061' and unchar<=u'\u007a'):
return True
else:
return False
if __name__ == '__main__':
result_path= "data_res"
scp_path="data.scp"
file_out="funasr_time.txt"
f_w=open(file_out,"w",encoding="gbk")
result_list=os.listdir(result_path)
scp_list=read_scp(scp_path)
word_time_dict={}
for file in result_list:
file_path=os.path.join(result_path,file)
contents=read_txt(file_path)
key=scp_list[int(file.split("_")[-1])]
content=[i for i in split_string(contents[1]).split("\n") if i]
f_w.write('"{}.mlf_fa_ph"'.format(key)+"\n")
for id,cont in enumerate(content):
if is_english(cont):
pass
else:
f_w.write(cont+"\t"+'[{},{}]'.format(eval(contents[-1])[id][0]/1000,eval(contents[-1])[id][1]/1000) +"\n")
整理之后的格式参考
#!MLF!#
"1.mlf_fa_ph"
就 [0.49000170298543766,0.6200021547979008]
是 [0.6200021547979008,0.741044242937249]
标注的格式也是同上
然后再将识别结果和标注转为HResults统计格式,参考语音识别HResults统计工具以及字根据关键词进行合并-CSDN博客
4.根据HResults统计出识别效果,根据识别效果中的正确字以及替换字作为标注和识别字进行时间戳对比
具体代码见附件