当前位置:   article > 正文

判断语音识别结果好坏的指标——python实现_字错率 统计 python

字错率 统计 python

判断语音识别结果好坏的指标——python实现:

  • WER字错率
  • SER句错率
  • 杰卡德系数

  • TF 相似度
  • TF-IDF 相似度
  • Word2Vec词向量比较相似性

素材的下载:

    下载地址:链接:https://pan.baidu.com/s/1cTjob0fic0wN16krePThxA

     提取码:269s

result.txt 是按照train.txt 中内容录得音频,经过语音识别的文字结果。

train.txt 为录音内容文本。

WER字错率

    字错率是一种常用的且计算速度比较快的评价方法,根本原理在于统计原句中的文字,和识别录音之后的字的不同之处从而断定语音识别模型好坏。在一般性的识别率的计算上常常使用。“WER(词错误率,Word Error Rate)”。

 

        Substitution——替换

        Deletion——删除

        Insertion——插入

        N——单词数目

        其中S+D+I的计算过程也叫:编辑距离计算

编辑距离计算:

        编辑距离,英文叫做 Edit Distance,又称 Levenshtein 距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数,如果它们的距离越大,说明它们越是不同。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

        例如我们有两个字符串:string 和 setting,如果我们想要把 string 转化为 setting,需要这么两步:

        第一步,在 s 和 t 之间加入字符 e。

        第二步,把 r 替换成 t。

        所以它们的编辑距离差就是 2,这就对应着二者要进行转化所要改变(添加、替换、删除)的最小步数。

因为有插入词,所以理论上WER有可能大于100%,但实际中、特别是大样本量的时候,是不可能的,否则就太差了,不可能被商用。(代码如下)

  1. import distance
  2. def edit_distance(s1, s2):
  3. return distance.levenshtein(s1, s2)

计算总WER():代码如下

  1. # 计算总WER
  2. def calculate_WER():
  3. text1_list = [i[11:].strip("\n") for i in read_result("result.txt")]
  4. text2_orgin_list = [i[11:].strip("\n") for i in read_result("train.txt")]
  5. # print(text2_orgin_list)
  6. total_distance = 0
  7. total_length = 0
  8. for i in range(len(text1_list)):
  9. text1 = text1_list[i]
  10. text2_orgin = text2_orgin_list[i]
  11. res, length = text_distance(text1, text2_orgin)
  12. # print(res, length)
  13. total_distance += res
  14. total_length += length
  15. print("总距离:", total_distance)
  16. print("总长度:", total_length)
  17. WER = total_distance / total_length
  18. print("总WER:", WER.__format__('0.2%'))

结果输出:

总距离: 538

总长度: 5213

总WER: 10.32%

SER句错率

        SER表述为句子中如果有一个词识别错误,那么这个句子被认为识别错误,句子识别错误的的个数,除以总的句子个数即为SER。

         站在纯产品体验角度,很多人会以为识别率应该等于“句子识别正确的个数/总的句子个数”,即“识别(正确)率等于96%”这种,实际工作中,这个应该指向“SER(句错误率,Sentence Error Rate)”,即“句子识别错误的个数/总的句子个数”。不过据说在实际工作中,句错率对结果太苛刻了,一般字错误率的2~3倍,所以可能就不太怎么看了。代码如下

  1. # 计算SER句错率
  2. def calculate_SER():
  3. text1_list = [i[11:].strip("\n") for i in read_result("result.txt")]
  4. text2_orgin_list = [i[11:].strip("\n") for i in read_result("train.txt")]
  5. total_distance = 0
  6. for i in range(len(text1_list)):
  7. text1 = text1_list[i]
  8. text2_orgin = text2_orgin_list[i]
  9. text2_orgin = remove_punctuation(text2_orgin)
  10. # 去除句子中的空格
  11. text1 = text1.replace(' ', '')
  12. # print(text1,"\n",text2_orgin)
  13. if text2_orgin != text1:
  14. total_distance += 1
  15. SER = total_distance / len(text1_list)
  16. print("总句子数量:", len(text1_list))
  17. print("总不相同句子数量:", total_distance)
  18. print("总SER:", SER.__format__('0.2%'))

