EER有什么用

发布时间:2021-12-08 14:11:20 作者:iii
来源:亿速云 阅读:175

这篇文章主要介绍“EER有什么用”,在日常操作中,相信很多人在EER有什么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”EER有什么用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

   FRR(False Rejection Rate)和FAR(False Acceptance Rate)是用来评估指纹识别算法性能的两个主要参数。

   FRR通俗叫法是拒真率的意思,标准称谓是 FNMR(False Non-Match Rate 不匹配率)。可以通俗的理解为“把应该相互匹配成功的指纹当成不能匹配的指纹”的概率。

     Equal Error Rate , 这个在说话人识别,说话人确认中最常用的评价标准,是一种使错误接受率(nontarget_is_target / (target_is_target + nontarget_is_target)) 和 错误拒绝

率(target_is_nontarget / (target_is_nontarget + nontarget_is_nontarget))的一个相对平衡点阈值点,然后这个阈值点可以作为实际使用阶段的固定的阈值。

   如 得分非 -170----A-------threshold ------B------- +100    按理来说 A 中都是nontarget, B中都是target。 如果在A 中出现了target 就是错误拒绝了,如果在B 中出现了

nontarget  就是错误接收了

   FAR一般称为认假率,其标准称谓是FMR(False Match Rate 错误匹配率)。FMR是用来评估指纹识别算法性能的最重要参数。可以通俗的理解为“把不应该匹配的指纹当成匹配

的指纹”的概率。

   FAR是随阈值增大而减小的,FRR是随阈值增大而增大的。因此它们一定有交点。这个点是在某个阈值下的FAR与FRR等值的点。习惯上用这一点的值来衡量算法的综合性能。

对于一个更优的指纹算法,希望在相同阈值情况下,FAR和FRR都越小越好。

   把FAR和FRR曲线都向下平移。同时相交点ERR也向下平移。所以EER值越小的时候,表示算法的整体性能越高。   

Equal Error Rate , 这个在说话人识别,说话人确认中最常用的评价标准,是一种使错误接受率(nontarget_is_target / (target_is_target + nontarget_is_target)) 和 错误拒绝率(target_is_nontarget / (target_is_nontarget + nontarget_is_nontarget))的一个相对平衡点阈值点,然后这个阈值点可以作为实际使用阶段的固定的阈值。 
还记得trials文件嘛,还记得没有cvs文件自己伪造trials文件嘛, 还记得不明白为什么要制造50%或者80%的nontarget嘛,就是为了要计算EER。所以在伪造trials文件的时候,最好是分布均匀,也就是要涉及到每一个人,每一个人都要有一定数量的nontarget,其实也可以每个人对其他所有人都做一个nontarget,到底是取一部分还是所有的这个我也不确定,等验证过后再更新(记得验证)。

-->先说一些EER的计算: 
false reject and false accept. Clearly, the false reject rate and the false accept rate depend on the threshold. When the two rates are equal, the common value is called equal error rate (EER).

什么是false reject(用fr表示), 就是本来应该accept 的结果 reject了: 
FR = target_is_nontarget / (target_is_nontarget + nontarget_is_nontarget) 
而false accept(用fa表示),就是本来应该reject的结果accept了: 
FA = nontarget_is_target / (target_is_target + nontarget_is_target) 
当E(fr) = E(fa) = E 时, E即 EER的值。 
-->维基百科ROC曲线 https://zh.wikipedia.org/wiki/ROC曲线 
--> 然后看一下kaldi源码: 
eer=compute-eer <(python local/prepare_for_eer.py $trials local/scores_gmm_${num_components}_${x}_${y}/plda_scores) 2> /dev/null
单独运行: 
python local/prepare_for_eer.py data/test/trials exp/scores_gmm_2048_ind_female/plda_scores 
结果:

