编辑距离与字符错误率CER

这篇具有很好参考价值的文章主要介绍了编辑距离与字符错误率CER。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在语音识别场景中,字符错误率(Character Error Rate,CER)是衡量语音识别效果的一个重要指标。下文将介绍CER的原理,并且给出python实现的代码。

1 编辑距离

说到CER,不得不提的是编辑距离(Edit Distance),它是一个用来衡量两个序列的相似度指标。

假设有两个字符串(a和b),编辑距离是指把字符串a修改成b(或者把b改成a)需要的最少编辑次数。编辑的操作只能有三种:

  • 插入(Insertion)
  • 删除(Deletion)
  • 替换(Substitution)

比如,把cat修改成cafe可以这样编辑:

  1. cat --> caf(替换)
  2. caf --> cafe(插入)

也可以这样编辑:

  1. cat --> cate(插入)
  2. cate --> cafe(替换)
1.1 原理

将两个字符串a和b的编辑距离表示为 l e v a , b lev_{a,b} leva,b。之所以用 l e v lev lev,是因为编辑距离的作者叫Levenshtein,所以编辑距离也叫Levenshtein Distance。

l e v a , b ( i , j ) lev_{a,b}(i,j) leva,b(i,j)表示字符串a的前i个字符与b的前j个字符间的编辑距离,比如, l e v c a t , c a f e ( 2 , 3 ) lev_{cat,cafe}(2,3) levcat,cafe(2,3)就表示ca与caf之间编辑距离。

Levenshtein Distance的思路就是,要计算字符串之间的距离,先计算子串间的距离,要计算子串间的距离,先计算子子串间的距离,如此分解下去。用数学语言表示,就是下面这个公式