输出结果: 

总句子数量: 100
总不相同句子数量: 59
总SER: 59.00%

杰卡德系数计算

        杰卡德系数,英文叫做 Jaccard index, 又称为 Jaccard 相似系数,用于比较有限样本集之间的相似性与差异性。Jaccard 系数值越大,样本相似度越高。 实际上它的计算方式非常简单,就是两个样本的交集除以并集得到的数值,当两个样本完全一致时,结果为 1,当两个样本完全不同时,结果为 0。 算法非常简单,就是交集除以并集。(代码如下)

  1. # Jaccard 相似度
  2. def jaccard_similarity(s1, s2):
  3. s1, s2 = set(s1), set(s2)
  4. return len(s1 & s2) / len(s1 | s2)

TF 相似度

        TF相似度计算就是,计算 TF(词频向量化) 矩阵中两个向量的相似度了,实际上就是求解两个向量夹角的余弦值,就是点乘积除以二者的模长,公式如下

        cosθ=a·b/|a|*|b|

代码如下:

  1. import numpy as np
  2. from sklearn.feature_extraction.text import CountVectorizer
  3. # TF 相似度
  4. def tf_similarity(s1, s2):
  5. def add_space(s):
  6. return ' '.join(list(s))
  7. # 将字中间加入空格
  8. s1, s2 = add_space(s1), add_space(s2)
  9. # 转化为TF矩阵
  10. cv = CountVectorizer(tokenizer=lambda s: s.split())
  11. corpus = [s1, s2]
  12. vectors = cv.fit_transform(corpus).toarray()
  13. print(vectors)
  14. return np.dot(vectors[0], vectors[1]) / (norm(vectors[0]) * norm(vectors[1]))

TF-IDF 相似度

        另外除了计算 TF 系数我们还可以计算 TFIDF 系数,TFIDF 实际上就是在词频 TF 的基础上再加入 IDF 的信息,IDF 称为逆文档频率。

TF-IDF与余弦相似性的应用(一):自动提取关键词 - 阮一峰的网络日志 (TFIDF讲解)        

代码如下:

  1. from sklearn.feature_extraction.text import TfidfVectorizer
  2. # TF-IDF 相似度
  3. def tfidf_similarity(s1, s2):
  4. def add_space(s):
  5. return ' '.join(list(s))
  6. # 将字中间加入空格
  7. s1, s2 = add_space(s1), add_space(s2)
  8. # 转化为TF-IDF矩阵
  9. cv = TfidfVectorizer(tokenizer=lambda s: s.split())
  10. corpus = [s1, s2]
  11. vectors = cv.fit_transform(corpus).toarray()
  12. print(vectors)
  13. return np.dot(vectors[0], vectors[1]) / (norm(vectors[0]) * norm(vectors[1]))

Word2Vec词向量比较相似性

        将词映射成词向量在通过计算夹角比较相似性,可以通过训练好的Word2Vec 模型,加载模型,将词转化为向量。

        这里使用的模型是:使用新闻、百度百科、小说数据来训练的 64 维的 Word2Vec 模型,数据量很大,整体效果还不错,我们可以直接下载下来使用,这里我们使用的是 news_12g_baidubaike_20g_novel_90g_embedding_64.bin 数据,然后实现 Sentence2Vec

        下载地址:链接:https://pan.baidu.com/s/1cTjob0fic0wN16krePThxA

        提取码:269s

代码如下:

  1. model_file = 'news_12g_baidubaike_20g_novel_90g_embedding_64.bin'
  2. model = gensim.models.KeyedVectors.load_word2vec_format(model_file, binary=True)
  3. def vector_similarity(s1, s2):
  4. def sentence_vector(s):
  5. words = jieba.lcut(s)
  6. v = np.zeros(64)
  7. for word in words:
  8. v += model[word]
  9. v /= len(words)
  10. return v
  11. v1, v2 = sentence_vector(s1), sentence_vector(s2)
  12. return np.dot(v1, v2) / (norm(v1) * norm(v2))

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/453260
推荐阅读
相关标签
  

闽ICP备14008679号