基于神经网络的情景喜剧笑点识别(CCL2020-EHC)

本文将通过神经网络预训练模型实现对情景喜剧笑点的识别

前言 

任务背景

任务介绍


数据集介绍 

数据集属性说明:

训练集:

验证集:

 测试集:

 评测指标:

由两个指标综合决定,即

步骤

1.数据预处理

思路:首先观察数据集本身,它是来源与情景喜剧对话,在一段对话中,存在不同角色进行交流,产生连续的对白(Utterance)。同一段对话中的对白按顺序出现,存在上下文关系。相比于单句幽默,对话中的幽默可能来自于上下文语境,而非对白内容本身。因此,需要结合上下文语境内容对对白是否幽默作出判断,识别出情景喜剧中的笑点。所以根据其特点设计了三种数据处理方法进行对比。

(1)若对数据集中的sentence不做处理,即只取Sentencelabel这两列的数据进行训练,如图: 

对应的结果:

(2)结合剧本本身的特点,将Speaker和Sentence这两列合并得到新的sentence,speaker和sentence之间用 : 隔开

 对应的结果:

 (可以看到确实有些许效果)

(3)考虑上下文关系,将前文和后文都考虑进来,每句话之间用 特殊符号。隔开(当然特殊符号可以选其他的,或者空格代替,但是经过实验我发现用。好可能稍好一些)。至于考虑前文多少句话,后文多少句话,这里经过实验比较,考虑当前语句的上一句和下一句最好。

 

 对应的结果:

(可以看到无论在中文数据集还是英文数据集上都有不小的提升) 

  代码:

  数据处理函数data_process():

#导入库
import pandas as pd
import csv


def data_process(path,filename):
    """
    path:string 为你的训练集或验证集的文件路径
    filename:string 为处理后的数据文件的存放路径,因为是csv文件,所以以.csv结尾
    """
    #读取数据
    data_sets=pd.read_csv(path)
    
    #读取Sentence这一列的数据
    data=data_sets['Sentence']
    
    #读取Speaker这一列的数据
    Speaker=data_sets['Speaker']
    
    #读取Label这一列的数据
    label=data_sets['Label']
    
    #考虑上下文信息,head表示考虑当前语句前head条对话,behind表示当前语句后behind-1条对话
    ahead=1
    behind=2
    
    #将处理后的数据写入filename文件中
    with open(filename, 'w', newline='',encoding='utf-8') as file:
        writer = csv.writer(file)
        
        #先写入属性名
        writer.writerow(["Sentence", "Label"])
        
        #依次读取原始数据每一行数据
        for i in range(len(data)):
            new_sentence=""
            
            #防止越界
            left=max(0,i-ahead)
            right=min(len(data),i+behind)
            
            #合并left到right-1条数据
            for j in range(left,right):
                
                #先合并Speaker和Sentence这两列数据
                speaker_sentence=Speaker[j]+":"+data[j]
                
                #再添到new_sentence中
                new_sentence=new_sentence+speaker_sentence+"."
                #print(new_sentence)
                
            #写入数据
            writer.writerow([new_sentence,int(label[i])])

 由于测试集没有Label属性,但又为了方便利用上面的代码,所以给它弄个伪标签

def data_process_test(path,filename):
    """
    path:string 为你的训练集或验证集的文件路径
    filename:string 为处理后的数据文件的存放路径,因为是csv文件,所以以.csv结尾
    """
    
    #读取数据
    data_sets=pd.read_csv(path)
    
    #读取Sentence这一列的数据
    data=data_sets['Sentence']
    
    #读取Speaker这一列的数据
    Speaker=data_sets['Speaker']
    
    #伪标签
    label=[0]*len(data)
    
    
    #考虑上下文信息,head表示考虑当前语句前head条对话,behind表示当前语句后behind-1条对话
    ahead=1
    behind=2
    
    #将处理后的数据写入filename文件中
    with open(filename, 'w', newline='',encoding='utf-8') as file:
        writer = csv.writer(file)
        
        #先写入属性名
        writer.writerow(["Sentence", "Label"])
        
        #依次读取原始数据每一行数据
        for i in range(len(data)):
            new_sentence=""
            
            #防止越界
            left=max(0,i-ahead)
            right=min(len(data),i+behind)
            
            #合并left到right-1条数据
            for j in range(left,right):
                
                #先合并Speaker和Sentence这两列数据
                speaker_sentence=Speaker[j]+":"+data[j]
                
                #再添到new_sentence中
                new_sentence=new_sentence+speaker_sentence+"."
                #print(new_sentence)
                
            #写入数据
            writer.writerow([new_sentence,int(label[i])])

