外呼号码空号检测
DA是什么
DA(Dialing Analysis)空号检测,是一种语音电话外呼失败的结果检测工具,由于现在SIP中继,在外呼失败情况,比如关机、停机、拒接等情况下没有信令返回,无法通过信令来检测,但是外呼结果对呼叫的重呼策略有很大的影响,外呼的失败结果检测对外呼应用是关键的一个模块;
DA通过检测前媒体跟样本库比对,匹配样本返回结果、挂断电话,目前DA模块只检测外呼失败的情况如关机、停机、拒接等情况,对于彩铃等情况不予以检测。
DA工具分为两个部分,一个是样本库,一个DA检测算法,算法的基本原理是将呼叫开始到呼叫接通或者呼叫结束之间的媒体流复制一份转发到DA工具,DA根据收到的媒体流,将媒体流转码成PCM(8K 16bit)格式,然后开始检测,检测的算法为将媒体流经过短时傅里叶转化为频谱图,取媒体流中的高能量点,然后跟样本库中的数据比较,满足一定数量的样本点阈值就认为找到合适的样式,样本数阈值可以设置,如果设置的越高,则准确度越高,同时识别时间也会越长。样本库可以维护,可维护的操作为添加样本、标记样本类型,对于识别不出的样本,会在DA中录音,可以将录音截取语音字段,然后加到样本库中,这样下次就可以识别出来了。
样本类型
DA目前支持样本类型有12种,分别为
样本ID |
样本类型 |
1 |
停机 |
2 |
关机 |
3 |
呼入限制 |
4 |
呼出限制 |
5 |
呼叫转移 |
6 |
无人接听 |
7 |
无法接通 |
8 |
来电提醒 |
9 |
正在通话中 |
10 |
用户正忙 |
11 |
空号 |
12 |
网络忙 |
基础知识
DA算法的实现需要一定语音和信号基础知识。下文会先介绍基础知识,然后再详细的介绍算法,最后举一个实际的例子来说明
时域和频域
时域是描述数学函数或物理信号对时间的关系。例如一个信号的时域波形可以表达信号随着时间的变化。如下图所示就是一段声音的时域波形图,X轴代表时间,Y轴代表振幅大小。一段语音文件可以转化为X轴为时间,Y轴为[-1, 1] 之间的时域图。
频域指在对函数或信号进行分析时,分析其和频率有关部分,而不是和时间有关的部分,和时域一词相对。跟时域相比,时域例如一段音乐,而频域相当于一首乐谱,乐谱是不会随着时间而变化。频域(频率域)——自变量是频率,即横轴是频率,纵轴是该频率信号的幅度,也就是通常说的频谱图。频谱图描述了信号的频率结构及频率与该频率信号幅度的关系。
根据傅里叶函数说明,任何周期函数,都可以看作是不同振幅,不同相位正弦波的叠加。在上图中里我们可以理解为,根据不同的曲谱,利用对不同琴键不同力度,不同时间点的敲击,可以组合出任何一首乐曲。
傅里叶级数(Fourier Series)的频谱
参考 https://blog.csdn.net/wangchao712217/article/details/78731494 (下面中用到图也是从中截取,感谢作者辛苦)
简单的说认为一个语音文件的时域图可以由无数个不同频率的正弦波来相加得到,如下图所示
,每两个正弦波之间都还有一条直线,那并不是分割线,而是振幅为 0 的正弦波!也就是说,为了组成特殊的曲线,有些正弦波成分是不需要的。这里,不同频率的正弦波我们成为频率分量。
如果我们把第一个频率最低的频率分量看作“1”,我们就有了构建频域的最基本单元。对于我们最常见的有理数轴,数字“1”就是有理数轴的基本单元
从频率方向来看我们就得到了频域图像如下图所示
可以发现,在频谱中,偶数项的振幅都是0,也就对应了图中的彩色直线。振幅为 0 的正弦波。
短时傅里叶变换
短时傅里叶变换是和傅里叶变换相关的一种数学变换,用以确定时变信号其局部区域正弦波的频率与相位。
短时傅里叶变换就是将原来的傅里叶变换在时域截短为多段分别进行傅里叶变换,每一段记为时刻ti,对应FFT求出频域特性,就可以粗略估计出时刻ti时的频域特性(也就是同时指导了时域和频域的对应关系)。用于信号截短的工具叫做窗函数(宽度相当于时间长度),窗越小,时域特性越明显,但是此时由于点数过少导致FFT降低了精确度,导致频域特性不明显。因此说窗的选取(包括大小和类型)是一个博弈的过程,根据自己研究的角度,选取适合的窗即可,当然最好还是选小波变换。
另外,为了保证频域特性的基础上提高时域特性,经常选择前后窗函数重叠一部分,这样两个窗确定的时刻就比较接近就提高了时域分析能力。但不是重叠越多越好,重叠点数过多会大幅增加计算量,导致效率低下,因此前后窗重叠的点数也需要外加确定
语谱图
频谱分析视图,如果针对语音数据的话,叫语谱图。语谱图的横坐标是时间,纵坐标是频率,坐标点值为语音数据能量。由于是采用二维平面表达三维信息,所以能量值的大小是通过颜色来表示的,颜色深,表示该点的语音能量越强。如下图就是一个语音文件的语谱图
其中X轴表示时间,y轴表示频率,不同颜色的点代表指定频率在指定时间的能量值。
算法过程
如果我们的语音文件采样率为8000,每次采样16bit,这样每秒语音文件大小为16000Byte为16kB;
先将语音文件转化为时域图基本算法是先将语音文件byte数组转化为short数组(采用little endian方式,大小为short数组的一般),然后将short数组转化为 float数组(大小为short数组的一半)
转化公相应的时域图;
这样按照现有的格式就可以每秒就可以 4000 个点,按照时间对应关系就可以画出是时域图
例如上图就是一个典型的时间图,
下一步就是 时域图 进行 STFT(短时傅里叶变换)目的是为了生成频谱图,
具体转化算法如下
参考https://blog.csdn.net/yuelulu0629/article/details/76167229
将float数组分成512大小的window窗口,经过傅里叶转化, 这样就会生成一个包含时间、频率、能量谱密度的频谱图,
如下图所示
在生成了频谱图之后,下一步我们在频谱图中去找能量高点,
首先我们要做数据清理
清理主要根据两个条件
一个是频率范围是100HZ ~ 2000HZ(人的听力范围在16HZ~20000HZ,在1000-3000HZ内最为敏感),所有小于100和大于2000都点都过滤掉,第二个是能量谱值大小,所有小于0的都过滤掉。如下图所示就是过滤掉所有无效点的频谱点图。
在清理了之后就可以开始定义基带了,设定基带
基带是从每个窗口512个float值中去寻找两个节点范围内的高点值
再这些能量点钟去寻找三个最高点。如下图就是定位某个能量谱高点的图。
在定位到能量谱高点之后,要做连接处理
在连接处理的时候需要满足下面三个条件
- 在同一个基带内
- 两点频率范围在 -600f ~ 600f
- 点数相隔距在 1 ~ 3
这样得到了一个连接关系数组,然后对连接关系数组做Hash处理,转化为一个Hash值
在计算出hash值和样本时间点就作为一个样本值
样本的匹配
样本的匹配是首先根据生成的样本点和时间去数据库中查找所有符合条件的Hash值的样本,然后根据两个的时间差再生成一个hash,这个hash 生成根据样本id 和时间差
原则上样本可能是样本库中样本的一个片段,所以只要样本相同而且时间差相同生成的Hash值应该也是相同的,然后根据符合的样本点数量,如果样本点大于设置的阈值(10),则停止匹配,返回样本码
识别效果
识别的效果根据样本库的数量,目前维护的样本库有2百个左右,根据目前的项目经验识别率可以达到90%以上;
有需要的可以提供源码,当然也不是无偿提供的。