面向子空间基于规则嵌入的论文相似性比较

面向子空间基于规则嵌入的论文相似性比较-ysl

创新实训个人过程记录
我负责的部分是论文摘要基于语义的子空间关键词提取并且比较关键词相似度,采用bertfortokenclassification进行关键词提取。

简单介绍一下bert
首先需要知道transformer,和大多数seq2seq模型一样,transformer的结构也是由encoder和decoder组成。不一样的是多头注意力机制扩展了模型专注于不同位置的能力,给出了注意力层的多个“表示子空间”。输入向量添加了位置编码,变为基于时间步的词嵌入,加入残差网络。
在这里插入图片描述
bert的结构就是双向的Transformer block连接
在这里插入图片描述
词的嵌入也加入了token embedding和position embedding(学习得出)
在这里插入图片描述
bert词性标注
BERT通过”Fill in the blank task” 以及 “Next sentence prediction” 两个任务进行预训练。在预训练模型的基础上稍加修改就可以处理多个下游任务。如下图所示,中文文本的序列标注问题,每个序列的第一个token始终是特殊分类嵌入([CLS]),剩下的每一个token代表一个汉字。BERT的input embeddings 是token embeddings, segmentation embeddings 和position embeddings的总和。其中token embeddings是词(字)向量,segment embeddings 用来区分两种句子,只有一个句子的任务(如序列标注),可以用来区分真正的句子以及句子padding的内容,而position embedding保留了每个token的位置信息。BERT的output 是每个token的encoding vector。只需要在BERT的基础上增加一层全连接层并确定全连接层的输出维度,便可把embedding vector映射到标集合。词性标注问题的标签集合即中文中所有词性的集合。
在这里插入图片描述

思路
通过Sem-Eval 2010关键字识别数据集训练BertForTokenClassification,输出bio标注的词序列,默认b和I为较重要词语,作为关键词输出。

主要代码
1.数据集:Sem-Eval 2010关键字识别数据集,论文基于规则判断的子空间的语句
2.数据预处理
将Sem-Eval 2010关键字识别数据集转换为BIO格式数据集。

def convert(key):
    sentences = ""
    for line in open(train_path + "/" + filekey[key], 'r'):
        sentences += (" " + line.rstrip())
    tokens = sent_tokenize(sentences)
    key_file = open(train_path + "/" + str(key),'r')
    keys = [line.strip() for line in key_file]
    key_sent = []
    labels = []
    for token in tokens:
        z = ['O'] * len(token.split())
        for k in keys:
            if k in token:
                
                if len(k.split())==1:
                    try:
                        z[token.lower().split().index(k.lower().split()[0])] = 'B'
                    except ValueError:
                        continue
                elif len(k.split())>1:
                    try:
                        if token.lower().split().index(k.lower().split()[0]) and token.lower().split().index(k.lower().split()[-1]):
                            z[token.lower().split().index(k.lower().split()[0])] = 'B'
                            for j in range(1, len(k.split())):
                                z[token.lower().split().index(k.lower().split()[j])] = 'I'
                    except ValueError:
                        continue
        for m, n in enumerate(z):
            if z[m] == 'I' and z[m-1] == 'O':
                z[m] = 'O'

        if set(z) != {'O'}:
            labels.append(z) 
            key_sent.append(token)
    return key_sent, labels

3.加载模型

model = BertForTokenClassification.from_pretrained("bert-base-uncased", num_labels=len(tag2idx))

4.训练模型

epochs = 4
max_grad_norm = 1.0

for _ in trange(epochs, desc="Epoch"):
    # TRAIN loop
    model.train()
    tr_loss = 0
    nb_tr_examples, nb_tr_steps = 0, 0
    for step, batch in enumerate(train_dataloader):
        # add batch to gpu
        batch = tuple(t.to(device) for t in batch)
        b_input_ids, b_input_mask, b_labels = batch
        # forward pass
        loss = model(b_input_ids, token_type_ids=None,
                     attention_mask=b_input_mask, labels=b_labels)
        # backward pass
        loss.backward()
        # track train loss
        tr_loss += loss.item()
        nb_tr_examples += b_input_ids.size(0)
        nb_tr_steps += 1
        # gradient clipping
        torch.nn.utils.clip_grad_norm_(parameters=model.parameters(), max_norm=max_grad_norm)
        # update parameters
        optimizer.step()
        model.zero_grad()
    # print train loss per epoch
    print("Train loss: {}".format(tr_loss/nb_tr_steps))
    # VALIDATION on validation set
    model.eval()
    eval_loss, eval_accuracy = 0, 0
    nb_eval_steps, nb_eval_examples = 0, 0
    predictions , true_labels = [], []
    for batch in valid_dataloader:
        batch = tuple(t.to(device) for t in batch)
        b_input_ids, b_input_mask, b_labels = batch
        
        with torch.no_grad():
            tmp_eval_loss = model(b_input_ids, token_type_ids=None,
                                  attention_mask=b_input_mask, labels=b_labels)
            logits = model(b_input_ids, token_type_ids=None,
                           attention_mask=b_input_mask)
        logits = logits.detach().cpu().numpy()
        label_ids = b_labels.to('cpu').numpy()
        predictions.extend([list(p) for p in np.argmax(logits, axis=2)])
        true_labels.append(label_ids)
        
        tmp_eval_accuracy = flat_accuracy(logits, label_ids)
        
        eval_loss += tmp_eval_loss.mean().item()
        eval_accuracy += tmp_eval_accuracy
        
        nb_eval_examples += b_input_ids.size(0)
        nb_eval_steps += 1
    eval_loss = eval_loss/nb_eval_steps
    print("Validation loss: {}".format(eval_loss))
    print("Validation Accuracy: {}".format(eval_accuracy/nb_eval_steps))
    pred_tags = [tags_vals[p_i] for p in predictions for p_i in p]
    valid_tags = [tags_vals[l_ii] for l in true_labels for l_i in l for l_ii in l_i]
    print("F1-Score: {}".format(f1_score(pred_tags, valid_tags)))

训练结果
训练结果
4.关键词提取
tensor为类别loss,数组为输出序列bio,最后两行为关键词结果
在这里插入图片描述

存在问题
属于bi分类的词语较少,提取出的关键词数量较少,所以需要其他基于统计信息的方法进行关键词的补充,尝试kea算法,tfidf,textrank等进行补充。

参考
https://cloud.tencent.com/developer/article/1454904
https://zhuanlan.zhihu.com/p/46652512
https://github.com/ibatra/BERT-Keyword-Extractor
以及链接中的论文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值