初號(hào)機(jī)暴走事件

初號(hào)機(jī)暴走事件
2015年第三使徒登陸第三新東京市,初號(hào)機(jī)在面對(duì)第三使徒時(shí),由于真嗣首次駕駛EVA作戰(zhàn),戰(zhàn)況非常殘酷,初號(hào)機(jī)的頭部被第三使徒刺穿,左腕被扯斷,導(dǎo)致與初號(hào)機(jī)保持神經(jīng)連接的真嗣失去了意識(shí)。在這樣極限的情況下,初號(hào)機(jī)開(kāi)始了暴走狀態(tài),使用再生功能修復(fù)了左腕,并且徒手撕裂了第三使徒的AT Field,虐殺了第三使徒。
EVA粉絲可以在看完文章后去B站溫習(xí)一下~
上面這段文本描述了初號(hào)機(jī)的第二次暴走事件,倘若我們想用人工智能的技術(shù)從這段文本中抽取出“初號(hào)機(jī)暴走事件”,需要用到NLP領(lǐng)域的“事件抽取技術(shù)”。
接下來(lái)筆者將分別介紹事件定義、任務(wù)定義、數(shù)據(jù)標(biāo)注、事件抽取模型以及模型demo。
1 事件定義
事件是指在一定時(shí)間、地點(diǎn)發(fā)生的涉及一個(gè)或多個(gè)參與者的具體行為,通??梢悦枋鰹橐环N狀態(tài)的變化[1]。有的情況下,事件的結(jié)構(gòu)是預(yù)先定義好的,這類事件屬于“封閉領(lǐng)域”事件,比如這里的初號(hào)機(jī)暴走事件。
事件類型 暴走事件 事件論元 暴走時(shí)間:2015年 暴走地點(diǎn):第三新東京市 暴走原因:真嗣失去了意識(shí) 暴走主角:初號(hào)機(jī) 暴走后果:虐殺了第三使徒
2 事件抽取任務(wù)定義
事件抽取的目的是檢測(cè)文本中存在的事件實(shí)例,并且識(shí)別出存在的事件類型及所有的參與者和屬性。簡(jiǎn)單的理解就是從非結(jié)構(gòu)化的文本中獲取結(jié)構(gòu)化表示的事件實(shí)例。
3 數(shù)據(jù)標(biāo)注
事件抽取也是一種信息抽取任務(wù),雖然抽取的是一定結(jié)構(gòu)的文本信息,但簡(jiǎn)單來(lái)看也只是抽取出表示事件論元的一些文本片段,以及確定某個(gè)事件類型,加上這里僅僅涉及到單事件的抽取,不存在多個(gè)事件的論元嵌套問(wèn)題,而文本片段可以看作是實(shí)體,因此可以使用簡(jiǎn)單的命名實(shí)體識(shí)別(NER)方法來(lái)抽取出事件論元的文本片段。
一段文本中存在的事件類型往往由關(guān)鍵的觸發(fā)詞隱式地表達(dá)出來(lái),例如這段文本的“暴走狀態(tài)”,這種隱式的表達(dá)也體現(xiàn)在整段文本的語(yǔ)義表達(dá)中,因此可以結(jié)合全文的語(yǔ)義編碼對(duì)事件類型進(jìn)行分類??偟膩?lái)說(shuō),可以聯(lián)合預(yù)測(cè)文本的事件類型以及抽取出事件論元的實(shí)體。
所以標(biāo)注的形式基本可以確定下來(lái),事件類型的標(biāo)注看作文本分類的標(biāo)注,把數(shù)據(jù)集的事件類型轉(zhuǎn)換為數(shù)字集合(0,1,2,...,k),獲得該文本的事件類型分類標(biāo)簽 L ∈[0, k]。
直接把事件論元作為實(shí)體類型,例如暴走時(shí)間、暴走地點(diǎn); 把事件類型和事件論元結(jié)合起來(lái)作為實(shí)體類型,例如暴走事件—暴走時(shí)間、暴走事件—暴走原因
后者能夠更好的聯(lián)合文本事件類型分類結(jié)果抽取事件實(shí)例,因此這里選擇后者的標(biāo)注方式,采用BIO標(biāo)簽對(duì)文本進(jìn)行序列標(biāo)注(標(biāo)注樣例如下)。

事件抽取模型
這里介紹一種筆者用到的事件抽取模型。

文本輸入BERT編碼器分別獲得句向量編碼(batch, hidden_size)和序列編碼(batch, sequence_len, hidden_size)。句向量輸出用于分類器對(duì)事件類型進(jìn)行分類,編碼輸出用于BIO序列標(biāo)注模型抽取實(shí)體。
預(yù)測(cè)過(guò)程中,對(duì)抽取出的每種”事件類型—論元“實(shí)體進(jìn)行平均置信度排序,篩選出每種“事件類型-論元”中置信度最高的實(shí)體,再結(jié)合文本預(yù)測(cè)的事件類型對(duì)剩余”事件類型—論元“實(shí)體進(jìn)行篩選,留下與預(yù)測(cè)的事件類型相匹配的論元實(shí)體,組合成預(yù)測(cè)的事件實(shí)例。
篩選過(guò)程如下:

模型Demo
from transformers import BertPreTrainedModel, BertModelclass BertForEventExtract(BertPreTrainedModel):def __init__(self, config):super(BertForEventExtract, self).__init__(config)self.bert = BertModel(config) # 定義BERT編碼器self.num_labels = config.num_labels #實(shí)體BIO標(biāo)簽self.event_type_outputs = nn.Linear(config.hidden_size, 5) # 假設(shè)這里一共有5種事件類型,該層用于對(duì)文本句向量進(jìn)行事件類型分類self.dropout = nn.Dropout(config.hidden_dropout_prob)self.BIO_classifier = nn.Linear(config.hidden_size, config.num_labels) # 該層用于對(duì)每個(gè)字符進(jìn)行BIO標(biāo)簽分類self.init_weights()def forward(self, input_ids, attention_mask=None, token_type_ids=None, position_ids=None, head_mask=None, labels=None):outputs = self.bert(input_ids,attention_mask=attention_mask,token_type_ids=token_type_ids,position_ids=position_ids,head_mask=head_mask) # 獲取BERT的輸出sequence_output = outputs[0] #序列編碼輸出pooled_output = outputs[1] #序列句向量輸出# 預(yù)測(cè)BIO實(shí)體sequence_output = self.dropout(sequence_output)BIO_logits = self.BIO_classifier(sequence_output)# 預(yù)測(cè)事件類型pooled_output = self.dropout(pooled_output)event_type_logits = self.event_type_outputs(pooled_output)if labels is not None:BIO_labels, event_type_label = labelsBIO_loss = nn.CrossEntropyLoss(ignore_index=-1)(BIO_logits.view(-1, self.num_labels), BIO_labels.view(-1))event_type_loss = nn.CrossEntropyLoss()(event_type_logits, event_type_label.view(-1))outputs = BIO_loss + event_type_losselse:outputs = (BIO_logits, event_type_logits)return outputs
引用
[1]Ace (Automatic Content Extraction) English Annotation Guidelines for Events, Linguistic Data Consortium, Philadelphia, PA, USA, 2005.

