朱德平 新疆乌鲁木齐
语音识别前,需要根据语音识别API的要求,对原始音频文件进行预处理,下面主要介绍音频编码转换和语音分割两项功能。
语音识别API一般对语音文件的编码算法、声道数、采样频率、量化比特等参数有要求,因此需要对原始语音文件进行编码转换,可以利用FFmpeg或者Pydub实现。FFmpeg是一个跨平台的音视频录制、转换、流化工具,其音频编码转换的命令示例:
os.system("ffmpeg -i speech.mp3 -acodec pcm_s16le-ac 1 -ar 16000 speech.wav")
Python语言中将speech.mp3转换成单声道、16K采样率、16量化比特的wav文件。
Pydub是Python的一个音频库,提供了简单、易于使用的音频编程接口,其中编码转换的示例:
from pydub import AudioSegment
speech = AudioSegment.from_mp3("speech.mp3")
speech.export("speech.wav", format="wav",parameters=["-ac", "1", "-ar", "16000"])
由于语音识别API通常对语音的时长有限制,例如不能超过60s等,因此需要对语音文件进行分割,一般采用VAD进行分割。VAD(语音激活检测,又叫语音端点检测),是指通过对语音信号和噪声信号的分析,区别语音区域和非语音区域,利用VAD进行语音分割的基本思路是将语音分割成时长10-30ms的帧,判断每一帧是否是语音信号。 WebRTC VAD是VAD的一个常用实现,py-webrtcvad是它的Python包装库,代码示例:
import webrtcvad
vad = webrtcvad.Vad()
sample_rate = 16000
result=vad.is_speech(frame, sample_rate)
其中frame是分割的帧,result为帧是否为语音的布尔值。
百度AI开放平台支持离线语音识别,要求音频文件单声道、采样率8K或16K,16位量化比特,文件格式是pcm、wav等。语音时间最长60s。代码示例:
from aip import AipSpeech
aipSpeech = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
with open(file_path, 'rb') as file:
speech_content = file.read()
result = aipSpeech.asr(speech_content, 'pcm', 16000, {'dev_pid': 1536})
if result["err_no"] == 0:
print("识别成功,文本是:{}".format(result["result"][0]))
else:
print("识别出错:{}".format(result["err_msg"]))
其中APP_ID,、API_KEY,、SECRET_KEY注册百度平台和创建应用时系统会创建和分配,file_path是语音文件名,dev_pid属性设置语言类型,1536为普通话识别,1537为英语识别。识别结果result为Json结构的数据,其中result["err_no"]若为0,代表识别成功,result["result"]是识别的1-5个候选结果,若result["err_no"]为其它数字,则表示识别出错,result["err_no"]为错误码。
有些情况下,需要将识别出的语音文本和已有的文本进行匹配,可以使用模糊匹配完成,一般使用Levenshtein编辑距离算法,Levenshtein距离是指两个文本由一个转换成另一个需要的最少编辑次数,此处的编辑是指替换、插入和删除操作。代码示例:
import Levenshtein
max_distance = 30
distance = Levenshtein.distance(text1, text2)
if distance < max_distance:
print("匹 配 成 功, Levenshtein距 离 是:{}".format(distance))
else:
print("匹 配 不 成 功, Levenshtein距 离 是:{}".format(distance))
其中text1和text2是进行匹配的文本,如果Levenshtein距离小于30,则认为匹配成功,否则匹配失败。
分词就是将句子切分成一个一个词汇,它是实现文本搜索、统计功能和自然语言处理等的基础,中文分词的算法和库都很多,这里介绍Jieba中文分词库。代码示例:
import jieba
words = jieba.cut(text, cut_all=True)
print("全模式:{} ".format(words)))
words = jieba.cut(text, cut_all=False)
print("精确模式模式:{} ".format(words)))
words = jieba.cut_for_search(text)
print("搜索引擎模式:{} ".format(words)))
其中text为需要分解的文本,words为切分后的词汇列表。分词有三种分词模式,精确模式、全模式、搜索引擎模式。精确模式是常用模式,适合文本分析,全模式是把所有可以成词的词汇都切分出来,搜索引擎模式会对长词再次切分,适用于搜索关键字切分。
若需要对文本进行进一步的处理,可以使用NLP工具实现词性标注、命名实体识别、依存句法分析、语义角色标注等自然语言处理功能。