调用:

data_process(train_cn_path,"train_cn_data.csv")
data_process(eval_cn_path,"eval_cn_data.csv")
data_process_test(test_cn_path,"test_cn_data.csv")

2.训练

处理好数据集后,就可以将训练集和验证集放入预训练模型中训练(具体内容就不展示了),得到训练好的模型,模型我放在了

EHC幽默识别英文模型-Python文档类资源-CSDN文库https://download.csdn.net/download/qq_53644346/85868692EHC幽默识别中文模型-Python文档类资源-CSDN文库https://download.csdn.net/download/qq_53644346/85868452

以下是使用它的具体方法:

2.1模型加载

from transformers import AutoModelForSequenceClassification, AutoTokenizer

# 模型路径
model_path="C:/Users/86182/Desktop/cn_model_final"

#加载模型
model = AutoModelForSequenceClassification.from_pretrained(model_path, use_auth_token=True)

tokenizer = AutoTokenizer.from_pretrained(model_path, use_auth_token=True)

2.2简单使用

输入一句话,返回的是一个二维张量,值是归一化后的类别概率。

Input_sentence="志国:我能踏实的了么我"
# 输入数据
inputs = tokenizer(Input_sentence, return_tensors="pt")

# 模型输出
outputs = model(**inputs)

print(outputs.logits)
if outputs.logits[0][0]>outputs.logits[0][1]:
    print(0)
else:
    print(1)

进行简单的处理,既可以得到类别输出: 

 

 2.3对test数据集进行预测

def get_result(path,filename):
    
    """
    path处理后的测试集路径
    filename为生成的结果文件路径
    """
    
    #读取处理过的测试集
    test_sets=pd.read_csv(path)
    test_sentences=test_sets['Sentence']
    
    with open(filename, 'w', newline='') as file:
    writer = csv.writer(file)
    
    #写入ID和Label属性名
    writer.writerow(["ID", "Label"])
    for i in range(len(test_sentences)):
        
        inputs = tokenizer(test_sentences[i], return_tensors="pt")

        outputs = model(**inputs)

        print(outputs.logits)
        label=0
        if outputs.logits[0][0]>outputs.logits[0][1]:
#             print(0)
            pass
        else:
#             print(1)
            label=1
        
        writer.writerow([i, label])

3.结果 

cn_result.csv

en_result.csv


 对比baseline:

以及其他模型:

 通过对比,可以看到我的预训练模型效果还是可以的。

 不足之处和改进:

1.数据集中的Dialogue_id这一属性我并没有用到,因为数据集自身的特点,每段对话都有一个场景,而Dialogue_id蕴含着场景信息,所以在场景切换时,对数据集当前对话取上下文并不合适,改进方法就是在获取当前对话的上下文时,把Dialogue_id也考虑进来。

2.预训练模型的选择不同,获得的效果也会不同,针对模型的调参本文并没有体现出来

3.对训练集和验证集没有做交叉验证,同时也没有对测试集的预测结果进行集成

总结

本文主要是针对数据集进行处理,通过预训练模型进行训练,而没有详细的讲怎么去构建神经网络模型,以及神经网络的实现过程是什么样的,当然这也是本文的不足吧。但是通过我给出的预训练模型,可以非常简单的完成本次幽默识别的任务,效果也还算不错吧。

最后,如果博客中有什么不对的地方,请多多指教。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值