SetFitABSA 是一种可以有效从文本中检测特定方面情感的技术。
方面级情感分析 (Aspect-Based Sentiment Analysis,ABSA) 是一种检测文本中特定方面的情感的任务。例如,在“这款手机的屏幕很棒,但电池太小”一句中,分别有“屏幕”和“电池”两个方面,它们的情感极性分别是正面和负面。
ABSA 应用颇为广泛,有了它我们可以通过分析顾客对产品或服务的多方面反馈,并从中提取出有价值的见解。然而,ABSA 要求在样本标注时对训练样本中涉及的各个方面进行词元级的识别,因此为 ABSA 标注训练数据成为了一件繁琐的任务。
为了缓解这一问题,英特尔实验室和 Hugging Face 联袂推出了 SetFitABSA,以用于少样本场景下的特定领域 ABSA 模型训练。实验表明,SetFitABSA 性能相当不错,其在少样本场景下表现甚至优于 Llama2 和 T5 等大型生成模型。
与基于 LLM 的方法相比,SetFitABSA 有两个独特优势:
🗣 无需提示: 在使用基于 LLM 的少样本上下文学习时,提示的作用非常关键,因此一般需要精心设计,这一要求使得最终效果对用词十分敏感且非常依赖用户的专业知识,因此整个方案会比较脆弱。SetFitABSA 直接从少量带标签的文本示例中生成丰富的嵌入,因此可完全无需提示。
🏎 快速训练: SetFitABSA 仅需少量的已标注训练样本。此外,其训练数据格式非常简单,无需专门的标注工具,因此数据标注过程简单而快速。
本文,我们将解释 SetFitABSA 的工作原理以及如何使用 SetFit 库 训练你自己的模型。我们开始吧!
工作原理与流程
SetFitABSA 的三段式训练流程
SetFitABSA 主要分三步。第一步从文本中提取候选方面; 第二步从候选方面中筛选出真正的方面,这一步主要由一个候选方面分类器来完成; 最后一步对每个方面判断其情感极性。其中,第二步和第三步均基于 SetFit 模型。
训练
1. 候选方面提取
这里我们假设: 方面一般指的是产品和服务的特性,因此其主要是名词或复合名词 (即几个相邻名词组成的字符串)。我们使用 spaCy 从少样本训练集的句子中提取并标注出名词/复合名词。由于并非所有提取的名词/复合名词都是方面,因此我们叫它们 候选方面。
2. 方面/非方面分类
有了候选方面后,我们还需要训练一个模型,以便能够区分这些候选方面中哪些是真正的方面。为此,我们需要一些带有方面/无方面标签的训练样本。如果候选方面存在于训练集中我们即视其为 True
,否则视其为 False
:
训练样本: “Waiters aren’t friendly but the cream pasta is out of this world.”
分词: [Waiters, are, n’t, friendly, but, the, cream, pasta, is, out, of, this, world, .]
提取候选方面: [Waiters, are, n’t, friendly, but, the, cream, pasta, is, out, of, this, world, .]
训练集标签,其格式为 BIO: [B-ASP, O, O, O, O、O、B-ASP、I-ASP、O、O、O、O、O、.]
根据训练集标签,生成方面/非方面标签: [Waiters, are, n’t, friendly, but, the, cream, pasta, is, out, of, this, world, .]
至此,我们对所有候选方面进行了标注,下一步就是如何训练方面分类模型?也就是说,我们如何使用 SetFit 这一句子分类框架来对词元进行分类?我们使用的方法是: 将每个候选方面与其所在的句子串接起来,我们使用以下模板创建训练样本:
候选方面:所在句子
将该模板应用于上面的例子,我们会生成 3 个训练样本 - 其中 2 个标签为 True
,1 个标签为 False
:
文本 | 标签 |
---|---|
Waiters:Waiters aren't friendly but the cream pasta is out of this world. | 1 |
cream pasta:Waiters aren't friendly but the cream pasta is out of this world. | 1 |
world:Waiters aren't friendly but the cream pasta is out of this world. | 0 |
... | ... |
生成训练样本后,我们就可以借助 SetFit 的强大功能仅用少许样本训练一个特定领域的二元分类器,以从输入文本评论中提取出方面。这是我们第一个微调 SetFit 模型。
3. 情感极性分类
一旦系统从文本中提取到方面,它需要判断每个方面的情感极性 (如积极、消极或中性)。为此,我们需要第二个 SetFit 模型,其训练方式与上面相似,如下例所示:
训练样本: “Waiters aren’t friendly but the cream pasta is out of this world.”
分词: [Waiters, are, n’t, friendly, but, the, cream, pasta, is, out, of, this, world, .]
标签: [NEG, O, O, O, O, O, POS, POS, O, O, O, O, O, .]
文本 | 标签 |
---|---|
Waiters:Waiters aren't friendly but the cream pasta is out of this world. | NEG |
cream pasta:Waiters aren't friendly but the cream pasta is out of this world. | POS |
... | ... |
注意,与方面提取模型不同,这里训练集中就不用包含非方面样本了,因为任务是对真正的方面进行情感极性分类。
推理
推理时,我们首先使用 spaCy 对输入句子进行候选方面提取,并用模板 aspect_candidate:test_sentence
生成推理样本。接下来,用方面/非方面分类器过滤掉非方面。最后,过滤出的方面会被送到情感极性分类器,该分类器预测每个方面的情感极性。
因此,我们的系统可以接收普通文本作为输入,并输出文本中的方面及其对应的情感:
模型输入:
"their dinner specials are fantastic."
模型输出:
[{'span': 'dinner specials', 'polarity': 'positive'}]
基准测试
我们将 SetFitABSA 与 AWS AI 实验室 和 Salesforce AI 研究院 的最新成果进行比较,这两项工作主要采用了对 T5 和 GPT2 进行提示微调的方法以实现方面级情感分析。为了对我们的工作进行全面测评,我们还将我们的模型与基于上下文学习的 Llama-2-chat 进行了比较。
我们采用的测评数据集是 2014 年语义评估挑战赛 (SemEval14) 中的 Laptop14 和 Restaurant14 ABSA 数据集。测评任务选择的是术语提取中间任务 (SB1) 及完整 ABSA 任务 (包括方面提取及情感极性预测,即 SB1+SB2)。
模型尺寸比较
模型 | 尺寸 (参数量) |
---|---|
Llama-2-chat | 7B |
T5-base | 220M |
GPT2-base | 124M |
GPT2-medium | 355M |
SetFit (MPNet) | 2x 110M |
请注意,SB1 任务使用的 SetFitABSA 的参数量为 110M; SB2 任务再加上一个 110M 的模型。因此 SB1+SB2 时, SetFitABSA 的总参数量为 220M。
性能比较
我们看到,当训练样本较少时,SetFitABSA 有明显优势,尽管它比 T5 小 2 倍,比 GPT2-medium 小 3 倍。即便是与 64 倍参数量的 Llama 2 相比,SetFitABSA 也能获得相当或更好的效果。
SetFitABSA vs GPT2
SetFitABSA vs T5
请注意,为公平起见,在比较 SetFitABSA 与各基线 (GPT2、T5 等) 时,我们使用了相同的数据集划分。
SetFitABSA vs Llama2
我们注意到,增加 Llama2 提示中的上下文样本的数目并不能改善效果。这种现象 之前也在 ChatGPT 中发现过,我们认为后续值得深入调查一下。
训练你自己的模型
SetFitABSA 是 SetFit 框架的一个功能。要训练 ABSA 模型,首先需要安装包含 absa
功能的 setfit
:
python -m pip install -U "setfit[absa]"
此外,我们必须安装 en_core_web_lg
版的 spaCy 模型:
python -m spacy download en_core_web_lg
接着开始准备训练数据集。训练集是一个 Dataset
对象,其包含 text
、 span
、 label
、 ordinal
四列:
text: 含有方面的完整句子或文本。
span: 句子中包含的方面。可以是一个单词或多个单词,如 “food”。
label: 每个 span (即方面) 的情感极性标签,如 “positive”。这些标签的名称是在标注时确定的。
ordinal: 如果某一方面在文本中出现了多次,则该列表示其在文本中出现的次序。这个值通常是 0,因为每个方面通常在对应文本中只出现一次。
举个例子,训练文本 “Restaurant with wonderful food but worst service I ever seen” 中包含两个方面,因此其在训练集表中占据两行,如下:
text | span | label | ordinal |
---|---|---|---|
Restaurant with wonderful food but worst service I ever seen | food | positive | 0 |
Restaurant with wonderful food but worst service I ever seen | service | negative | 0 |
... | ... | ... | ... |
一旦准备好训练数据集,我们就可以创建一个 ABSA 训练器并运行训练。SetFit 模型的训练效率相当高,但由于 SetFitABSA 涉及两个依次训练的模型,因此建议使用 GPU 进行训练,以缩短训练时间。例如,以下训练脚本在免费的 Google Colab T4 GPU 上仅需约 10 分钟就可以完成 SetFitABSA 模型的训练。
from datasets import load_dataset
from setfit import AbsaTrainer, AbsaModel# Create a training dataset as above
# For convenience we will use an already prepared dataset here
train_dataset = load_dataset("tomaarsen/setfit-absa-semeval-restaurants", split="train[:128]")# Create a model with a chosen sentence transformer from the Hub
model = AbsaModel.from_pretrained("sentence-transformers/paraphrase-mpnet-base-v2")# Create a trainer:
trainer = AbsaTrainer(model, train_dataset=train_dataset)
# Execute training:
trainer.train()
好了!自此,我们成功训得一个特定领域的 ABSA 模型。我们可以将训得的模型保存到硬盘或将其上传到 Hugging Face Hub。请记住,该模型包含两个子模型,因此每个子模型都需有自己的路径:
model.save_pretrained("models/setfit-absa-model-aspect","models/setfit-absa-model-polarity"
)
# 或
model.push_to_hub("tomaarsen/setfit-absa-paraphrase-mpnet-base-v2-restaurants-aspect","tomaarsen/setfit-absa-paraphrase-mpnet-base-v2-restaurants-polarity"
)
现在我们使用训得的模型进行推理。首先加载模型:
from setfit import AbsaModelmodel = AbsaModel.from_pretrained("tomaarsen/setfit-absa-paraphrase-mpnet-base-v2-restaurants-aspect","tomaarsen/setfit-absa-paraphrase-mpnet-base-v2-restaurants-polarity"
)
然后,使用模型的预测 API 进行推理。输入一个字符串列表,其中每个字符串代表一个评论文本:
preds = model.predict(["Best pizza outside of Italy and really tasty.","The food variations are great and the prices are absolutely fair.","Unfortunately, you have to expect some waiting time and get a note with a waiting number if it should be very full."
])print(preds)
# [
# [{'span': 'pizza', 'polarity': 'positive'}],
# [{'span': 'food variations', 'polarity': 'positive'}, {'span': 'prices', 'polarity': 'positive'}],
# [{'span': 'waiting time', 'polarity': 'neutral'}, {'span': 'waiting number', 'polarity': 'neutral'}]
# ]
有关训练选项、如何保存和加载模型以及如何推理等更多详细信息,请参阅 SetFit 文档。
参考文献
Maria Pontiki, Dimitris Galanis, John Pavlopoulos, Harris Papageorgiou, Ion Androutsopoulos, and Suresh Manandhar. 2014. SemEval-2014 task 4: Aspect based sentiment analysis. In Proceedings of the 8th International Workshop on Semantic Evaluation (SemEval 2014), pages 27–35.
Siddharth Varia, Shuai Wang, Kishaloy Halder, Robert Vacareanu, Miguel Ballesteros, Yassine Benajiba, Neha Anna John, Rishita Anubhai, Smaranda Muresan, Dan Roth, 2023 “Instruction Tuning for Few-Shot Aspect-Based Sentiment Analysis”. https://arxiv.org/abs/2210.06629
Ehsan Hosseini-Asl, Wenhao Liu, Caiming Xiong, 2022. “A Generative Language Model for Few-shot Aspect-Based Sentiment Analysis”. https://arxiv.org/abs/2204.05356
Lewis Tunstall, Nils Reimers, Unso Eun Seo Jo, Luke Bates, Daniel Korat, Moshe Wasserblat, Oren Pereg, 2022. “Efficient Few-Shot Learning Without Prompts”. https://arxiv.org/abs/2209.11055
🤗 宝子们可以戳 阅读原文 查看文中所有的外部链接哟!
英文原文: https://hf.co/blog/setfit-absa
原文作者: Ronen Laperdon,Tom Aarsen,Lewis Tunstall,Daniel Korat,Oren Pereg,Moshe Wasserblat
译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。