PaddleNLP情感分析应用立足真实企业用户对情感分析方面的需求,针对情感分析领域的痛点和难点,提供基于前沿模型的情感分析解决方案,助力开发者快速分析业务相关产品或服务的用户感受。
本项目以通用信息抽取模型UIE为训练底座,提供了语句级情感分析和属性级情感分析能力、覆盖情感分类、属性抽取、观点抽取等常用情感分析能力,如下图所示。同时提供了可视化能力,支持从输入数据到情感分析结果可视化,帮助用户快速分析业务数据。更进一步地,本项目同时支持基于业务数据进行定制训练,同时支持引入业务侧积累的经验和知识,包括同义属性和隐性观点词表,加强模型进行属性聚合和隐性观点抽取的能力,进一步提高模型对于业务场景数据的分析能力。
- 功能丰富🎓:提供情感分析训练模型作为底座,支持语句级情感分析和属性级情感分析,覆盖情感分类、属性与观点抽取、同义属性聚合、隐性观点抽取、可视化分析等常见情感分析任务。
- 效果领先✊: 以通用信息抽取模型UIE为训练底座,具有较强的零样本预测和小样本微调能力。
- 开箱即用👶:打通Taskflow使用流程,3行代码获取分析结果,同时提供了情感分析结果可视化能力。
- 定制模型🏃:支持针对特定业务场景进行全流程定制,包括数据标注、样本构建、模型训练和模型测试,同时通过融合业务相关的同义属性词和隐性观点词,可进一步提高模型针对业务场景的情感分析能力。
代码结构
unified_sentiment_extraction/
├── batch_predict.py # 以文件的形式输入,进行批量预测的脚本
├── evaluate.py # 模型评估脚本
├── finetune.py # 模型微调脚本
├── label_studio.py # 将label-studio导出数据转换为模型输入数据的脚本
├── label_studio.md # 将label-studio标注说明
├── utils.py # 工具函数脚本
├── visual_analysis.py # 情感分析结果可视化脚本
└── README.md # 使用说明
安装依赖
- python == 3.9.12
- paddlepaddle == 2.3.2
- paddlenlp == 2.4.5
- wordcloud == 1.8.2.2
安装PaddlePaddle:
环境中paddlepaddle-gpu或paddlepaddle版本应大于或等于2.3, 具体可以参见飞桨快速安装根据自己需求选择合适的PaddlePaddle下载命令。如下命令可以安装linux系统,CUDA版本为10.2环境下的paddlepaddle,具体版本号为支持GPU的2.3.2版本。
conda install paddlepaddle-gpu==2.3.2 cudatoolkit=10.2 --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/
安装PaddleNLP: 安装PaddleNLP可以开启百度镜像源来加速下载,更多关于PaddleNLP安装的详细教程请查见PaddleNLP快速安装。
python3 -m pip install --upgrade paddlenlp -i https://mirror.baidu.com/pypi/simple
安装wordcloud:
python3 -m pip install wordcloud==1.8.2.2
本项目以通用信息抽取模型UIE为训练底座,基于大量情感分析数据进一步训练,增强了模型对于情感知识的处理能力,支持语句级情感分类、属性抽取、观点词抽取、属性级情感分类等基础情感分析能力。下表展示了通用UIE uie-base
和情感知识增强的UIE uie-senta-base
在测试集上的效果对比。
模型 | Precision | Recall | F1 |
---|---|---|---|
uie-base |
0.86759 | 0.83696 | 0.85200 |
uie-senta-base |
0.93403 | 0.92795 | 0.93098 |
另外,为方便用户体验和使用,本项目提供的情感分析能力已经集成到了 Taskflow,可以通过Taskflow开箱即用的的能力快速体验情感分析的功能。
整句情感分析功能当前支持二分类:正向和负向,调用示例如下:
>>> from paddlenlp import Taskflow
>>> schema = ['情感倾向[正向,负向]']
>>> senta = Taskflow("sentiment_analysis", model="uie-senta-base", schema=schema)
>>> print(senta('蛋糕味道不错,店家服务也很好'))
[
{
'情感倾向[正向,负向]': [
{
'text': '正向',
'probability': 0.996646058824652
}
]
}
]
除语句级情感分析之外,本项目同时支持属性级情感分析,包括属性抽取(Aspect Term Extraction)、观点抽取(Opinion Term Extraction)、属性级情感分析(Aspect Based Sentiment Classification)等等。可以通过设置相应的schema进行对应信息的抽取,其调用示例如下。
>>> from paddlenlp import Taskflow
>>> # Aspect Term Extraction
>>> # schema = ["评价维度"]
>>> # Aspect - Opinion Extraction
>>> # schema = [{"评价维度":["观点词"]}]
>>> # Aspect - Sentiment Extraction
>>> # schema = [{"评价维度":["情感倾向[正向,负向,未提及]"]}]
>>> # Aspect - Sentiment - Opinion Extraction
>>> schema = [{"评价维度":["观点词", "情感倾向[正向,负向,未提及]"]}]
>>> senta = Taskflow("sentiment_analysis", model="uie-senta-base", schema=schema)
>>> print(senta('蛋糕味道不错,店家服务也很热情'))
[
{
'评价维度': [
{
'text': '服务',
'start': 9,
'end': 11,
'probability': 0.9709093024793489,
'relations': {
'观点词': [
{
'text': '热情',
'start': 13,
'end': 15,
'probability': 0.9897222206316556
}
],
'情感倾向[正向,负向,未提及]': [
{
'text': '正向',
'probability': 0.9999327669598301
}
]
}
},
{
'text': '味道',
'start': 2,
'end': 4,
'probability': 0.9105472387838915,
'relations': {
'观点词': [
{
'text': '不错',
'start': 4,
'end': 6,
'probability': 0.9946981266891619
}
],
'情感倾向[正向,负向,未提及]': [
{
'text': '正向',
'probability': 0.9998829392709467
}
]
}
}
]
}
]
更进一步地,在某些业务场景中,特别是一些垂域场景,用户可能比较关注固定的某些属性。在这种情况下,可以预先提供相应的属性集合,则本项目将只会在该属性集上进行情感分析,分析和抽取该集合中各个属性的信息。
针对固定属性的情感分析示例如下,需要将属性集合传入参数 aspects
中,后续将只针对这些属性进行分析。可以看到在示例中,传入了属性 房间
,位置
和 价格
,针对 房间
和 价格
均分析到了观点词和情感倾向,但是位置
由于在样本中并未提及,因此相应观点词为空,情感倾向为 未提及
。
>>> # define schema for pre-defined aspects, schema
>>> schema = ["观点词", "情感倾向[正向,负向,未提及]"]
>>> aspects = ["房间", "位置", "价格"]
>>> # set aspects for Taskflow
>>> senta = Taskflow("sentiment_analysis", model="uie-senta-base", schema=schema, aspects=aspects)
>>> print(senta("这家店的房间很大,店家服务也很热情,就是价格有点贵"))
[
{
'评价维度': [
{
'text': '房间',
'relations': {
'观点词': [
{
'text': '大',
'start': 7,
'end': 8,
'probability': 0.9998772175681552
}
],
'情感倾向[正向,负向,未提及]': [
{
'text': '正向',
'probability': 0.9999312170965595
}
]
}
},
{
'text': '位置',
'relations': {
'情感倾向[正向,负向,未提及]': [
{
'text': '未提及',
'probability': 0.9999939203353847
}
]
}
},
{
'text': '价格',
'relations': {
'观点词': [
{
'text': '贵',
'start': 24,
'end': 25,
'probability': 0.998841669863026
}
],
'情感倾向[正向,负向,未提及]': [
{
'text': '负向',
'probability': 0.9997340617174757
}
]
}
}
]
}
]
为方便用户实际业务应用情况,本项目多个版本的模型,可以根据业务对于精度和速度方面的要求进行选择,下表展示了不同版本模型的结构以及在测试集上的指标。
模型 | 结构 | Precision | Recall | F1 |
---|---|---|---|---|
uie-senta-base (默认) |
12-layers, 768-hidden, 12-heads | 0.93403 | 0.92795 | 0.93098 |
uie-senta-medium |
6-layers, 768-hidden, 12-heads | 0.93146 | 0.92137 | 0.92639 |
uie-senta-mini |
6-layers, 384-hidden, 12-heads | 0.91799 | 0.92028 | 0.91913 |
uie-senta-micro |
4-layers, 384-hidden, 12-heads | 0.91542 | 0.90957 | 0.91248 |
uie-senta-nano |
4-layers, 312-hidden, 12-heads | 0.90817 | 0.90878 | 0.90847 |
在Taskflow中,可以直接指定相应模型名称进行使用,使用uie-senta-mini
版本的示例如下:
>>> from paddlenlp import Taskflow
>>> schema = [{"评价维度":["观点词", "情感倾向[正向,负向,未提及]"]}]
>>> senta = Taskflow("sentiment_analysis", model="uie-senta-mini", schema=schema)
为方便使用,本项目提供了批量处理的功能,支持以文件形式输入,批量进行情感分析。同时打通了从数据到情感分析结果可视化的流程,帮助用户可以更加快速获取情感分析结果,聚焦于业务分析方面。
输入数据如下方式进行组织,每行表示一个文本评论。可以点击这里下载酒店场景的测试数据进行分析。
非常好的酒店 不枉我们爬了近一个小时的山,另外 大厨手艺非常棒 竹筒饭 竹筒鸡推荐入住的客人必须要点,
房间隔音效果不好,楼下KTV好吵的
酒店的房间很大,干净舒适,服务热情
怎么说呢,早上办理入住的,一进房间闷热的一股怪味,很臭,不能开热风,好多了,虽然房间小,但是合理范围
总台服务很差,房间一般
通过脚本 batch_predict.py
批量进行情感分析,通过 file_path
指定要进行情感分析的文件路径,处理完后,结果将会保存在 save_path
指定的文件中,示例如下:
python batch_predict.py \
--file_path "./data/test_hotel.txt" \
--save_path "./data/sentiment_analysis.json" \
--model "uie-senta-base" \
--schema "[{'评价维度': ['观点词', '情感倾向[正向,负向,未提及]']}]" \
--batch_size 4 \
--max_seq_len 512
参数说明:
file_path
: 用于进行情感分析的文件路径。save_path
: 情感分析结果的保存路径。model
: 进行情感分析的模型名称,可以在这些模型中进行选择:['uie-senta-base', 'uie-senta-medium', 'uie-senta-mini', 'uie-senta-micro', 'uie-senta-nano']。load_from_dir
: 指定需要加载的离线模型目录,比如训练后保存的模型,如果不进行指定,则默认根据model
指定的模型名称自动下载相应模型。schema
: 基于UIE模型进行信息抽取的Schema描述。batch_size
: 预测过程中的批处理大小,请结合显存情况进行调整,若出现显存不足,请适当调低这一参数;默认为 16。max_seq_len
: 模型支持处理的最大序列长度,默认为512。aspects
: 预先给定的属性,如果设置,模型将只针对这些属性进行情感分析,比如分析这些属性的观点词。
在情感分析处理之后,可以根据情感分析的保存结果进行可视化展示,帮助用户更友好地分析业务特点。默认情况下,可视化功能支持围绕属性、观点、属性+观点、属性+情感、指定属性+观点分析功能。在各项分析中,均支持词云和直方图两类图像展示。
下面将以酒店场景数据为例进行展示。
4.2.3.1 一键生成情感分析结果
基于以上生成的情感分析结果,可以使用visual_analysis.py
脚本对情感分析结果进行可视化,最终可视化结果将会被保存在 save_dir
指定的目录下。 使用时需要指定情感分析可视化的结果的任务类型,若是语句级的情感分类,则将task_type指定为cls
,若是属性级的情感分析,则将task_type指定为ext
,示例如下:
python visual_analysis.py \
--file_path "./outputs/test_hotel.json" \
--save_dir "./outputs/images" \
--task_type "ext"
可配置参数说明:
file_path
: 指定情感分析结果的保存路径。save_dir
: 指定图片的保存目录。task_type
: 指定任务类型,语句级情感分类请指定为cls
,属性级情感分析请指定为ext
,默认为ext
。font_path
: 指定字体文件的路径,用以在生成的wordcloud图片中辅助显示中文,如果为空,则会自动下载黑体字,用以展示中文字体。
备注:在visual_analysis.py
脚本启动时,默认会删除当前已经存在的save_dir
目录以及其中文件,然后在该目录下重新生成相应的可视化图片。
下图展示了对酒店场景数据分析后的部分图片:
4.2.3.2 情感分析详细展示
(1) 属性分析
通过属性信息,可以查看客户对于产品/服务的重点关注方面. 可以通过plot_aspect_with_frequency
函数对属性进行可视化,当前可通过参数image_type
分别指定wordcloud
和'histogram',通过词云和直方图的形式进行可视化。
# define SentimentResult to process the result of sentiment result.
sr = SentimentResult(args.file_path, sentiment_name=args.sentiment_name)
# define VisualSentiment to help visualization
vs = VisualSentiment(font_path=args.font_path)
# visualization for aspect
save_path = os.path.join(args.save_dir, "aspect_wc.png")
vs.plot_aspect_with_frequency(sr.aspect_frequency, save_path, image_type="wordcloud")
save_path = os.path.join(args.save_dir, "aspect_hist.png")
vs.plot_aspect_with_frequency(sr.aspect_frequency, save_path, image_type="histogram")
(2) 观点分析
通过观点信息,可以查看客户对于产品/服务整体的直观印象。可以通过plot_opinion_with_frequency
函数对观点进行可视化。
# visualization for opinion
save_path = os.path.join(args.save_dir, "opinion_wc.png")
vs.plot_opinion_with_frequency(sr.opinion_frequency, save_path, image_type="wordcloud")
(3) 属性+观点分析
结合属性和观点两者信息,可以更加具体的展现客户对于产品/服务的详细观点,分析某个属性的优劣,从而能够帮助商家更有针对性地改善或提高自己的产品/服务质量。可以通过plot_aspect_with_opinion
函数对属性+观点进行可视化,同时可通过设置参数sentiment
按照情感倾向展示不同分析结果,以更好进行情感分析,若设置为all
,则会展示正向和负向所有的属性;若为positive
,则会仅展示正向的属性;若为negative
,则会仅展示负向的属性。如果在绘制直方图时,通过设置参数top_n
,可以展示频率最高的top n个属性。
# visualization for aspect + opinion
save_path = os.path.join(args.save_dir, "aspect_opinion_wc.png")
vs.plot_aspect_with_opinion(sr.aspect_opinion, save_path, image_type="wordcloud", sentiment="all")
save_path = os.path.join(args.save_dir, "aspect_opinion_hist.png")
vs.plot_aspect_with_opinion(sr.aspect_opinion, save_path, image_type="histogram", sentiment="all", top_n=8)
(4) 属性+情感分析
挖掘客户对于产品/服务针对属性的情感极性,帮助商家直观地查看客户对于产品/服务的某些属性的印象。可以通过plot_aspect_with_sentiment
函数对属性+情感进行可视化。如果在绘制直方图时,通过设置参数top_n
,可以展示频率最高的top n个属性。
# visualization for aspect + sentiment
save_path = os.path.join(args.save_dir, "aspect_sentiment_wc.png")
vs.plot_aspect_with_sentiment(sr.aspect_sentiment, save_path, image_type="wordcloud")
save_path = os.path.join(args.save_dir, "aspect_sentiment_hist.png")
vs.plot_aspect_with_sentiment(sr.aspect_sentiment, save_path, image_type="histogram", top_n=15, descend_aspects=sr.descend_aspects)
(5) 对给定属性进行观点分析
通过指定属性,更加细致查看客户对于产品/服务某个属性的观点。可以帮助商家更加细粒度地分析客户对于产品/服务的某个属性的印象。下面图片示例中,展示了客户对于属性"房间"的观点。可以通过plot_opinion_with_aspect
函数,对给定的属性进行观点分析。默认情况下,不会自动生成该类图像,需要开发者手动调用plot_opinion_with_aspect
进行可视化分析。
aspect = "房间"
save_path = os.path.join(args.save_dir, "opinions_for_aspect_wc.png")
vs.plot_opinion_with_aspect(aspect, sr.aspect_opinion, save_path, image_type="wordcloud")
save_path = os.path.join(args.save_dir, "opinions_for_aspect_hist.png")
vs.plot_opinion_with_aspect(aspect, sr.aspect_opinion, save_path, image_type="histogram")
考虑到用户在对业务数据进行情感分析时,往往聚焦于某个特定场景或领域,为满足用户更高的情感分析要求,本项目支持从以下方面协助用户,结合业务经验,进一步定制情感分析能力,提高模型对业务数据的理解和分析能力。
- 数据层面:打通 label-studio 平台,定制了情感信息的标注规则,支持根据标注数据自动转换为模型输入样本。
- 属性聚合:结合业务经验,支持传入同义的属性集合,可以增强模型对于数据聚合的能力。
- 隐性观点抽取:结合业务经验,支持自定义隐性观点词表,可以增强模型对于隐性观点的抽取能力。
下面以酒店场景为例,讲解定制酒店垂域的情感分析能力。具体地,将从数据标注及样本构建 - 模型训练 - 模型测试 - 模型预测及效果展示等全流程展开介绍。
本项目建议用户使用 label-studio 平台标注数据,同时提供了一套用于情感信息标注的规则,可以参考情感分析任务Label Studio使用指南获取更多信息,这里不再赘述。同时本项目打通了从 label-studio 标注平台到转换为模型输入形式数据的流程, 即支持用户在基于 label_studio 标注业务侧数据后,通过label-studio 导出标注好的json数据, 然后利用本项目提供的 label_studio.py
脚本,可以将导出数据一键转换为模型训练数据。
在利用 label_studio.py
脚本进行数据转换时,需要考虑任务类型的不同,选择相应的样本构建方式,整体可以分为 分类
和 抽取
任务。
为方便用户使用,本项目提供了300+条酒店场景的标注数据,可点击这里进行下载,请注意该数据仅适合用于 抽取
类型的任务。
对于语句级情感分类任务,默认支持2分类:正向
和 负向
,可以通过如下命令构造相关训练数据。
python label_studio.py \
--label_studio_file ./data/label_studio.json \
--task_type cls \
--save_dir ./data \
--splits 0.8 0.1 0.1 \
--options "正向" "负向" \
--is_shuffle True \
--seed 1000
参数介绍:
label_studio_file
: 从label studio导出的语句级情感分类的数据标注文件。task_type
: 选择任务类型,可选有抽取和分类两种类型的任务,其中前者需要设置为ext
,后者需要设置为cls
。由于此处为语句级情感分类任务,因此需要设置为cls
。save_dir
: 训练数据的保存目录,默认存储在data
目录下。splits
: 划分数据集时训练集、验证集所占的比例。默认为[0.8, 0.1, 0.1]表示按照8:1:1
的比例将数据划分为训练集、验证集和测试集。options
: 情感极性分类任务的选项设置。对于语句级情感分类任务,默认支持2分类:正向
和负向
;对于属性级情感分析任务,默认支持3分类:正向
,负向
和未提及
,其中未提及
表示要分析的属性在原文本评论中未提及,因此无法分析情感极性。如果业务需要其他情感极性选项,可以通过options
字段进行设置,需要注意的是,如果定制了options
,参数label_studio_file
指定的文件需要包含针对新设置的选项的标注数据。is_shuffle
: 是否对数据集进行随机打散,默认为True。seed
: 随机种子,默认为1000.
备注:参数options
可以不进行手动指定,如果这么做,则采用默认的设置。针对语句级情感分类任务,其默认将被设置为:"正向" "负向"
;对于属性级情感分析任务,默认将被设置为:"正向" "负向" "未提及"
。
针对抽取式的任务,比如属性-观点抽取、属性-情感极性-观点词抽取、属性分类任务等,可以使用如下命令将label-studio导出数据转换为模型训练数据。
python label_studio.py \
--label_studio_file ./data/label_studio.json \
--task_type ext \
--save_dir ./data \
--splits 0.8 0.1 0.1 \
--options "正向" "负向" "未提及" \
--negative_ratio 5 \
--is_shuffle True \
--seed 1000
重点参数介绍:
label_studio_file
: 从label studio导出的属性抽取相关的数据标注文件。task_type
: 选择任务类型,可选有抽取和分类两种类型的任务,其中前者需要设置为ext
,后者需要设置为cls
。由于此处为属性抽取相关任务,因此需要设置为ext
。negative_ratio
表示对于一个样本,为每个子任务(属性级的观点抽取,属性级的情感分类)最多生成negative_ratio
个负样本。如果额外提供了属性同义词标或隐性观点抽取词表,将结合两者信息生成更多的负样本,以增强属性聚合和隐性观点抽取能力。 其他参数解释同上,这里不再赘述。
在用户对产品或服务进行评论时,对某一些属性可能会有不同的说法,这会在后续对属性分析时可能会带来困扰。如以下示例中的"价格","价钱"和"费用"。
蛋糕味道不错,外观很漂亮,而且价格比较便宜
蛋糕味道不错,外观很漂亮,而且价钱比较便宜
蛋糕味道不错,外观很漂亮,而且费用比较便宜
针对这种情况,针对属性相关任务,本项目同时支持用户结合业务经验,通过设置同义的属性词表,加强模型的属性聚合能力。具体来讲,本项目期望通过以下两点,支持对属性聚合能力的建设。
- 支持针对用户给定的属性进行情感分析
- 支持用户提供同义的属性词表,用以加强模型对用户领域属性同义词的理解能力
以下给出了酒店场景的示例,每行代表1类同义词,不同词之间以"空格"隔开。
房间 屋子 房子
位置 地理位置
隔音 隔声
价格 价钱 费用
可以通过以下命令,使用synonym_file指定凝聚业务经验的同义属性集合,利用同义属性生成对应的数据样本:
python label_studio.py \
--label_studio_file ./data/label_studio.json \
--synonym_file ./data/synonyms.txt \
--task_type ext \
--save_dir ./data \
--splits 0.8 0.1 0.1 \
--options "正向" "负向" "未提及" \
--negative_ratio 5 \
--is_shuffle True \
--seed 1000
另外,本项目同时支持加强对隐性观点功能抽取的能力,这里需要说明一点,本项目中定义隐性观点是指没有对应属性的纯观点词,如以下示例中的"比较便宜"便是隐性观点。
蛋糕味道不错,外观很漂亮,而且比较便宜
本项目支持用户提供一个隐性观点映射文件,用户可以根据自己的业务场景定义隐性观点词,以下给出了酒店场景的示例。其格式为,第1个单词为隐性观点对应的属性,后续按照情感情感倾向对隐性观点词进行了归类,同一类的以"[ ]"方式放到一块。
价格, 正向[实惠 便宜 超划算 划算 物超所值 物有所值 不贵], 负向[贵 不便宜 不划算]
卫生, 正向[干净], 负向[很脏 很臭 不干净]
隔音, 负向[好吵]
位置, 负向[不太好找]
可以通过参数"implicit_file"指定凝聚业务经验的隐性观点词表,生成对应的隐性观点数据样本:
python label_studio.py \
--label_studio_file ./data/label_studio.json \
--implicit_file ./data/implicit_opinions.txt \
--task_type ext \
--save_dir ./data \
--splits 0.8 0.1 0.1 \
--options "正向" "负向" "未提及" \
--negative_ratio 5 \
--is_shuffle True \
--seed 1000
在生成酒店场景的训练数据后,可以通过以下命令启动模型训练:
python -u -m paddle.distributed.launch --gpus "0" finetune.py \
--train_path ./data/train.json \
--dev_path ./data/dev.json \
--save_dir ./checkpoint \
--learning_rate 1e-5 \
--batch_size 16 \
--max_seq_len 512 \
--num_epochs 3 \
--model uie-senta-base \
--seed 1000 \
--logging_steps 10 \
--valid_steps 100 \
--device gpu
可配置参数说明:
train_path
:必须,训练集文件路径。dev_path
:必须,验证集文件路径。save_dir
:模型 checkpoints 的保存目录,默认为"./checkpoint"。learning_rate
:训练最大学习率,UIE 推荐设置为 1e-5;默认值为1e-5。batch_size
:训练集训练过程批处理大小,请结合显存情况进行调整,若出现显存不足,请适当调低这一参数;默认为 16。max_seq_len
:模型支持处理的最大序列长度,默认为512。num_epochs
:模型训练的轮次,可以视任务情况进行调整,默认为10。model
:训练使用的预训练模型。可选择的有uie-senta-base
,uie-senta-medium
,uie-senta-mini
,uie-senta-micro
,uie-senta-nano
,默认为uie-senta-base
。logging_steps
: 训练过程中日志打印的间隔 steps 数,默认10。valid_steps
: 训练过程中模型评估的间隔 steps 数,默认100。seed
:全局随机种子,默认为 42。device
: 训练设备,可选择 'cpu'、'gpu' 其中的一种;默认为 GPU 训练。
通过运行以下命令进行对酒店场景的测试集进行评估:
python evaluate.py \
--model_path ./checkpoint/model_best \
--test_path ./data/test.json \
--batch_size 16 \
--max_seq_len 512
可配置参数说明:
model_path
:必须,进行评估的模型文件夹路径,路径下需包含模型权重文件model_state.pdparams及配置文件model_config.json。test_path
:必须,进行评估的测试集文件。batch_size
:训练集训练过程批处理大小,请结合显存情况进行调整,若出现显存不足,请适当调低这一参数;默认为 16。max_seq_len
:文本最大切分长度,输入超过最大长度时会对输入文本进行自动切分,默认为512。debug
: 是否开启debug模式对每个正例类别分别进行评估,该模式仅用于模型调试,默认关闭。
在构造样本过程中,如果设置了最大负例比例negative_ratio,会在样本中添加一定数量的负样本,模型测试默认会对正样本和负样本共同进行评估。特别地,当开启debug模式后,会对每个正例类别分别进行评估,该模式仅用于模型调试:
python evaluate.py \
--model_path ./checkpoint/model_best \
--test_path ./data/test.json \
--batch_size 16 \
--max_seq_len 512 \
--debug
输出打印示例:
[2022-12-12 05:20:06,152] [ INFO] - -----------------------------
[2022-12-12 05:20:06,152] [ INFO] - Class Name: 评价维度
[2022-12-12 05:20:06,152] [ INFO] - Evaluation Precision: 0.89655 | Recall: 0.89655 | F1: 0.89655
[2022-12-12 05:20:06,553] [ INFO] - -----------------------------
[2022-12-12 05:20:06,553] [ INFO] - Class Name: 观点词
[2022-12-12 05:20:06,553] [ INFO] - Evaluation Precision: 0.81159 | Recall: 0.86154 | F1: 0.83582
[2022-12-12 05:20:07,610] [ INFO] - -----------------------------
[2022-12-12 05:20:07,611] [ INFO] - Class Name: X的观点词
[2022-12-12 05:20:07,611] [ INFO] - Evaluation Precision: 0.92222 | Recall: 0.90217 | F1: 0.91209
[2022-12-12 05:20:08,331] [ INFO] - -----------------------------
[2022-12-12 05:20:08,331] [ INFO] - Class Name: X的情感倾向[未提及,正向,负向]
[2022-12-12 05:20:08,331] [ INFO] - Evaluation Precision: 0.81481 | Recall: 0.81481 | F1: 0.81481
paddlenlp.Taskflow装载定制模型,通过task_path指定模型权重文件的路径,路径下需要包含训练好的模型权重文件model_state.pdparams。
>>> # define schema
>>> schema = [{'评价维度': ['观点词', '情感倾向[正向,负向,未提及]']}]
>>> senta = Taskflow("sentiment_analysis", model="uie-senta-base", schema=schema, task_path="./checkpoint/model_best")
>>> senta("这家点的房间很大,店家服务也很热情,就是房间隔音不好")
[
{
'评价维度': [
{
'text': '服务',
'start': 11,
'end': 13,
'probability': 0.9600759151746807,
'relations': {
'观点词': [
{
'text': '热情',
'start': 15,
'end': 17,
'probability': 0.9995151134519027
}
],
'情感倾向[正向,负向,未提及]': [
{
'text': '正向',
'probability': 0.9998306104766073
}
]
}
},
{
'text': '隔音',
'start': 22,
'end': 24,
'probability': 0.9993525950520166,
'relations': {
'观点词': [
{
'text': '不好',
'start': 24,
'end': 26,
'probability': 0.9992370362201655
}
],
'情感倾向[正向,负向,未提及]': [
{
'text': '负向',
'probability': 0.9842680108546062
}
]
}
},
{
'text': '房间',
'start': 4,
'end': 6,
'probability': 0.9991784415865368,
'relations': {
'观点词': [
{
'text': '很大',
'start': 6,
'end': 8,
'probability': 0.8359714693985723
}
],
'情感倾向[正向,负向,未提及]': [
{
'text': '正向',
'probability': 0.997688853839179
}
]
}
}
]
}
]
下面就 隔音
与 价格
两个属性进行分析,抽取样本中与这两个属性相关的情感信息,代码如下:
>>> schema = [{'评价维度': ['观点词', '情感倾向[正向,负向,未提及]']}]
>>> aspects = ["隔音", "价格"]
>>> senta = Taskflow("sentiment_analysis", model="uie-senta-base", schema=schema, task_path="./checkpoint/model_best", aspects=aspects)
>>> senta("这家点的房间很大,店家服务也很热情,就是房间隔音不好")
下图展示了关于模型对于属性聚合能力支持的样本,在分析之前设定固定的属性集合["隔音", "价格"]
,可以看到尽管语料中同时出现了隔音
、隔声
、价格
、价钱
和费用
,但是经过定制后的情感分析模型依然能够准确识别出对于属性 隔音
和 价格
的情感信息,从而起到属性聚合的效果。
样本 | 属性 | 观点词 | 情感倾向 |
---|---|---|---|
这家店的房间很大,隔音效果不错,而且价格很便宜 | 隔音 | 不错 | 正向 |
房间比较小,隔声也不太好,设施还是挺齐全的 | 隔音 | 不太好 | 负向 |
房间还不错,有免费的矿泉水,而且价格很实惠 | 价格 | 实惠 | 正向 |
房间很大,店家也挺热情,很棒,就是价钱有点贵 | 价格 | 贵 | 负向 |
酒店不错,房间面积大,住的也舒适,而且价格很划算 | 价格 | 划算 | 正向 |
房间好大呀,而且这边还挺安静的,不过整体还是很好的,很宽敞,而且价格很便宜 | 价格 | 便宜 | 正向 |
下面就价格
和 卫生
两个属性进行分析隐性观点,抽取样本中与这两个属性相关的情感信息,代码如下:
对于"价格"的调用示例:
>>> schema = [{'评价维度': ['观点词', '情感倾向[正向,负向,未提及]']}]
>>> aspects = ["价格"]
>>> senta = Taskflow("sentiment_analysis", model="uie-senta-base", schema=schema, task_path="./checkpoint/model_best", aspects=aspects)
>>> senta("这家店的房间很大,店家服务也很热情,而且很便宜")
下图展示了关于模型对于隐性观点抽取的样本,可以看到,虽然以下这些样本中,并未出现价格
和 卫生
,但模型依然正确识别除了这两个属性的情感信息。
样本 | 属性 | 观点词 | 情感倾向 |
---|---|---|---|
房间比较大,就是感觉贵了点,不太划算 | 价格 | 贵、不太划算 | 负向 |
这家店的房间很大,店家服务也很热情,而且很便宜 | 价格 | 便宜 | 正向 |
这次来荆州给我的房间小的无语了,所幸比较实惠 | 价格 | 实惠 | 正向 |
酒店不大,有点不干净 | 卫生 | 不干净 | 负向 |
老板人很好,房间虽然很大,但有点脏 | 卫生 | 脏 | 负向 |
房间不大,很温暖,也很干净 | 卫生 | 干净 | 正向 |
本项目支持基于PaddleNLP SimpleServing进行服务化部署,可以在deploy
目录下执行以下命令启动服务和请求。
启动服务
paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8189
Client发送请求
服务启动后, 通过 client.py
脚本发送请求:
python client.py
多卡服务化预测
PaddleNLP SimpleServing 支持多卡负载均衡预测,主要在服务化注册的时候,注册两个Taskflow的task即可,代码示例如下:
senta1 = Taskflow("sentiment_analysis", schema=schema, model="uie-senta-base", device_id=0)
senta2 = Taskflow("sentiment_analysis", schema=schema, model="uie-senta-base", device_id=1)
app.register_taskflow('senta', [senta1, senta2])
本项目支持基于Pipeline的方式进行部署,用户只需要上传测试文件,即可获取对应的情感分析可视化结果,更多信息请参考情感分析Pipeline。