法研杯要素識別第二名方案總結:多標籤分類實踐與效果對比

  • 2019 年 10 月 11 日
  • 筆記

作者徐亮(實在智能算法專家)

項目鏈接,點擊閱讀原文直達:

https://github.com/brightmart/multi-label_classification

本文為法研杯-要素識別第二名(top2/186) 方案分享,與第一名相差僅為0.38個百分點,超過第三名1.8個點,以下來自該項目介紹頁。


Multi-label Classification

Transform multi-label classification as sentence pair task &

Together with generating more training data, use more information and external knowledge

Performance 效果對比

Additional information for pre-train RoBERTa chinese models, check: Roberta_zh

Introduction 多標籤分類介紹

Multi-label Classification is a classification problem where multiple labels may be assigned to each instance.

Zero, one or multiple labels can be associated with an instance(or example). It is more general than multi-class

classification where one and only one label assigned to an example.

You can think the problem as a multiple binary classification that map input(X) to

a value(y) either 0 or 1 for each label in label space. According to wiki:

Multi-label classification is the problem of finding a model that maps inputs x to binary vectors y (assigning a value of 0 or 1 for each element (label) in y).

Transform Multi-label Classification as Sentence Pair Task

任務轉化:將多標籤分類轉換為句子對任務

It is normal to get a baseline by trying use a single classification model to predict the labels for each input string.

And it will be time-effective during inference since only one time computation is happened. However, the performance is quite poor especially when

you only have few instances or examples for each label. one of the reasons for poor performance is that it try to map input to target labels directly

but fail to use more information and training example is not enough.

By cast to sentence pair task, it is easy to use more information including label information, instance information, key words from each label.

Generating more training data and Information

產生更多訓練數據、結合更多信息和額外的知識

Let's talk about how to use additional information and generate more data.

Sentence pair task is like this:. for sentence_1, it come from original input string.

Then it be:. so where is sentence_2 come from? it is another input sentence. it can be come from:

1) chinese label string, or 2) an sentence which can represent a label. you can randomly pick a sentence from a specific label to represent label, you can also manual give an description to a label to represent this label; 3) you can learn the keywords from the label and put keywords together to repsenent the label.

In a words, there are many way to generate sentence_2 to do sentence pair task. and as a result, we generate more than

1 million training instances for sentence pair task by using only 30k labeled instance.

直接的多標籤分類去預測,由於設法直接從輸入的文本去影射標籤,沒有使用額外的信息,訓練數據也有限,效果比較差。

通過將其轉化為句子對任務,我們可以比較容易的利用額外的信息,並且產生極大數量的訓練樣本。這些額外的信息包括但不限於:

特定標籤對應的訓練樣本中的部分輸入文本、中文的標籤信息、標籤對應的top關鍵詞的組合。這些額外的信息可用來代表這個標籤。

在#Task Description和#Generate Training Data,我將詳細展開並舉例。

Procedure 流程

1) Transform multi-label classification to sentence pair task with random instance from label —> 2) Additional information: add label information, which is chinese; or keys words from label, or export knowledge —> 3) Additional domain knowledge: large scale domain pre-training

Task Description 任務介紹

About Task 任務是什麼?

The purpose of this task is to extract important fact from description of legal case,

and map description of case to case elements according to system designed by experts in the field.

for each sentence in the paragraph from judicial document, the model need to identify the key element(s).

multiple or zero elements may exist in a sentence.

本任務的主要目的是為了將案件描述中重要事實描述自動抽取出來,並根據領域專家設計的案情要素體系進行分類。

案情要素抽取的結果可以用於案情摘要、可解釋性的類案推送以及相關知識推薦等司法領域的實際業務需求中。

具體地,給定司法文書中的相關段落,系統需針對文書中每個句子進行判斷,識別其中的關鍵案情要素。

本任務共涉及三個領域,包括婚姻家庭、勞動爭議、借款合同等領域。

Check this for more details on this task:中國法研杯_CAIL2019(要素識別賽道)

This is the 2rd/188 solution for this task.

Examples of Data 數據介紹

本任務所使用的數據集主要來自於「中國裁判文書網」公開的法律文書,每條訓練數據由一份法律文書的案情描述片段構成,其中每個句子都被標記了對應的類別標籤

(需要特別注意的是,每個句子對應的類別標籤個數不定),例如:

