2023年全国行业职业技能竞赛【笔记】
2023年全国行业职业技能竞赛【笔记】
辅助工具
写代码时的自动补全
Tab 键
查看类、模块或函数的帮助
help()
查看类的或模块的属性和方法
dir()
查找依赖包的路径
find / -name tencentcloud 2>/dev/null
在Unix和Linux系统中,2>/dev/null是一种重定向操作,用于抑制错误消息。
在这里,2代表"标准错误"(stderr),>是重定向操作符,/dev/null是一个特殊的文件,写入到它的数据会被系统自动丢弃。
所以,2>/dev/null的意思是将标准错误的输出重定向到/dev/null,即忽略错误消息。这在运行可能会产生错误输出的命令时非常有用,可以让命令的输出更加清晰。
语音识别
导入语音识别(ASR)的依赖包
import json
import base64
from tencentcloud.common import credential
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.asr.v20190614 import asr_client, models
- from tencentcloud.asr.v20190614 import asr_client, models
ASR(Automatic Speech Recognition)
文件转 Base64 字符串
def ToBase64(file):
with open(file, 'rb') as f:
data = f.read()
bytes_base64 = base64.b64encode(data)
str_base64 = bytes.decode(bytes_base64)
return str_base64
- bytes_base64 = base64.b64encode(data) 使用base64.b64encode函数将data转换为Base64编码。这会返回一个新的字节串,其中包含data的Base64编码。
- str_base64 = bytes.decode(bytes_base64) 使用bytes.decode方法将Base64编码的字节串转换为字符串。这是因为Base64编码通常用于将二进制数据转换为ASCII字符串,以便在文本协议中传输。
语音识别
voice = ToBase64(file)
params = {
'EngSerViceType': '16k_zh',
'SourceType': 1,
'Data': voice,
'VoiceFormat': 'mp3',
'FilterDirty': 0,
'FilterPunc': 0
}
req = models.SentenceRecognitionRequest()
req.from_json_string(json.dumps(params))
resp = client.SentenceRecognition(req)
result=resp.to_json_string()
print(result)
{"Result": "药物的副作用和不良反应有区别吗?", "AudioDuration": 8202,
"WordSize": 0, "WordList": null, "RequestId": "ff0b2fe1-78c1-4fc2-aa7d-c7fca0e5b41e"}
语音合成
导入语音合成(TTS)的依赖包
import uuid
import json
import base64
from tencentcloud.common import credential
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.tts.v20190823 import tts_client, models
- from tencentcloud.tts.v20190823 import tts_client, models
TTS(Text to Speech)
Base64 字符串转文件
def ToFile(base64_data, file):
data = base64.b64decode(base64_data)
with open(file, 'wb') as f:
f.write(data)
- data = base64.b64decode(base64_data) 使用base64.b64decode函数将Base64编码的字符串转换为字节串。这会返回一个新的字节串,其中包含Base64编码的字符串的解码结果。
语音合成
sessionId = str(uuid.uuid1())
params = {
'Text': '欢迎使用智能医院服务',
'SessionId': sessionId,
'Volume': 5,
'VoiceType': 1004,
'PrimaryLanguage': 1,
'Codec': 'mp3' # 不要忘记了
}
req = models.TextToVoiceRequest()
req.from_json_string(json.dumps(params))
resp = client.TextToVoice(req)
json_resp = json.loads(resp.to_json_string())
base64_data = json_resp['Audio']
file = '语音合成结果.mp3'
ToFile(base64_data, file)
微调语音识别模型
基于模型的语音识别
import os
from speech_model import ModelSpeech # 语音模型类
from speech_model_zoo import SpeechModel26
from speech_features import Spectrogram # 语音识别内置的语谱图声学特征提取类
from LanguageModel import ModelLanguage
from utils.ops import cosine_similarity
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
class modelTest:
# 定义初始化方法__init__,初始化模型路径,创建声学模型对象。
def __init__(self):
# (1)初始化模型路径。
self.model_path = 'save_models/PretrainedModel.h5'
# (2)创建初始声学模型类实例对象,要求初始模型的输出的拼音表示为1428,通道数为1,音频长度为1600,特征值序列为200维。
pinyin, channel, voice_len, spec_dim = 1428, 1, 1600, 200
# (3)创建声学特征类型实例对象。
self.speech_model = SpeechModel26(input_shape = (voice_len, spec_dim, channel), output_size = pinyin)
# 定义识别函数recognize(),实现模型的调用并成功输出识别到的语句。
def recognize(self):
# (4)创建声学模型功能类实例对象,最长标签长度设置为32。
spec = Spectrogram()
model_speech = ModelSpeech(self.speech_model, spec, max_label_length = 32)
# (5)基于预训练模型“PretrainedModel.h5”,进行模型的调用,识别“1.wav”这个语音文件
model_speech.load_model(self.model_path)
pinyin = model_speech.recognize_speech_from_file('1.wav')
model_lang = ModelLanguage('model_language') # model_language 为语言模型的路径
model_lang.LoadModel()
text = model_lang.SpeechToText(pinyin)
return text
if __name__ == '__main__':
mt = modelTest()
print(cosine_similarity(mt.recognize(), 1))
模型训练
import os
from keras.optimizers import Adam
from speech_model import ModelSpeech
from speech_model_zoo import SpeechModel26
from data_loader import DataLoader
from speech_features import Spectrogram
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
speech_model = SpeechModel26(
input_shape = (1600, 200, 1),
output_size = 1428
)
feat = Spectrogram()
train_data = DataLoader('train')
opt = Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model_speech = ModelSpeech(speech_model, feat, max_label_length=64)
model_speech.load_model('save_models/PretrainedModel.h5')
model_speech.train_model(optimizer=opt, data_loader=train_data, epochs=10, save_step=1, batch_size=16)
数据采集与处理
爬虫采集数据
import requests
header = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}
url = 'http://43.139.169.182/hospital.html'
r = requests.get(url, headers=headers)
r.encoding = 'utf-8'
html = r.text
解析数据
from bs4 import BeautifulSoup
bs = BeautifulSoup(html)
items = bs.select('.history .messages .text')
texts = [item.text for item in items]
for text in texts:
print(text)
output_file = 'hosptial.txt'
with open(output_file, 'w') as f:
f.write('\n'.join(texts))
解析后的数据
你好,我要预约。
好的,请问您要预约门诊部还是住院部?
我要预约门诊部。
好的,请问您要预约什么科室。
我要预约心血管科。
今日心血管科坐诊医生有:张三(主任)、李四(副主任)、李丽(副主任),请问您需要预约哪位医生?
预约张三医生。
好的,张三医生今日坐诊剩余时段号有10号(9:00—9:20)、16号(11:00—11:20)。
就预约3号吧。
好的。请登记您的姓名和身份证号。
我叫王五,身份证号1234567。
加载语料
from nltk.corpus import PlaintextCorpusReader
# 将 hosptial.txt 文件内容作为语料,选择用于分析文本文件的方法载入语料
file = 'hosptial.txt'
corpus = PlaintextCorpusReader('.', file)
text = corpus.raw(file)
print(f'原文本:{text}')
原文本:你好,我要预约。
好的,请问您要预约门诊部还是住院部?
我要预约门诊部。
好的,请问您要预约什么科室。
我要预约心血管科。
今日心血管科坐诊医生有:张三(主任)、李四(副主任)、李丽(副主任),请问您需要预约哪位医生?
预约张三医生。
好的,张三医生今日坐诊剩余时段号有10号(9:00—9:20)、16号(11:00—11:20)。
就预约3号吧。
好的。请登记您的姓名和身份证号。
我叫王五,身份证号1234567。
数据清洗
import re
# 清洗掉除汉字以外的字符。
cleaned_text = re.sub(r'[^\u4e00-\u9fa5]', '', text)
print(f'清洗的文本:{cleaned_text}')
清洗的文本:你好我要预约好的请问您要预约门诊部还是住院部我要预约门诊部好的请问您要预约什么科室我要预约心血管科
今日心血管科坐诊医生有张三主任李四副主任李丽副主任请问您需要预约哪位医生预约张三医生好的张三医生今日坐诊剩余时段号有号号
就预约号吧好的请登记您的姓名和身份证号我叫王五身份证号
结果为一行,这里手动分行了。
数据扩充
from nlpcda import Similarword
# 返回2个增强文本,文本改变率要求为25%
similarword = Similarword(create_num=2, change_rate=0.25)
similar_cleaned_text = similarword.replace(cleaned_text)
for i, s in enumerate(similar_cleaned_text):
print(f'扩充样本 {i+1}:{s}')
扩充样本 1:你好我要预约好的请问您要预约门诊部还是住院部我要预约门诊部好的请问您要预约什么科室我要预约心血管科
今日心血管科坐诊医生有张三主任李四副主任李丽副主任请问您需要预约哪位医生预约张三医生好的张三医生今日坐诊剩余时段号有号号
就预约号吧好的请登记您的姓名和身份证号我叫王五身份证号
扩充样本 2:你好我要约定好的请问您要预约门诊部还是住院部我要预约门诊部好的请问您要约定什么科室我要预约心血管科
今日心血管科坐诊医生有张三主任李四副主任李丽副主任请问您用约定哪位白衣战士预约张三医生好的张三医生今日坐诊剩余时段号有号号
就预约号吧好的请登记您的姓名和身份证号我叫王五身份证号
结果为一行,这里手动分行了。
StanfordCoreNLP:中文分词、词性标注以及中文命名实体识别
from stanfordcorenlp import StanfordCoreNLP
# (5)调用CoreNLP中文语料包。
nlp = StanfordCoreNLP('../stanford-corenlp-full-2018-02-27/')
word = nlp.word_tokenize(text)
print(f'中文分词: {word}')
pos_tag = nlp.pos_tag(text)
print(f'词性标注: {pos_tag}')
ner = nlp.ner(text)
print(f'中文命名实体识别: {ner}')
中文分词
中文分词: ['你好', ',', '我要预约', '。', '好的', ',', '请问您要预约门诊部还是住院部', '?', '我要预约门诊部', '。', '好的', ',', '请问您要预约什么科室', '。', '我要预约心血管科', '。', '今日心血管科坐诊医生有', ':', '张三', '(', '主任', ')', '、', '李四', '(', '副主任', ')', '、', '李丽', '(', '副主任', ')', ',', '请问您需要预约哪位医生', '?', '预约张三医生', '。', '好的', ',', '张三医生今日坐诊剩余时段号有10号', '(', '9:00', '—', '9:20', ')', '、', '16号', '(', '11:00', '—', '11:20', ')', '。', '就预约3号吧', '。', '好的', '。', '请登记您的姓名和身份证号', '。', '我叫王五', ',', '身份证号1234567', '。']
词性标注
词性标注: [('你好', 'NN'), (',', 'CD'), ('我要预约', 'CD'), ('。', 'NN'), ('好的', 'NN'), (',', 'CD'), ('请问您要预约门诊部还是住院部', 'CD'), ('?', 'NN'), ('我要预约门诊部', 'NN'), ('。', 'SYM'), ('好的', 'NN'), (',', 'CD'), ('请问您要预约什么科室', 'CD'), ('。', 'NN'), ('我要预约心血管科', 'JJ'), ('。', 'NN'), ('今日心血管科坐诊医生有', 'NN'), (':', 'SYM'), ('张三', 'FW'), ('(', 'FW'), ('主任', 'FW'), (')', 'FW'), ('、', 'FW'), ('李四', 'FW'), ('(', 'FW'), ('副主任', 'FW'), (')', 'FW'), ('、', 'FW'), ('李丽', 'FW'), ('(', 'FW'), ('副主任', 'FW'), (')', 'FW'), (',', 'FW'), ('请问您需要预约哪位医生', 'FW'), ('?', 'FW'), ('预约张三医生', 'JJ'), ('。', 'NN'), ('好的', 'NN'), (',', 'CD'), ('张三医生今日坐诊剩余时段号有10号', 'CD'), ('(', 'CD'), ('9:00', 'CD'), ('—', ':'), ('9:20', 'CD'), (')', 'CD'), ('、', 'NN'), ('16号', 'CD'), ('(', 'CD'), ('11:00', 'CD'), ('—', ':'), ('11:20', 'CD'), (')', 'CD'), ('。', 'NN'), ('就预约3号吧', 'CD'), ('。', 'CD'), ('好的', 'NN'), ('。', 'SYM'), ('请登记您的姓名和身份证号', 'NN'), ('。', 'SYM'), ('我叫王五', 'CD'), (',', 'CD'), ('身份证号1234567', 'CD'), ('。', 'NN')]
中文命名实体识别
中文命名实体识别: [('你好', 'O'), (',', 'NUMBER'), ('我要预约', 'NUMBER'), ('。', 'O'), ('好的', 'O'), (',', 'NUMBER'), ('请问您要预约门诊部还是住院部', 'NUMBER'), ('?', 'O'), ('我要预约门诊部', 'O'), ('。', 'O'), ('好的', 'O'), (',', 'NUMBER'), ('请问您要预约什么科室', 'NUMBER'), ('。', 'O'), ('我要预约心血管科', 'O'), ('。', 'O'), ('今日心血管科坐诊医生有', 'O'), (':', 'O'), ('张三', 'O'), ('(', 'O'), ('主任', 'O'), (')', 'O'), ('、', 'O'), ('李四', 'O'), ('(', 'O'), ('副主任', 'O'), (')', 'O'), ('、', 'O'), ('李丽', 'O'), ('(', 'O'), ('副主任', 'O'), (')', 'O'), (',', 'O'), ('请问您需要预约哪位医生', 'O'), ('?', 'O'), ('预约张三医生', 'O'), ('。', 'O'), ('好的', 'O'), (',', 'NUMBER'), ('张三医生今日坐诊剩余时段号有10号', 'NUMBER'), ('(', 'NUMBER'), ('9:00', 'TIME'), ('—', 'O'), ('9:20', 'TIME'), (')', 'NUMBER'), ('、', 'O'), ('16号', 'NUMBER'), ('(', 'NUMBER'), ('11:00', 'TIME'), ('—', 'O'), ('11:20', 'TIME'), (')', 'NUMBER'), ('。', 'O'), ('就预约3号吧', 'NUMBER'), ('。', 'NUMBER'), ('好的', 'O'), ('。', 'O'), ('请登记您的姓名和身份证号', 'O'), ('。', 'O'), ('我叫王五', 'NUMBER'), (',', 'NUMBER'), ('身份证号1234567', 'NUMBER'), ('。', 'O')]
matplotlib 绘图
统计人数
root_path = '/home/tione/notebook/任务四'
excel_path = os.path.join(root_path,'hosptial.xls')
row_list = read_excel(excel_path)
from collections import defaultdict
sex_count = defaultdict(int)
person_per_day_count = defaultdict(int)
person_per_clinic_count = defaultdict(int)
for name, sex, age, clinic, date in row_list:
if name == '姓名':
continue
sex_count[sex] += 1
person_per_day_count[date] += 1
person_per_clinic_count[clinic] += 1
print('近五天急诊科男女分别的人数:', dict(sex_count))
print('近五天来医院就诊的人数:', dict(person_per_day_count))
print('近五天每个诊室就诊人数:',dict(person_per_clinic_count))
统计人数-结果
近五天急诊科男女分别的人数: {'boy': 9, 'girl': 7}
近五天来医院就诊的人数: {'2023.1.1': 3, '2023.1.2': 2, '2023.1.3': 4, '2023.1.4': 3, '2023.1.5': 4}
近五天每个诊室就诊人数: {'EW': 2, 'OD': 4, 'DD': 4, 'IMD': 2, 'ED': 4}
绘制饼状图
%matplotlib inline
import matplotlib.pyplot as plt
"""
近五天急诊科就诊男女比例生成饼状图并保存图片
表头设置为’Male to female ratio in the last five days of emergency department’
"""
plt.figure()
plt.pie(sex_count.values(), labels=sex_count.keys())
plt.title('Male to female ratio in the last five days of emergency department')
plt.savefig('sex.jpg')
plt.show()
绘制柱状图
%matplotlib inline
import matplotlib.pyplot as plt
"""
近五天每个诊室就诊人数生成柱状图并保存图片
表头设置为’Number of visits per consultation room’
xlabel设置为’consulting room’
ylabel设置为’number’
"""
plt.figure()
plt.bar(person_per_clinic_count.keys(), person_per_clinic_count.values())
plt.title('Number of visits per consultation room')
plt.xlabel('consulting room')
plt.ylabel('number')
plt.savefig('clinic.jpg')
plt.show()
绘制折线图
%matplotlib inline
import matplotlib.pyplot as plt
"""
近五天来医院就诊的人数生成折线图并保存图片
表头设置为’The number of people who came to the hospital in the last five days’
xlabel设置为’day’
ylabel设置为’number’
"""
plt.figure()
plt.plot(person_per_day_count.keys(), person_per_day_count.values())
plt.title('The number of people who came to the hospital in the last five days')
plt.xlabel('day')
plt.ylabel('number')
plt.savefig('day.jpg')
plt.show()