l e v a , b ( i , j ) = { m a x ( i , j )  if  m i n ( i , j ) = 0 m i n { l e v a , b ( i − 1 , j ) + 1 l e v a , b ( i , j − 1 ) + 1 l e v a , b ( i − 1 , j − 1 ) + s i g n ( a i , b j )  if  m i n ( i , j ) ≠ 0 lev_{a,b}(i,j)=\begin{cases} max(i,j) & \text{ if } min(i,j)=0 \\ min\begin{cases} lev_{a,b}(i-1,j)+1 \\ lev_{a,b}(i,j-1)+1 \\ lev_{a,b}(i-1,j-1)+sign(a_i,b_j) \end{cases} & \text{ if } min(i,j)\neq0 \end{cases} leva,b(i,j)=max(i,j)minleva,b(i1,j)+1leva,b(i,j1)+1leva,b(i1,j1)+sign(ai,bj) if min(i,j)=0 if min(i,j)=0
其中,
s i g n ( a i , b j ) = { 0  if  a i = b j 1  if  a i ≠ b j sign(a_i,b_j)=\begin{cases} 0 & \text { if } a_i = b_j \\ 1 & \text { if } a_i \neq b_j \end{cases} sign(ai,bj)={01 if ai=bj if ai=bj

  • m i n ( i , j ) = 0 min(i,j)=0 min(i,j)=0说明有一个子串是空的,什么都没有,要修改成另外一个子串,光插入字符就行,所以需要的最少编辑次数就是 m a x ( i , j ) max(i,j) max(i,j)。比如 l e v c a t , c a f e ( 2 , 0 ) = l e v c a , 空 白 = 2 lev_{cat,cafe}(2,0)=lev_{ca,空白}=2 levcat,cafe(2,0)=levca,=2

  • m i n ( i , j ) ≠ 0 min(i,j) \neq 0 min(i,j)=0的时候, l e v a , b ( i , j ) lev_{a,b}(i,j) leva,b(i,j)等于以下三种情况的最小值:

    • l e v a , b ( i − 1 , j ) + 1 lev_{a,b}(i-1,j)+1 leva,b(i1,j)+1

    • l e v a , b ( i , j − 1 ) + 1 lev_{a,b}(i,j-1)+1 leva,b(i,j1)+1

    • l e v a , b ( i − 1 , j − 1 ) + s i g n ( a i , b j ) lev_{a,b}(i-1,j-1)+sign(a_i,b_j) leva,b(i1,j1)+sign(ai,bj)

      以cat和cafe为例, l e v c a t , c a f e lev_{cat, cafe} levcat,cafe等于以下三种情况的最小值:

    1. l e v c a , c a f e + 1 lev_{ca, cafe}+1 levca,cafe+1,cat的子串ca与cafe求编辑距离再加1,加1是因为 l e v c a , c a t = 1 lev_{ca, cat}=1 levca,cat=1
    2. l e v c a t , c a f + 1 lev_{cat, caf}+1 levcat,caf+1,cafe的子串caf与cat求编辑距离再加1,加1是因为 l e v c a f , c a f e = 1 lev_{caf, cafe}=1 levcaf,cafe=1
    3. l e v c a , c a f + 1 lev_{ca, caf}+1 levca,caf+1,cat和cafe各自的子串ca和caf求编辑距离再加1,加1是因为(ca)t替换成(caf)e需要一次操作。

根据上面的公式可知,当 i = ∣ a ∣ , j = ∣ b ∣ i=|a|,j=|b| i=a,j=b时, l e v a , b = l e v a , b ( i , j ) lev_{a,b}=lev_{a,b}(i,j) leva,b=leva,b(i,j),其中 ∣ a ∣ |a| a ∣ b ∣ |b| b分别表示a和b的长度。

1.2 演算过程

编辑距离的计算过程可以用一个矩阵来记录。

以cat和cafe为例,建立一个矩阵,用来记录计算的中间结果:

c a f e
0 1 2 3 4
c 1 a 1 , 1 a_{1,1} a1,1 a 1 , 2 a_{1,2} a1,2 a 1 , 3 a_{1,3} a1,3 a 1 , 4 a_{1,4} a1,4
a 2 a 2 , 1 a_{2,1} a2,1 a 2 , 2 a_{2,2} a2,2 a 2 , 3 a_{2,3} a2,3 a 2 , 4 a_{2,4} a2,4
t 3 a 3 , 1 a_{3,1} a3,1 a 3 , 2 a_{3,2} a3,2 a 3 , 3 a_{3,3} a3,3 a 3 , 4 a_{3,4} a3,4

第二行的01234表示从什么都没有到c、ca、caf、cafe分别需要的最少编辑次数;同样地,第二列的0123表示从什么都没有到c、ca、cat分别需要的最少编辑次数。

a 1 , 1 = m i n ( a 1 , 0 + 1 , a 0 , 1 + 1 , a 0 , 0 ) a_{1,1}=min(a_{1,0}+1,a_{0,1}+1,a_{0,0}) a1,1=min(a1,0+1,a0,1+1,a0,0)

a 1 , 2 = m i n ( a 1 , 1 + 1 , a 0 , 2 + 1 , a 0 , 1 + 1 ) a_{1,2}=min(a_{1,1}+1,a_{0,2}+1,a_{0,1}+1) a1,2=min(a1,1+1,a0,2+1,a0,1+1)

a 2 , 1 = m i n ( a 1 , 1 + 1 , a 2 , 0 + 1 , a 1 , 0 + 1 ) a_{2,1}=min(a_{1,1}+1,a_{2,0}+1,a_{1,0}+1) a2,1=min(a1,1+1,a2,0+1,a1,0+1)

……

最终的矩阵如下:

c a f e
0 1 2 3 4
c 1 0 1 2 3
a 2 1 0 1 2
t 3 2 1 1 2

可以找出规律, 每 个 格 子 的 值 = m i n ( 上 方 格 子 的 值 + 1 , 左 方 格 子 的 值 + 1 , 左 上 方 格 子 + ( 0 或 1 ) ) 每个格子的值=min(上方格子的值+1,左方格子的值+1,左上方格子+(0或1)) =min(+1+1+(01)),0还是1取决于格子左边的字母是否等于格子上面的字母。

1.3 代码实现

找到编辑距离的计算规律后,代码实现就不难了。python代码如下:

def edit_distance(str1, str2):
    """计算两个字符串之间的编辑距离。
    Args:
        str1: 字符串1。
        str2: 字符串2。
    Returns:
        dist: 编辑距离。
    """
    matrix = [[i + j for j in range(len(str2) + 1)] for i in range(len(str1) + 1)]
    for i in range(1, len(str1) + 1):
        for j in range(1, len(str2) + 1):
            if str1[i - 1] == str2[j - 1]:
                d = 0
            else:
                d = 1
            matrix[i][j] = min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + d)
    dist = matrix[len(str1)][len(str2)]
    return dist

2 字符错误率

弄清楚编辑距离的原理后,理解字符错误率(CER)就很简单了。假设我说了一句话a,被语音识别系统识别成b,那么 c e r = l e v a , b ÷ ∣ a ∣ cer=lev_{a,b}\div|a| cer=leva,b÷a,就这么简单,所以代码也很简单:

def get_cer(src, trg):
    """把源字符串src修改成目标字符串trg的字符错误率。
    Args:
        src: 源字符串。
        trg: 目标字符串。
    Returns:
        cer: 字符错误率。
    """
    dist = edit_distance(src, trg)
    cer = dist / len(trg)
    return cer

最后,祝我的大宝雨水快乐!文章来源地址https://www.toymoban.com/news/detail-644441.html

到了这里,关于编辑距离与字符错误率CER的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器学习与深度学习——通过SVM线性支持向量机分类鸢尾花数据集iris求出错误率并可视化

    先来看一下什么叫数据近似线性可分,如下图所示,蓝色圆点和红色圆点分别代表正类和负类,显然我们不能找到一个线性的分离超平面将这两类完全正确的分开;但是如果将数据中的某些特异点(黑色箭头指向的点)去除之后,剩下的大部分样本点组成的集合是线性可分的,

    2023年04月18日
    浏览(63)
  • 算法刷题|583.两个字符串的删除操作、72.编辑距离

    题目:给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 dp[i][j] 表示以i-1结尾的word1子序列和以j-1结尾word2变成相同所需要的最小的步数为dp[i][j] 递推公式:分两种情况,word1.charAt(i-1) 和 word2.charAt(j-1)是否

    2024年02月08日
    浏览(47)
  • 动态规划16 | ● 583. 两个字符串的删除操作 ● *72. 编辑距离

    https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html 考点 子序列问题 我的思路 dp[i][j]的含义是,当两个字符串分别取前i和j个元素时,对应的最少相等删除步数是多少 递推公式为,如果两个字符串第i和j个元素恰好相等,则dp值应

    2024年04月22日
    浏览(51)
  • Day56 | 583. 两个字符串的删除操作 | 72. 编辑距离

    583. 两个字符串的删除操作 注意点: 1.当word1[i - 1] 与 word2[j - 1]不相同的时候, 情况一:删word1[i - 1],最少操作次数为dp[i - 1][j] + 1 情况二:删word2[j - 1],最少操作次数为dp[i][j - 1] + 1 情况三:同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2 因为 dp[i][j-1]+1 = d

    2024年02月08日
    浏览(45)
  • 【dp】不同的子序列 & 两个字符串的删除操作 & 编辑距离

    dp[i][j]:以j-1为结尾的t出现在以i-1为结尾的s子序列的个数 需要开辟m+1行,n+1列的二维数组 为啥状态方程是: s[i] == t[j] 时 dp[i][j] = dp[i-1][j-1] + dp[i-1][j] s[i] != t[j] 时 dp[i][j] = dp[i-1][j] 先看s[i] == t[j] 时,以s = “rara” t = “ra” 为例,当i = 3, j = 1时,s[i] == t[j] 此时分为2种情况:

    2023年04月15日
    浏览(45)
  • LeetCode | C++ 动态规划——583. 两个字符串的删除操作、72. 编辑距离

    583题目链接 做法一: 本题和1143.最长公共子序列基本相同,只要求出两个字符串的最长公共子序列长度即可,那么除了最长公共子序列之外的字符都是必须删除的,最后用两个字符串的总长度减去两个最长公共子序列的长度就是删除的最少步数。 做法二: 本题和115.不同的子

    2024年02月16日
    浏览(53)
  • 代码随想录第五十六天——两个字符串的删除操作,编辑距离

    题目链接:两个字符串的删除操作 两个字符串可以相互删除 版本一: 确定dp数组及下标的含义 dp[i][j] :以i-1为结尾的字符串word1,和以j-1为结尾的字符串word2,想要达到相等,所需要删除元素的最少次数 确定递推公式 (1)当word1[i - 1] 与 word2[j - 1]相同: (2)当word1[i - 1] 与

    2024年02月02日
    浏览(40)
  • 代码随想录打卡第56天|583. 两个字符串的删除操作;72. 编辑距离

    583. 两个字符串的删除操作 关键点1:dp数组的含义 dp[i][j],使得以i-1为结尾word1 和 以j-1为结尾的word2 相同所需的最小步数; 关键点2:递归公式的推导 if(nums1[i-1] == nums2[j-1]),则i和j同时移动,所以为i-1,j-1;dp[i][j] = dp[i-1][j-1];由于不需要进行删除操作,所以不需要加1 如果不相

    2023年04月19日
    浏览(51)
  • 【动态规划】求解编辑距离问题

    编辑距离问题是求解将⼀个字符串转换为另⼀个字符串所需的 插⼊、删除、替换 的最小次数。 C O M M O M → s u b C O M M U M → s u b C O M M U N → i n s C O M M U N E mathbb{COMMOM} overset{sub}{rightarrow} mathbb{COMMUM} overset{sub}{rightarrow}mathbb{COMMUN} overset{ins}{rightarrow} mathbb{COMMUNE} COMMOM →

    2024年02月02日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包