{"labels": ["DV1", "DV4", "DV2"],"sentence": "In our opinion, according to the agreement between the two parties at the time of divorce, the plaintiff has paid 22210.00 yuan for the child's upbringing on the basis of ten-year upbringing. We can confirm that the plaintiff pays 200.00 yuan for the child's upbringing on a monthly basis."} {"labels": ["DV1", "DV4", "DV2"],"sentence": "本院認為,依據雙方離婚時的協議約定,原告已按尚撫養十年一性支付孩子撫養費22210.00元,可確認原告每月支付孩子撫養費為200.00元。"}, {"labels": [],"sentence": "父母離婚後子女的撫養問題,應從有利於子女身心健康以及保障子女合法權益出發,結合父母雙方的撫養能力和撫養條件等具體情況妥善解決。"}, {"labels": ["DV1", "DV8", "DV4", "DV2"],"sentence": "二、關於撫養費的承擔問題,本院根據子女的實際需要、父母雙方的負擔能力和當地的實際生活水平確定,由被告趙某甲每月給付孩子撫養費600.00元;"}, {"labels": ["DV14", "DV9", "DV12"], "sentence": "原告訴稱,原被告原系夫妻關係,雙方於2015年3月18日經河南省焦作市山陽區人民法院一審判決離婚,離婚後原告才發現被告在婚姻關係存續期間,與他人同居懷孕並生下一男孩,給原告造成極大傷害。"}, {"labels": [], "sentence": "特訴至貴院,請求判決被告賠償原告精神損害撫慰金3萬元。"}, {"labels": [], "sentence": "被告辯稱,1、原告在焦作市山陽區人民法院離婚訴訟中,提交答辯狀期間就同意被告的離婚請求,被告並未出現與他人同居懷孕情況,原告不具備損害賠償權利主體資格。"}, {"labels": [], "sentence": "2、被告沒有與他人持續穩定的同居生活,不具備損害賠償責任主體資格。"}, {"labels": [], "sentence": "3、原被告婚姻關係存續期間,原告經常對被告實施家庭暴力。"}, {"labels": [], "sentence": "原告存在較大過錯,無權提起本案損失賠償請求。"}, {"labels": ["DV1"], "sentence": "經審理查明:原被告於××××年××月××日登記結婚,××××年××月××日生育女孩都某乙。"}, {"labels": ["DV9"], "sentence": "被告於2014年9月23日向焦作市山陽區人民法院起訴與原告離婚,該院於2015年3月18日判決准予原被告離婚後,原告不服上訴至焦作市中級人民法院,該院於2015年6月15日作出終審判決,駁回原告上訴,維持原判。"} for each english label like DV1, it associated with a chinese label, such as 婚後有子女, which means 'Having children after marriage'. 對於每個英文標籤,都有一個對應的中文標籤名稱。 如 DV1、DV2、DV4對應的中文標籤分別為:婚後有子女、限制行為能力子女撫養、支付撫養費。DV8對應:按月給付撫養費

Generate Training Data 生成訓練數據

標籤下的代表性樣本的產生

我們首先選取每個標籤下一定數量樣本,如隨機的選取5個樣本,來代表這個標籤;並且由於我們知道這個標籤對應的中文名稱,所以,對於任何一個標籤,我們都構造了6個句子來代表這個標籤,

記為集合{representation_set}. 需要注意的是,為了使得樣本更有代表性,在隨機選取樣本過程中,我們優先選擇哪些只有一個標籤的樣本作為我們的代表性的樣本。

如對於DV1,我們6個樣本包括:

婚後有子女(來自於中文標籤) ××××年××月××日生育女兒趙某乙。(來自於DV1標籤下的樣本) 綜合全案證據及庭審調查,本院確認以下法律事實:××××年××月××日,原告林某和被告趙某甲辦理結婚登記手續,婚後於××××年××月××日生育婚生女兒趙某乙。(來自於DV1標籤下的樣本) 四、撫養權變更後,被告趙某甲有探望女兒趙某乙的權利,原告林某應為被告趙某甲探望孩子提供必要便利。(來自於DV1標籤下的樣本)

原始樣本:{"labels": ["DV1", "DV4", "DV2"],"sentence": "本院認為,依據雙方離婚時的協議約定,原告已按尚撫養十年一性支付孩子撫養費22210.00元,可確認原告每月支付孩子撫養費為200.00元。"}

正樣本的構造

我們需要構造句子對任務:

句子對任務中的第一部分的輸入為,原始的文本,即本院認為,依據雙方離婚時的協議約定…),第二部分的輸入是數據產生過程的關鍵所在。

對於DV1這個標籤,我們得到六個句子即representation_set[DV1],並且對於原始輸入與這裏面的每個樣本的組合,我們給label賦值為1。如:

<"本院認為,依據雙方離婚時的協議約定,原告已按尚撫養十年一性支付孩子撫養費22210.00元,可確認原告每月支付孩子撫養費為200.00元。", "婚後有子女", 1> <"本院認為,依據雙方離婚時的協議約定,原告已按尚撫養十年一性支付孩子撫養費22210.00元,可確認原告每月支付孩子撫養費為200.00元。", 「××××年××月××日生育女兒趙某乙。", 1> <"本院認為,依據雙方離婚時的協議約定,原告已按尚撫養十年一性支付孩子撫養費22210.00元,可確認原告每月支付孩子撫養費為200.00元。", 「綜合全案證據及庭審調查,本院確認以下法律事實:××××年××月××日,原告林某和被告趙某甲辦理結婚登記手續,婚後於××××年××月××日生育婚生女兒趙某乙。", 1> ….

通過這個形式,我們將正樣本擴大了6倍;我們可以通過標籤下採樣更多的例子,以及使用標籤下統計得到的關鍵詞的組合,來進一步擴大正樣本的集合。

負樣本的構造

