AlexYangLi / ccks2019_el

CCKS 2019 中文短文本实体链指比赛技术创新奖解决方案
https://biendata.com/competition/ccks_2019_el/
411 stars 80 forks source link
bert-ner bert-wwm bilstm-cnn ccks character-embeddings entity-disambiguation entity-linking entity-recognition knowledge-base knowledge-graph

Enhanced Character Embedding for Chinese Short Text Entity Linking

目录

详细设计

整体设计思路

本次比赛我使用的是 pipeline 的方式解决实体链接问题,即先进行实体识别,而后进行实体消歧。由于中文缺少显式的词语分割符,基于词序列的实体链接容易受分词错误影响。但基于字序列的实体链接又无法充分利用句子中单词的语义信息。因此本次比赛的整体设计思路是在子序列输入的基础上,加入额外的信息来增强字的语义表达,即使用 enhanced character embedding 解决中文短文本实体链接问题。具体而言,对于实体识别,由于要求所识别的实体必须存在于知识库中的 mention 库,因此考虑加入 mention 库匹配信息;而对于实体消歧,在同一文本中出现的不同 mention 的 representation 应该不同,因此考虑加入 mention 的位置信息。

实体识别

er_model 实体识别我采用经典的 BiLSTM+CNN+CRF 序列标注模型,输出使用 BIOES 标注。而在输入层上,我们除了使用字向量序列作为基础输入,还在此基础上拼接了一系列具有丰富语义信息,有助于识别实体 mention 边界的 embedding。拼接的 embedding 主要有:

实体消歧

el
实体消歧使用语义匹配的思路,我们使用待消歧文本以及知识库中候选实体所有三元组拼接起来的实体描述文本作为匹配文本对,使用神经网络对它们进行建模得到各自的 representation,然后使用 cosine 相似度进行匹配度打分,选择得分最高的候选实体输出。神经网络框架大体是 BiLSTM+CNN,由于待消歧文本与候选实体描述文本的长度相差较大,我们没有使用孪生网络结构。下面重点介绍 mention embedding 和 entity embedding 如何生成。

集成

为了提分,我们还采用了两种模型集成的方式。

项目配置与运行

数据准备

环境准备

pip install -r requirements.txt

训练

  1. 预处理

    python3 preprocess.py
  2. 实体识别模型训练

    python3 train_er.py
  3. 实体消歧模型训练

    python3 train_el.py

预测

python3 ensemble.py

代码执行完毕后,会在submit目录生成final_submit.json

预处理文件与已训练模型下载

我也把预处理后生成的文件以及自己线下训练好的模型上传到了百度云。下载完毕后,把文件放在对应的目录下即可。预处理文件放在data目录,模型文件放在ckpt目录。

FAQ

论文

论文和海报在paper文件夹

实体识别模型的命名

实体识别模型主要的区别在于输入的特征向量组合不同,以 2step_er_c2v_fix_32_adam_0.001_BIOES_encoder_type_bilstm_cnn_use_crf_True_swa_ernie_layer_1_fix_bichar_bic2v_fix_word_w2v_fix_charpos_cpos2v_fix_softword_dictfeat_maxmatch_swa 为例:

实体消歧模型的命名

实体消歧模型的区别主要在于如何产生 mention 表征和 entity 表征的方法不同:

  1. 2step_el_c2v_fix_32_adam_0.001_rel_neg_5_not_omit_score_func_cosine_margin_0.04_max_mention_True_add_cnn_after_swa_swa.hdf5
    • c2v_fix:字符向量的预训练方法 (c2v, c_fastext, c_glove) 以及在模型训练过程中是否可以微调 (fix, tune)
    • 32:batch_size
    • adam_0.001:optimizer和学习率
    • rel:产生mention表征的模型使用相对位置embedding输入
    • neg_5:负样本个数(5)
    • not_omit:不去掉只有一个候选实体的样本(无需消歧),默认会去掉
    • score_func_cosine:使用何种相似度度量函数(cosine, dense(即mlp), polynomial, sigmoid, euclidean等)
    • margin_0.04:损失函数中的margin的取值
    • max_mention_True:使用隐藏状态序列产生 mention 表征的时候,除了对取来自 mention 部分序列的第一个和最后一个隐藏状态向量,还有对该部分序列使用self-attention的结果之外,是否对该部分序列使用max-pooling(max_mention_True)以及avg-pooling(avg_mention_True)
    • add_cnn_after:是否在BiLSTM的基础上加上CNN,在BiLSTM前面(before)还是在后面加(after)
    • swa:采用权重平均集成策略
  2. 2step_el_c2v_fix_32_adam_0.001_rel_neg_4_score_func_cosine_margin_0.04_max_mention_True_encoder_type_self_attend_single_attend_ent_attend_type_mul_swa_swa.hdf5
    • encoder_type:在linking_model.py尝试了多种使用隐藏状态序列产生 mention 表征和 entity 表征的方法:1. "self_attend_max" 表示 mention 表征使用来自 mention 部分序列的self-attention结果(还有第一个和最后一个隐藏状态向量,可能还有max-pooling和avg-pooling的结果),而 entity 表征使用 max-pooling的结果,这是默认的方法;2. "self_attend_single_attend" 表示 mention 表征使用来自 mention 部分序列的self-attention结果(还有第一个和最后一个隐藏状态向量,可能还有max-pooling和avg-pooling的结果),而 entity 表征使用 mention 表征跟 entity 文本进行 attention 的结果,这时需要 "ent_attend_type" 指示使用哪种 attention 权重计算方式(mul, add, dot, scaled_dot);3. "co_attend":mention 表征 和 entity 表征使用两者的隐藏状态序列的interactive attention来产生。