nlp实验--基于CRF的药物副作用的实体识别(Wapiti)
一、实验环境
ubuntu系统、python3.6
Wapiti工具环境配置
mkdir myproject
cd myproject
git clone https://github.com/Jekub/Wapiti.git
cd Wapiti
make
make install
./wapiti
(./wapiti有帮助文档输出表示安装成功)
工作环境配置
cd myproject
git clone https://github.com/kyzhouhzau/2019SpringTextM.git
二、数据描述
训练数据
训练数据有100个Drug Label
测试数据
34个测试数据存放在2019SpringTextM/need_drug目录下
三、数据处理
训练数据和测试数据的格式均为XML格式,但在训练模型和测试前均需要对数据进行预处理,将数据处理成“.tab”格式。
训练数据预处理
cd 2019SpringTextM
python3 tac2brat.py -d train_xml -o outtrain -F TokenDict:diso:diso-DISO.dic -t conll -s OBBEI
说明:运行2019SpringTextM中的tac2brat.py文件,将train_xml中的训练数据进行预处理,转变为“.tab”文件,存入outtrain文件夹。
-d 训练文件夹
-o 预处理结果输出文件夹
-F字典特征
-t 输出格式
-s 标签格式
outtrain文件夹里面的内容展示如下:
打开其中一个.tab文件,文件显示内容:单词名+协助溯源的信息(文件名:所属段落:起始段落:单词长度)+字典特征+实体标签。
在实体标签中,我们使用的标签方式称为”BIEO”,其中B-type 表示begin, I-type 表示Inside, E-type 表示End, O 表示不属于该标签。
测试数据预处理
cd 2019SpringTextM
python3 to_xml_needed.py need_drug output
python3 tac2brat.py -d output -o outtest -F TokenDict:diso:diso-DISO.dic -t conll -s OBBEI
可以发现,目前测试数据的实体标签全部显示为“O”。
四、模型训练
调整参数优化模型
sudo bash dev-wapiti.sh
如果在结果中FB1的值太低,说明需要修改2019SpringTextM/pat目录下的Tok321dis .pat文件里面的特征,使得FB1的值更加理想.
修改后的pat文件如下:
这样相对于输出序列而言的表示方式是Unigram模板,意思是前一个数据,后一个数据和当前的数据构成的上下文对当前标签的影响,还有一种表示方式是Bigram模板,这个模板会考虑当前输出标签和上一个输出标签。
修改pat里面的特征调整参数优化模型之后的结果如下:
预测测试数据
sudo bash test_wapiti.sh
在这里遇到如下报错:
发现wapiti文件现在在Wapiti文件夹下,将其位置移动到Wapiti/bin文件夹下即可。
预测结果如下:
出现Finished!说明序列标注完成。
序列标注结果存储在2019SpringTextM/eval/bio/Tok321dis-train-test-outtrain.tab 中。
标注得到的结果内容较多,其中部分内容如下,此时,测试数据的预测结果显示在.tab文件的最后一列。
五、实验进阶要求
不同Unigram模板的效果差异分析
该部分参考crf++里的特征模板
CRF++包中模板构建分为两类,一类是Unigram标注,一类是Bigram标注。Unigram模板是比较常用的模板,这类模板提取的信息较为全面,组成的模板数量也比较多;Bigram模板比较简单,一般是当前词和前面一个词的自动组合生成的Bigram特征集合。
特征模板格式:%x[row,col]。x可取U或B,对应两种类型。方括号里的编号用于标定特征来源,row表示相对当前位置的行,0即是当前行;col对应训练文件中的列。
Unigram类型每一行模板生成一组状态特征函数,数量是L*N 个,L是标签状态数。N是此行模板在训练集上展开后的唯一样本数。
举个例子。假设有如下用于分词标注的训练文件:
北 N B
京 N E
欢 V B
迎 V I
你 N E
例如:U01:%x[0,0],生成如下15个函数:
func1 = if (output = B and feature=U01:“北”) return 1 else return 0
func2 = if (output = Iand feature=U01:“北”) return 1 else return 0
func3 = if (output = E and feature=U01:“北”) return 1 else return 0
func4 = if (output = B and feature=U01:“京”) return 1 else return 0
…
func13 = if (output = B and feature=U01:“你”) return 1 else return 0
func14 = if (output = I and feature=U01:“你”) return 1 else return 0
func15 = if (output = E and feature=U01:“你”) return 1 else return 0
每个模板会把所有可能的标记输出都列一遍,然后通过训练确定每种标记的权重,合理的标记在训练样本中出现的次数多,对应的权重就高,不合理的标记在训练样本中出现的少,对应的权重就少。
利用模板生成转移特征函数会把所有可能的特征函数都列出来,模型可以通过训练决定每个特征的重要程度。
在本次实验中,我们可以通过修改2019SpringTextM/pat目录下Tok321dis .pat文件里面的特征来比较效果差异。
当U:%X[row,col]的模板如下所示时:
该模型的precision、recall和FB1值如下图所示:
当U:%X[row,col]的模板如下所示时:
该模型的precision、recall和FB1值如下图所示:
我们发现,当U:%X[row,col]的模板数越多,该模型的FB1值越理想,这个训练模型的标注能力越好。
.sh集成命令解读
调整参数优化模型中用到的dev-wapiti.sh是一个命令集成文件。
相对应,预测测试数据环节用到的test_wapiti.sh也是一个命令集成文件。
训练集(train set) —— 用于模型拟合的数据样本。
验证集(development set)—— 是模型训练过程中单独留出的样本集,它可以用于调整模型的超参数和用于对模型的能力进行初步评估。
测试集 (test set) —— 用来评估模最终模型的泛化能力。但不能作为调参、选择特征等算法相关的选择的依据。
一个形象的比喻:
训练集-----------学生的课本;学生 根据课本里的内容来掌握知识。
验证集------------作业,通过作业可以知道 不同学生学习情况、进步的速度快慢。
测试集-----------考试,考的题是平常都没有见过,考察学生举一反三的能力。
此时,outtrain/[A-S]数据是训练集,outtrain/[T-Z]数据是验证集,outtest数据是测试集。
分析dev-wapiti.sh
命令解读:dev-wapiti.sh 完成以下任务:
1.生成 wapiti 模型,使用 Tok321dis.pat 模板,用训练集outtrain/[A-S]*.tab训练模型,pat结果存入 Tok321dis-train-outtrain.mod 中。’ -a sgd-l1 -t 3 -i 10 '是训练指令。
2.用刚训练好的模型标注outtrain/[T-Z]*.tab验证集,标注结果存入 eval/bio/Tok321dis-train-
test-outtrain.tab。
3.用 conlleval.pl 脚本评估验证集训练结果 eval/bio/Tok321dis-train-
test-outtrain.tab,将评估结果放入 eval/bio/Tok321dis-train-test-
outtrain.eval。
也就是说,我们在终端运行运行"sudo bash dev-wapiti.sh"命令实际上就是在运行如下几条命令:
sudo chmod -R 777 eval/bio/Tok321dis-train-outtrain.mod
wapiti train -a sgd-l1 -t 3 -i 10 -p pat/Tok321dis.pat <(cat outtrain/[A-S]*.tab) eval/bio/Tok321dis-train-outtrain.mod
sudo chmod -R 777 eval/bio/Tok321dis-train-test-outtrain.tab
wapiti label -c -m eval/bio/Tok321dis-train-outtrain.mod <(cat outtrain/[T-Z]*.tab) eval/bio/Tok321dis-train-test-outtrain.tab
sudo chmod -R 777 eval/bio/Tok321dis-train-test-outtrain.eval
sudo perl ./conlleval.pl -d $'\t' <eval/bio/Tok321dis-train-test-outtrain.tab | tee eval/bio/Tok321dis-train-test-outtrain.eval
分析test_wapiti.sh
命令解读:test_wapiti.sh 完成以下任务:
1.生成 wapiti 模型,使用 Tok321dis.pat 模板,用整个训练集outtrain(之前的训练集+验证集) 训练模型,pat结果存入 Tok321dis-train-outtrain.mod 中。’ -a sgd-l1 -t 3 -i 10 '是训练指令。
2.用刚训练好的模型标注测试集outtest,标注结果存入 eval/bio/Tok321dis-train-test-outtrain.tab。
也就是说,我们在终端运行运行"sudo bash test_wapiti.sh"命令实际上就是在运行如下几条命令:
wapiti train -a sgd-l1 -t 3 -i 10 -p pat/Tok321dis.pat <(cat outtrain/*.tab) eval/bio/Tok321dis-train-outtrain.mod
wapiti label -c -m eval/bio/Tok321dis-train-outtrain.mod <(cat outtest/*) eval/bio/Tok321dis-train-test-outtrain.tab
参考文件
实验指导书 基于CRF的药物副作用的实体识别
实验数据地址crf实验
crf++里的特征模板
训练集、验证集、测试集以及交验验证的理解