對於一個標籤集合,如婚姻家庭下有20個標籤,那麼對於一個句子,只要沒有被打上標籤的,就是負樣本。我們也構造了一個標籤下的可能的所有樣本的集合外加中文標籤,並通過隨機樣本的方式來得到需要的樣本。

如對於我們的原始樣本的輸入文本:"本院認為,依據雙方離婚時的協議約定,原告已按尚撫養十年一性支付孩子撫養費22210.00元,可確認原告每月支付孩子撫養費為200.00元。",

它被打上了三個標籤["DV1", "DV4", "DV2"],那麼其他標籤["DV3","DV5",…,"DV20"],都可以用來構造負樣本。對應DV3,我們選擇4+1即5個樣本。3即從DV3下隨機的找出三個樣本,1即中文標籤做為樣本。

正負樣本分佈 Training data and Its distribution

由於正樣本量擴大了至少6倍,負樣本擴大了20倍左右,最終我們從原始的1萬個樣本中產生了100多萬的數據。當然為了樣本分佈受控,我們也對負樣本有部分下採樣。

另外為了得到與任務目標接近的驗證集,我們在驗證集上對負樣本精選了更大程度的下採樣。

分佈大致如下:

train:     count_pos: 261001 ;count_neg: 1011322 ;pert of pos: 0.20513737470752316    dev:     count_pos: 13863 ;count_neg: 16121 ;pert of pos: 0.4623465848452508  

生成訓練數據的命令 Run command to generate training data :

python3 -u zuo/generate_training_data  

Relationship with Few-Shot Learning 與Few-Shot Learning有什麼關係

According to Quora: with the term 「few-shot learning」, the 「few」 usually lies between zero and five,

meaning that training a model with zero examples is known as zero-shot learning, one example is one-shot learning, and so on.

All of these variants are trying to solve the same problem with differing levels of training material.

We are not doing few shot learning. however we try to get maximum performance for tasks with not so many examples.

And also try to use information and knowledge,whether come from task or outside the task, as much as possible, to boost the performance.

Download Data 下載數據

點擊這裡下載數據,並解壓縮到zuo目錄下。這樣你就有了一個新的包含所有需要的數據的目錄./zuo/data_all

Training 訓練模型

Run Command to Train the model:

export BERT_BASE_DIR=./RoBERTa_zh_Large export TEXT_DIR=./zuo/data_all/train_data nohup python3 run_classifier.py –task_name=sentence_pair –do_train=true –do_eval=true –data_dir=$TEXT_DIR –vocab_file=$BERT_BASE_DIR/vocab.txt –bert_config_file=$BERT_BASE_DIR/bert_config_big.json –init_checkpoint=$BERT_BASE_DIR/roberta_zh_large_model.ckpt –max_seq_length=256 –train_batch_size=128 –learning_rate=1e-5 –num_train_epochs=3 –output_dir=zuo/model_files/roberta-zh-large_law & 如果你從現有的模型基礎上訓練,指定一下BERT_BASE_DIR的路徑,並確保bert_config_file和init_checkpoint兩個參數的值能對應到相應的文件上。 這裡假設你下載了roberta的模型並放在本項目的這個RoBERTa_zh_Large目錄下。

Inference and its acceleration 預測加速

訓練完成後,運行命令來進行預測 Run Command to Train Model:

python3 -u main.py 需要注意的是,你需要確保相應的目錄有訓練好的模型,見zuo/run_classifier_predict_online.py,特別注意這兩個參數要能對應上: init_checkpoint和bert_config_file

句子對任務的構建 Construct Sentence Pair

雖然訓練階段使用了很多信息和知識來訓練,但是預測階段我們只採用<原始輸入的句子,候選標籤對應的中文標籤>來構造句子對任務。我們認為樣本下的標籤雖然能

代表標籤,但中文標籤具有最好的代表性,預測效果也好一些。

預測階段加速 Accelerate Inference Time

由於採用了sentence pair任務即句子對形式,對於一個輸入,有20個標籤,每個標籤都需要預測,那麼總共需要預測20次,這會導致預測時間過長。

所以,我們採用的是快速召回+精細預測的形式。

快速召回,採用多標籤分類的形式,只需一次預測就可以將可能的候選項找到,如概率大於0.05的標籤都是候選項。實踐中,多數時候候選的標籤為只有0個或1個。

對於每個候選的標籤,都會使用句子對任務(原始句子,標籤對應的中文描述)的模型去預測這個標籤的概率;當某個標籤的概率超過0.5的時候,即認為是目標標籤。

對於響應速度要求不是特別嚴格的時候,我們也可以通過訓練層數比較少的句子對模型來作為快速召回模塊。

Multi-label classification directly with Bert 使用Bert直接做多標籤分類

Check this 3.BERT, You can find code here:

train_bert_multi-label.py  

Unfinished Work 未完成的工作

利用標籤間的關係,構造更多數據和更難的任務。

由於標籤之間具有共現關係或排斥關係等,通過標籤關係來生成更多數據,也是未來可以研究的一個方向。

項目貢獻者,還包括:

skyhawk1990

yucong

Reference

1、BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

2、RoBERTa中文預訓練模型:Roberta_zh

3、Pre-Training with Whole Word Masking for Chinese BERT