基于PaddleHub的Fine-tune讯飞医疗搜索意图识别
项目地址: https://aistudio.baidu.com/aistudio/projectdetail/4523108?contributionType=1
欢迎fork
一、医疗搜索意图识别挑战赛简介
地址:https://challenge.xfyun.cn/topic/info?type=medical-search&option=ssgy
随着人们的生活质量逐步提高,老百姓更加关注医疗监控问题。但现在仍然存在患者和医生比例不对等的情况,患者需要贴近生活的「智能医生」。在医疗对话和搜索中,如果能设计一个智能算法对患者的搜索或对话意图进行分类,可为后续患者分诊提供帮助。
1.赛事任务
本次赛题需要选手对患者的对话和搜索问题进行处理,识别出意图类别。案例如下:
2.评审规则
2.1 数据说明
赛题数据由训练集和测试集组成,训练集数据集读取代码:
2.2 评估指标
本次竞赛的评价标准采用准确率指标,最高分为1。
计算方法参考:https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html
评估代码参考:
2.3 评测及排行
1、赛事提供下载数据,选手在本地进行算法调试,在比赛页面提交结果。
2、每支团队每天最多提交3次。
3、排行按照得分从高到低排序,排行榜将选择团队的历史最优成绩进行排名。
2.4作品提交要求
文件格式:预测结果文件按照csv格式提交
文件大小:无要求
提交次数限制:每支队伍每天最多3次
预测结果文件详细说明:
-
以csv格式提交,编码为UTF-8,第一行为表头;
-
标签顺序需要与测试集文本保持一致;
-
提交前请确保预测结果的格式与sample_submit.csv中的格式一致。具体格式如下:
3.意图分析
经分析,该题目是意图识别,其实也就是句子分类。下面使用分类模型进行处理。
二、数据处理
1.解压缩
!unzip -qoa data/data166530/yt.zip
2.数据查看
import pandas as pd
train=pd.read_csv("yt/train.csv",sep = '\t')
train.head()
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
text | label | |
---|---|---|
0 | 治痔疮会影响上班吗,医保有报吗?外痔。有无报销。会否影响工作 | 多问 |
1 | 本人今年16,最近感觉睾丸多长了一块肉,不痛不痒的,是睾丸癌吗 | 临床表现(病症表现) |
2 | 痔疮手术几个月后,肛门周围有长了一个,吃辣的东西就会肿起来,怎么办?是术后复发了吗? | 多问 |
3 | 你好,我宝宝8kg,吃美林要吃多少啊?你好,我宝宝8kg,吃美林要吃多少啊? | 用法 |
4 | 请问月经量多服用什么药? | 适用症 |
train["text_a"]=train["text"]
train=train.drop('text',axis=1)
label_unique_list=train.label.unique()
label_list_id=[i for i in range(10)]
print(label_unique_list)
print(label_list_id)
['多问' '临床表现(病症表现)' '用法' '适用症' '定义' '病因' '治疗方法' '无法确定' '作用' '方法']
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
train=train[['label', 'text_a']]
train.head(10)
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
label | text_a | |
---|---|---|
0 | 多问 | 治痔疮会影响上班吗,医保有报吗?外痔。有无报销。会否影响工作 |
1 | 临床表现(病症表现) | 本人今年16,最近感觉睾丸多长了一块肉,不痛不痒的,是睾丸癌吗 |
2 | 多问 | 痔疮手术几个月后,肛门周围有长了一个,吃辣的东西就会肿起来,怎么办?是术后复发了吗? |
3 | 用法 | 你好,我宝宝8kg,吃美林要吃多少啊?你好,我宝宝8kg,吃美林要吃多少啊? |
4 | 适用症 | 请问月经量多服用什么药? |
5 | 定义 | 什么是心悸怔忡 |
6 | 病因 | 支气管扩张症是什么原因引起的? |
7 | 病因 | 我最近总是感觉喘息不对,声音很粗重还很急促而且经常感觉胸闷咳嗽,有时甚至会呼吸困难,我很担心... |
8 | 病因 | 请问尿失禁是怎么回事 |
9 | 病因 | 导致慢性支气管炎的原因是什么 |
%matplotlib inline
print(max(train['text_a'].str.len()))
print( train["label"].value_counts())
train.groupby(['label']).count().plot(kind='bar')
221
治疗方法 468
临床表现(病症表现) 313
多问 255
病因 233
适用症 223
无法确定 207
作用 124
定义 102
用法 100
方法 99
Name: label, dtype: int64
<matplotlib.axes._subplots.AxesSubplot at 0x7f2c5f0ea590>
3.数据增强
拟采用同义词替换方式进行数据增强
3.1数据增强工具包安装
https://pypi.org/project/nlpcda/
nlpcda是中文数据增强工具,支持多种数据增强方法:
- 1.随机实体替换
- 2.近义词
- 3.近义近音字替换
- 4.随机字删除(内部细节:数字时间日期片段,内容不会删)
- 5.NER类
BIO
数据增强 - 6.随机置换邻近的字:研表究明,汉字序顺并不定一影响文字的阅读理解<<是乱序的
- 7.中文等价字替换(1 一 壹 ①,2 二 贰 ②)
- 8.翻译互转实现的增强
- 9.使用
simbert
做生成式相似句生成
!pip install -q nlpcda
3.2 同义词增强
参数:
-
base_file :缺省时使用内置同义词表,你可以设定/自己指定更加丰富的同义词表:
是文本文件路径,内容形如(空格隔开):
Aa01A0 人类 生人 全人类
id2 同义词b1 同义词b2 … 同义词bk
…
idn 同义词n1 同义词n2\ -
create_num=3 :返回最多3个增强文本
-
change_rate=0.3 : 文本改变率
-
seed : 随机种子
from nlpcda import Similarword
smw = Similarword(create_num=1, change_rate=0.3)
new_train=train
for index, row in train.iterrows():
results=smw.replace(row['text_a'])
for result in results:
new_train.loc[1]=[row['label'], result]
Building prefix dict from the default dictionary ...
Loading model from cache /tmp/jieba.cache
Simbert不能正常使用,除非你安装:bert4keras、tensorflow ,为了安装快捷,没有默认安装.... No module named 'bert4keras'
Loading model cost 0.737 seconds.
Prefix dict has been built successfully.
load :/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/nlpcda/data/同义词.txt done
3.3 近义词增强
参数:
-
base_file :缺省时使用内置【同义同音字表】,你可以设定/自己指定更加丰富的同义同音字表:
是文本文件路径,内容形如(\t隔开):
de 的 地 得 德 嘚 徳 锝 脦 悳 淂 鍀 惪 恴 棏
拼音2 字b1 字b2 … 字bk
…
拼音n 字n1 字n2\ -
create_num=3 :返回最多3个增强文本
-
change_rate=0.3 : 文本改变率
-
seed : 随机种子
from nlpcda import Homophone
smw = Homophone(create_num=1, change_rate=0.3)
for index, row in train.iterrows():
results=smw.replace(row['text_a'])
for result in results:
new_train.loc[1]=[row['label'], result]
load :/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/nlpcda/data/同音意字.txt done
3.4 等价词替换
参数:
-
base_file :缺省时使用内置【等价数字字表】,你可以设定/自己指定更加丰富的等价字表(或者使用函数:add_equivalent_list):
是文本文件路径,内容形如((\t)隔开):
0 零 〇
1 一 壹 ①
…
9 九 玖 ⑨ -
create_num=3 :返回最多3个增强文本
-
change_rate=0.3 : 文本改变率
-
seed : 随机种子
from nlpcda import EquivalentChar
smw = EquivalentChar(create_num=1, change_rate=0.3)
for index, row in train.iterrows():
results=smw.replace(row['text_a'])
for result in results:
new_train.loc[1]=[row['label'], result]
load :/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/nlpcda/data/等价字.txt done
# 数据增强后回复给原train
train=new_train
4.数据集划分
train_df = train.sample(frac=0.7,random_state=0,axis=0)
validation_df = train[~train.index.isin(train_df.index)]
train_df.to_csv("yt/train_ok.csv", index=None,sep="\t")
validation_df.to_csv("yt/val_ok.csv", index=None,sep="\t")
!head yt/train_ok.csv
label text_a
无法确定 不知道自己怀孕啦,我以为是吃药把胃吃坏啦才知道怀孕啦
病因 前几天便秘夜间躺下是有那种绞痛感持续几秒时间就消失了今天解了大便晚上症状消失但肚脐下方按压痛请问这和便秘有关吗
多问 我53岁已经没有例假了,是更年期的年龄吗?乌灵胶囊:用于心肾不交所致的失眠、健忘、心悸心烦、神疲乏力。能喝这个吧?
无法确定 总胆固醇不高但颈椎,用什么药治疗对身体影响小一点啊
临床表现(病症表现) 小便时痛是怎么回事,这个情况已经有一个多星期了开始时没有注意
病因 宝宝打嗝是什么原因啊?
作用 维思通是起什么作用的
临床表现(病症表现) 男人小便出血是怎么回事
无法确定 请问阴道炎对月经有没有影响?
三、环境构建
ERNIE 通过建模海量数据中的词、实体及实体关系,学习真实世界的语义知识。相较于 BERT 学习原始语言信号,ERNIE 直接对先验语义知识单元进行建模,增强了模型语义表示能力,以 Transformer 为网络基本组件,以Masked Bi-Language Model和 Next Sentence Prediction 为训练目标,通过预训练得到通用语义表示,再结合简单的输出层,应用到下游的 NLP 任务。本示例展示利用ERNIE进行文本分类任务。
1.paddlehub安装
!pip install -U -q paddlehub
2.模型下载
PaddleHub还提供BERT等模型可供选择, 当前支持文本分类任务的模型对应的加载示例如下:
模型名 | PaddleHub Module |
---|---|
ERNIE, Chinese | hub.Module(name='ernie') |
ERNIE tiny, Chinese | hub.Module(name='ernie_tiny') |
ERNIE 2.0 Base, English | hub.Module(name='ernie_v2_eng_base') |
ERNIE 2.0 Large, English | hub.Module(name='ernie_v2_eng_large') |
BERT-Base, English Cased | hub.Module(name='bert-base-cased') |
BERT-Base, English Uncased | hub.Module(name='bert-base-uncased') |
BERT-Large, English Cased | hub.Module(name='bert-large-cased') |
BERT-Large, English Uncased | hub.Module(name='bert-large-uncased') |
BERT-Base, Multilingual Cased | hub.Module(nane='bert-base-multilingual-cased') |
BERT-Base, Multilingual Uncased | hub.Module(nane='bert-base-multilingual-uncased') |
BERT-Base, Chinese | hub.Module(name='bert-base-chinese') |
BERT-wwm, Chinese | hub.Module(name='chinese-bert-wwm') |
BERT-wwm-ext, Chinese | hub.Module(name='chinese-bert-wwm-ext') |
RoBERTa-wwm-ext, Chinese | hub.Module(name='roberta-wwm-ext') |
RoBERTa-wwm-ext-large, Chinese | hub.Module(name='roberta-wwm-ext-large') |
RBT3, Chinese | hub.Module(name='rbt3') |
RBTL3, Chinese | hub.Module(name='rbtl3') |
ELECTRA-Small, English | hub.Module(name='electra-small') |
ELECTRA-Base, English | hub.Module(name='electra-base') |
ELECTRA-Large, English | hub.Module(name='electra-large') |
ELECTRA-Base, Chinese | hub.Module(name='chinese-electra-base') |
ELECTRA-Small, Chinese | hub.Module(name='chinese-electra-small') |
!hub install roberta-wwm-ext-large
[32m[2022-09-10 14:56:17,391] [ INFO][0m - Module roberta-wwm-ext-large already installed in /home/aistudio/.paddlehub/modules/roberta_wwm_ext_large[0m
[0m
四、模型Fine-tune
# 设置使用的GPU卡号
!export CUDA_VISIBLE_DEVICES=0
import paddlehub as hub
model = hub.Module(name='roberta-wwm-ext-large', task='seq-cls', num_classes=10)
[2022-09-10 14:56:20,673] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/roberta-wwm-ext-large/roberta_chn_large.pdparams
W0910 14:56:20.677435 25230 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 11.2
W0910 14:56:20.681991 25230 gpu_resources.cc:91] device: 0, cuDNN Version: 8.2.
1.自定义数据集
from typing import Dict, List, Optional, Union, Tuple
import os
from paddlehub.env import DATA_HOME
from paddlehub.utils.download import download_data
from paddlehub.datasets.base_nlp_dataset import TextClassificationDataset
from paddlehub.text.bert_tokenizer import BertTokenizer
from paddlehub.text.tokenizer import CustomTokenizer
class MyDataset(TextClassificationDataset):
def __init__(self, tokenizer: Union[BertTokenizer, CustomTokenizer], max_seq_len: int = 128, mode: str = 'train'):
base_path = "yt"
if mode == 'train':
data_file = 'train_ok.csv'
elif mode=="val":
data_file = 'val_ok.csv'
super().__init__(
base_path=base_path,
tokenizer=tokenizer,
max_seq_len=max_seq_len,
mode=mode,
data_file=data_file,
label_list=['多问', '临床表现(病症表现)', '用法' ,'适用症', '定义', '病因' ,'治疗方法', '无法确定', '作用', '方法'],
is_file_with_header=True)
2.Reader定义
接着生成一个文本分类的reader,reader负责将dataset的数据进行预处理,首先对文本进行切词,接着以特定格式组织并输入给模型进行训练。
ClassifyReader
的参数有以下三个:
dataset
: 传入PaddleHub Dataset;vocab_path
: 传入ERNIE/BERT模型对应的词表文件路径;max_seq_len
: ERNIE模型的最大序列长度,若序列长度不足,会通过padding方式补到max_seq_len
, 若序列长度大于该值,则会以截断方式让序列长度为max_seq_len
;
train_dataset = MyDataset(tokenizer=model.get_tokenizer(), max_seq_len=221, mode='train')
val_dataset = MyDataset(tokenizer=model.get_tokenizer(), max_seq_len=221, mode='val')
[2022-09-10 14:56:26,339] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/roberta-wwm-ext-large/vocab.txt
[2022-09-10 14:56:26,739] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/roberta-wwm-ext-large/vocab.txt
3.选择优化策略和运行配置
# 设置使用的GPU卡号
!export CUDA_VISIBLE_DEVICES=0
import paddle
optimizer = paddle.optimizer.Adam(learning_rate=5e-5, parameters=model.parameters())
trainer = hub.Trainer(model, optimizer, checkpoint_dir='test_ernie_text_cls', use_gpu=True)
trainer.train(train_dataset=train_dataset, eval_dataset=val_dataset,epochs=5, batch_size=32, save_interval=1)
五、模型预测
当完成Fine-tune后,Fine-tune过程在验证集上表现最优的模型会被保存在 {CHECKPOINT_DIR}目录为Fine-tune时所选择的保存checkpoint的目录。
1.读取数据
import numpy as np
import pandas as pd
test=pd.read_csv('yt/test.csv',sep='\t')
test_list=np.array(test.text).tolist()
print(len(test_list))
2000
test_data=[]
for item in test_list:
test_data.append([item])
print(test_data[:10])
[['四磨汤口服液的成分是什么,可以改善腹痛腹泻的情况吗?'], ['阴茎上长泡是怎么回事?'], ['21金维他多维元素片适用于怎样的营养补给'], ['臀部护理是不是应该有什么步骤和用品呢?都应该怎么进行?'], ['您的答复我收到了,谢谢!我还想在问一下,如果胸腔积液继续增加有什么好的办法解决吗?今天下午感觉胸闷又排了五百多毫升我观察比前几次浓度增加了。'], ['晕痛定胶囊这个药物能不能长期吃的啊,不知道治疗偏头痛怎么样呢'], ['医师你好,我女儿右腿左侧胎生血管瘤,现在还显瘀青色,有人建议激光治疗,激光对她太疼,有什么更好的治疗?内蒙古婴儿的血管瘤长手上危害大不大?'], ['月见草油胶丸会导致大便稀?需要停止用药吗?'], ['宝宝经常性便秘怎么办?'], ['有没有人知道在深圳哪个药房才可以买到益肾蠲痹丸这个药物呢?']]
label_list=['多问', '临床表现(病症表现)', '用法' ,'适用症', '定义', '病因' ,'治疗方法', '无法确定', '作用', '方法']
label_map = {}
for i in range(10):
label_map[i]=label_list[i]
print(label_map)
{0: '多问', 1: '临床表现(病症表现)', 2: '用法', 3: '适用症', 4: '定义', 5: '病因', 6: '治疗方法', 7: '无法确定', 8: '作用', 9: '方法'}
2.模型预测
import paddlehub as hub
model = hub.Module(
name='ernie_tiny',
version='2.0.1',
task='seq-cls',
load_checkpoint='./test_ernie_text_cls/best_model/model.pdparams',
label_map=label_map)
results = model.predict(test_data, max_seq_len=221, batch_size=1, use_gpu=True)
[2022-09-10 15:03:03,990] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/ernie-tiny/ernie_tiny.pdparams
[2022-09-10 15:03:07,737] [ INFO] - Loaded parameters from /home/aistudio/test_ernie_text_cls/best_model/model.pdparams
[2022-09-10 15:03:07,749] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/ernie-tiny/vocab.txt
[2022-09-10 15:03:07,751] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/ernie-tiny/spm_cased_simp_sampled.model
[2022-09-10 15:03:07,753] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/ernie-tiny/dict.wordseg.pickle
print(results[0])
print(len(results))
定义
2000
3.保存结果
f=open('result.csv','w')
f.write('label\n')
for idx in range(len(results)):
f.write(results[idx]+'\n')
f.close()
六、提交
下载提交,即可出分数
- 另:可划分 train 和 eval ,选取最佳模型
- 点赞
- 收藏
- 关注作者
评论(0)