-30.99115 target
-28.06169 target
-17.78868 target
-87.6428 nontarget
-74.32495 nontarget
-74.18333 nontarget
-5.662024 target
-7.832421 target
-26.46083 target
-74.93365 nontarget
-86.17784 nontarget
-50.90917 nontarget
-26.51904 target
-14.09044 target
...
#Ki就是上面的lines流, 把没用的代码全都删掉,可以去看kaldi的源码
 while (std::getline(ki.Stream(), line)) {
      std::vector<std::string> split_line;
      SplitStringToVector(line, " \t", true, &split_line);
      BaseFloat score;
      if (split_line[1] == "target")
        target_scores.push_back(score);
      else if (split_line[1] == "nontarget")
        nontarget_scores.push_back(score);
      else 
        KALDI_ERR << "blablabla"
    }
    BaseFloat threshold;
    #定义一个threshold,两个list: target_scores, nontarget_scores
    BaseFloat eer = ComputeEer(&target_scores, &nontarget_scores, &threshold);
    KALDI_LOG << "Equal error rate is " << (100.0 * eer)
              << "%, at threshold " << threshold;
    std::cout.precision(4);
    std::cout << (100.0 * eer);
    return 0;

下面看ComputeEer(&target_scores, &nontarget_scores, &threshold)的实现

 {
  #将两个都从大到小排列
  std::sort(target_scores->begin(), target_scores->end());
  std::sort(nontarget_scores->begin(), nontarget_scores->end());

  size_t target_position = 0,
      target_size = target_scores->size();
  for (; target_position + 1 < target_size; target_position++) {
        size_t nontarget_size = nontarget_scores->size(), #计算nontarget的个数
        #比如nontarget_size=100 ,target_size=100 这个 nontarget_n 属于[0,100], 
        #所以nontarget_positon 从99到-1
        nontarget_n = nontarget_size * target_position * 1.0 / target_size; 
        nontarget_position = nontarget_size - 1 - nontarget_n;
    if (nontarget_position  < 0)
      nontarget_position = 0;
    #所以当nontarget_position 小于 target_position 的值的时候
    if ((*nontarget_scores)[nontarget_position] <
        (*target_scores)[target_position])
      break;
  }
  *threshold = (*target_scores)[target_position];
  BaseFloat eer = target_position * 1.0 / target_size;
  return eer;
}
要理解这个函数的实现,其实在compute-eer里边还是一行注释:
ComputeEer computes the Equal Error Rate (EER) for the given scores
   and returns it as a proportion beween 0 and 1.
   If we set the threshold at x, then the target error-rate is the
   proportion of target_scores below x; and the non-target error-rate
   is the proportion of non-target scores above x.  We seek a
   threshold x for which these error rates are the same; this
   error rate is the EER.

   We compute this by iterating over the positions in target_scores: 0, 1, 2,
   and so on, and for each position consider whether the cutoff could be here.
   For each of these position we compute the corresponding position in
   nontarget_scores where the cutoff would be if the EER were the same.
   For instance, if the vectors had the same length, this would be position
   length() - 1, length() - 2, and so on.  As soon as the value at that
   position in nontarget_scores at that position is less than the value from
   target_scores, we have our EER.
下面拿一个例子用python简单模拟一下:
#coding: utf-8
'''
首先计算这一步,将target的得分和nontarget的得分文件
python local/prepare_for_eer.py data/test/trials exp/scores_gmm_2048_ind_female/plda_scores > scores
'''
target_scores = []
nontarget_scores = []
f = open('scores').readlines()
#将两个数组读出来
for line in f:
    splits = line.strip().split(' ')
    if splits[1] == 'target':
        target_scores.append(eval(splits[0]))
    else:
        nontarget_scores.append(eval(splits[0]))

#排序,从小到大排序
target_scores = sorted(target_scores)
nontarget_scores = sorted(nontarget_scores)

print target_scores

target_size = len(target_scores)
target_position = 0
for target_position in range(target_size):
    nontarget_size = len(nontarget_scores)
    nontarget_n = nontarget_size * target_position * 1.0 / target_size
    nontarget_position = int(nontarget_size - 1 - nontarget_n)
    if nontarget_position < 0:
        nontarget_position = 0
    if nontarget_scores[nontarget_position] < target_scores[target_position]:
        print "nontarget_scores[nontarget_position] is",  nontarget_position, nontarget_scores[nontarget_position]
        print "target_scores[target_position] is",  target_position, target_scores[target_position]
        break

threshold = target_scores[target_position]
print "threshold is --> ",  threshold
eer = target_position * 1.0 / target_size
print "eer is --> ",  eer

到此,关于“EER有什么用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. aside有什么用
  2. ajax有什么用途

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

上一篇:Hbase如何写入hdfs

下一篇:Linux的输入输出方法有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》