Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

NER

数据来源

MRSA微软亚洲研究院的标注语料 [B, I, O] * [PER, LOC, ORG]

特征选取与定义

字符角色定义

BIESO (其他的字符角色定义还有很多)

  • B, 即Begin, 表示开始
  • I, 即Intermediate, 表示中间
  • E, 即End, 表示结尾
  • S, 即Single, 表示单个字符
  • O, 即Other, 表示其他, 用于标记无关字符

实体类别定义

命名实体识别中常见的实体类别有:

  • PERSON 人名
  • LOCATION 地名
  • ORGNIZATION 机构名
  • TIME 时间

但是在其他领域, 如医学领域, 实体类别可细分为:

  • TREATMENT 治疗方式
  • BODY 身体部位
  • SIGNS 疾病症状
  • CHECK 医学检查
  • DISEASE 疾病实体
  • MEDICINE 药物实体

在训练预料中, 结合字符角色定义和实体类别定义, 一个句子(一个句子即为一个序列, 以换行符'\n'分隔)按照字符(word/char)可标注为:

美 B-LOC
国 I-LOC
的 O
华 B-PER
莱 B-PER
士 B-PER
,  O
我 O
和 O
他 O
谈 O
笑 O
风 O
生 O
。 O

针对语料的不同, 亦可在此基础上添加其他特征, 如增加“非汉字字符串”的定义。

模型选取

NER通常被转换成文本表示和分类任务, 类别即我们根据特征定义的字符角色和实体类别的排列组合

CRF

条件随机场, 传统的机器学习模型,在深度学习模型中通常作为最后的标签推断层。

BiLSTM-CRF

BiLSTM是Bi-directional Long Short-Term Memory的缩写, 是由前向LSTM与后向LSTM组合而成, 常被用来建模上下文信息。

  1. 使用预训练字向量作为embedding层输入, 否则, 随机化初始字向量;
  2. 然后经过两个双向LSTM层进行编码, 编码后加入dense全连接层;
  3. 最后输入CRF层进行序列标注。

在这里, 我们使用开源的基于中文维基百科训练的100维的字向量作为embedding层(实验证明随机初始化字向量,在同领域的验证集也能达到较好的效果), 在blstm_ner使用tag2label定义标签类别, 视具体任务而定。

在训练BiLSTM_CRF模型的过程中发现, 设置learning_rate=0.001, batch_size=64的收敛效率较好, 在第十几个epoch就达到了较好的效果。

learning_rate一般通过指数衰减调参,学习率决定了参数每次更新的幅度, 如果幅度过大, 那么可能导致参数在极优值得两侧来回移动;如果幅度过小, 虽然能保证收敛性, 但这会大大降低优化速度。

batch_size一般从128开始上下浮动。一个batch即批训练一次神经网络, 计算损失函数, 利用梯度下降更新网络参数。batch越大其越能代表整个数据集的分布, 但越大也意味着计算量越大, 收敛越慢。

注意,由于LSTM的遗忘机制,在训练时dropout要设置得大一点,一般取0.5。

BERT

BERT(Bidirectional Encoder Representations from Transfoemers), 是预训练好的语言模型, 可应用于不同的NLP下游任务。

扩展阅读: 从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史

在这里, 我们使用预训练的Bert中文模型作为embedding层, 在get_lables里定义标签类别, 视具体任务而定。

return ["X",  "B-LOC",  "I-LOC",  "B-PER",  "I-PER",  "B-ORG",  "I-ORG",  "O",  "[CLS]",  "[SEP]"]

在训练Bert模型的过程中, 使用的是开源模型的参数learning_rate=2e-5, batch_size=32, 模型在验证集上的效果已经很好, 所以没有再调参数。

实验

Requirements

  • Python 3.5 (recommended)
  • TensorFlow >= 1.10.0
  • numpy >= 1.14.3
  • Anaconda (recommended on Windows)

注意

  • BERT在CPU上运行可能会卡机, 模型训练耗时约day+
  • Google Colab 提供了免费的GPU, 需要科学上网
  • 由于Git托管体积大的文件不方便,相关的训练集、词向量、预训练模型、下游任务训练模型已上传到网盘

链接 提取码: h8st

模型训练

cmd.exe不支持sh脚本, 可在git bash上执行, 或在控制台带参数运行, 对于不同的语料、输出和参数, 需要相应地修改sh脚本

  1. BERT / BERT + CRF / BERT + BiLSTM / BERT + BiLSTM + CRF
bash run_bert_ner.sh
#!/usr/bin/env bash

# 部分参数在bert_ber中有默认值
python bert_ner.py
    --do_lower_case=False \
    --do_train=True   \
    --do_eval=True   \
    --do_test=True \
    --data_dir=./data/MSRA/   \
    --vocab_file=data/vocab.txt   \
    --bert_config_file=chinese_L-12_H-768_A-12/bert_config.json   \
    --init_checkpoint=chinese_L-12_H-768_A-12/bert_model.ckpt   \
    --max_seq_length=128   \
    --train_batch_size=32   \
    --learning_rate=2e-5   \
    --num_train_epochs=10.0   \
    --dropout_rate=0.5   \
    --output_dir=./output/MSRA/bert_bilstm_crf/   \
    --bilstm=True   \
    --crf=True

由于训练样本大,只需训练4-5个epoch就能达到不错的效果,再多有点过拟合。

  1. BiLSTM / BiLSTM + CRF
bash run_bilstm_ner.sh
python blstm_ner.py\
    --data_dir=./data/MSRA   \
    --output_dir=./output/MSRA/char2vec_blstm_crf/   \
    --vocab_file=./data/wiki/char2id.pkl   \
    --embedding_file=./data/wiki/char2vec.txt   \
    --embedding_source=./data/wiki/wiki_100.utf8.txt   \
    --lr=0.001   \
    --num_train_epochs=40   \
    --batch_size=64   \
    --CRF=True   \
    --mode=train

应用

输入新文本, 抽取目标实体

若从文件读入文本,设置file_input=<file_name under data_dir>,默认在txt2seq.py中以r'([。?!])'切割句子,如果切割后序列长度仍超出128-2(CLS和SEP),则继续以切割。

若从控制台交互输入文本,设置raw_input=True,长度超过128-2会自动截断(尝试训练max_seq_length=256的模型但是提示内存溢出)。

在预测过程中,可能会出现字典文件vocab.txt未包含的字符,以[UNK]输出,可手动更新[unused1~99]另存为vocab_update文件。

目标实体以句子为单位输出。

另外,可在seq2entity.py中加入规则,抽取其他类型的实体,如《》。

(Attention: args 不支持 raw_input=False,只要加上该参数就会设置为True,所以还是flags更灵活一点吧)

  1. BERT / BERT + CRF / BERT + BiLSTM / BERT + BiLSTM + CRF
cd application
bash run_predict.sh

data_dir不是训练语料的目录,而是应用文本的目录,最好分开,最终输出的实体文件和日志文件也会保存在这里.

init_checkpoint是训练好的模型,预测的时候会从该文件里重加载神经网络模型的参数.

output_dir是训练模型的保存路径,用来重载某些依赖文件,如label2id.pkl.

  1. BiLSTM / BiLSTM + CRF
python blstm_ner.py\
    --data_dir=./data/ywsz/   \
    --output_dir=./output/ChinaDaily/blstm_crf/   \
    --vocab_file=./data/wiki/char2id.pkl   \
    --embedding_file=./data/wiki/char2vec.txt   \
    --CRF=True   \
    --mode=predict   \
  • incremental learning
You can’t perform that action at this time.