Paddlenlp之UIE分类模型【以情感倾向分析新闻分类为例】含智能标注方案)
相关文章:
Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】
项目连接:百度AIstudio直接fork我的项目就可以复现
Paddlenlp之UIE分类模型【以情感倾向分析新闻分类为例】含智能标注方案)
0 前言
首先回顾上一个项目:
Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】
会存在以下问题:
自己样本数据该如何标注
如果样本量大有什么好方法进行智能标注
可视化工具详细介绍
本次项目将会先把,数据标注、智能标注、数据可视化方法
进行详细讲解。
0.1 如何对数据进行标注—doccano
强烈推荐:数据标注平台doccano----简介、安装、使用、踩坑记录
详细步骤可以参考博客
官方文档:
https://github.com/doccano/doccano
记的进虚拟环境!!!!!
Step 1. 本地安装doccano(请勿在AI Studio内部运行,本地测试环境python=3.8)
$ pip install doccano
Step 2. 初始化数据库和账户(用户名和密码可替换为自定义值)
# 初始化,设置用户名= admin,密码=pass
doccano init
doccano createuser --username admin --password pass
-------------------------个人设置---------------------------
$ doccano init
$ doccano createuser --username my_admin_name --password my_password
Step 3. 启动doccano
在一个窗口启动doccano的WebServer,保持窗口
$ doccano webserver --port 8000
在另一个窗口启动doccano的任务队列
$ doccano task
打开浏览器(推荐Chrome),在地址栏中输入http://127.0.0.1:8000/后回车即得以下界面。
具体如何进行标注请参考博客或者官网文档
0.2 智能标注
当你数据样本很大的时候,一条条标注会很费时,效率很低
这里推荐去hugging face加载一些预训练模型进行一次标注再进行人工复核。
基于 hugging face 预训练模型的实体识别智能标注方案:生成doccano要求json格式
根据doccano标注平台格式要求
json格式导入数据格式要求: 实体;包含关系样式展示
{
"text": "Google was founded on September 4, 1998, by Larry Page and Sergey Brin.",
"entities": [
{
"id": 0,
"start_offset": 0,
"end_offset": 6,
"label": "ORG"
},
{
"id": 1,
"start_offset": 22,
"end_offset": 39,
"label": "DATE"
},
{
"id": 2,
"start_offset": 44,
"end_offset": 54,
"label": "PERSON"
},
{
"id": 3,
"start_offset": 59,
"end_offset": 70,
"label": "PERSON"
}
],
"relations": [
{
"from_id": 0,
"to_id": 1,
"type": "foundedAt"
},
{
"from_id": 0,
"to_id": 2,
"type": "foundedBy"
},
{
"from_id": 0,
"to_id": 3,
"type": "foundedBy"
}
]
}
0.3 实体智能标注+格式转换
0.3.1 长文本(一个txt长篇)code
注释部分包含预训练模型识别实体;以及精灵标注助手格式要求
ps:提示一下下面这段程序是在torch下用的,因为直接拿的huggingface预训练模型,降低我们工作量。用paddle的话求快推荐UIE直接小样本搞一个简单预模型协助标注!
from transformers import pipeline
import os
from tqdm import tqdm
import pandas as pd
from time import time
import json
def return_single_entity(name, start, end):
return [int(start), int(end), name]
# def return_single_entity(name, word, start, end, id, attributes=[]):
# entity = {}
# entity['type'] = 'T'
# entity['name'] = name
# entity['value'] = word
# entity['start'] = int(start)
# entity['end'] = int(end)
# entity['attributes'] = attributes
# entity['id'] = int(id)
# return entity
# input_dir = 'E:/datasets/myUIE/inputs'
input_dir = 'C:/Users/admin/Desktop//test_input.txt'
output_dir = 'C:/Users/admin/Desktop//outputs'
tagger = pipeline(task='ner', model='xlm-roberta-large-finetuned-conll03-english',
aggregation_strategy='simple')
keywords = {'PER': '人', 'ORG': '机构'} # loc 地理位置 misc 其他类型实体
# for filename in tqdm(input_dir):
# # 读取数据并自动打标
# json_list = []
with open(input_dir, 'r', encoding='utf8') as f:
text = f.readlines()
json_list = [0 for i in range(len(text))]
for t in text:
i = t.strip("\n").strip("'").strip('"')
named_ents = tagger(i) # 预训练模型
# named_ents = tagger(text)
df = pd.DataFrame(named_ents)
""" 标注结果:entity_group score word start end
0 ORG 0.999997 National Science Board 18 40
1 ORG 0.999997 NSB 42 45
2 ORG 0.999997 NSF 71 74"""
# 放在循环里面,那每次开始新的循环就会重新定义一次,上一次定义的内容就丢了
# json_list = [0 for i in range(len(text))]
entity_list=[]
# entity_list2=[]
for index, elem in df.iterrows():
if not elem.entity_group in keywords:
continue
if elem.end - elem.start <= 1:
continue
entity = return_single_entity(
keywords[elem.entity_group], elem.start, elem.end)
entity_list.append(entity)
# entity_list2.append(entity_list)
json_obj = {"text": text[index], "label": entity_list}
json_list[index] = json.dumps(json_obj)
# entity_list.append(entity)
# data = json.dumps(json_list)
# json_list.append(data)
with open(f'{output_dir}/data_2.json', 'w', encoding='utf8') as f:
for line in json_list:
f.write(line+"\n")
# f.write('\n'.join(data))
# f.write(str(data))
print('done!')
# 转化为精灵标注助手导入格式(但是精灵标注助手的nlp标注模块有编码的问题,部分utf8字符不能正常显示,会影响标注结果)
# id = 1
# entity_list = ['']
# for index, elem in df.iterrows():
# if not elem.entity_group in keywords:
# continue
# entity = return_single_entity(keywords[elem.entity_group], elem.word, elem.start, elem.end, id)
# id += 1
# entity_list.append(entity)
# python_obj = {'path': f'{input_dir}/{filename}',
# 'outputs': {'annotation': {'T': entity_list, "E": [""], "R": [""], "A": [""]}},
# 'time_labeled': int(1000 * time()), 'labeled': True, 'content': text}
# data = json.dumps(python_obj)
# with open(f'{output_dir}/{filename.rstrip(".txt")}.json', 'w', encoding='utf8') as f:
# f.write(data)
输出结果:
{"text": "The company was founded in 1852 by Jacob Estey\n", "label": [[35, 46, "\u4eba"]]}
{"text": "The company was founded in 1852 by Jacob Estey, who bought out another Brattleboro manufacturing business.", "label": [[35, 46, "\u4eba"], [71, 82, "\u673a\u6784"]]}
可以看到label标签是乱码的,不用在意导入到doccano平台后会显示正常
0.3.2 提高标注质量
- 人工复核
不多说就是一条一条检查过去,智能标注后已经省事很多了
对已标注数据进行
- 删除无效标注
import json
dir_path = r'C:/Users/admin/Desktop/光合项目/自动标注' # 这里改文件地址
with open(f'{dir_path}/pre_data.jsonl', 'r',encoding='utf8')as f: # 文件命名
text = f.readlines()
content = [json.loads(elem.strip('\n')) for elem in text]
content = [json.dumps(cont) for cont in content if cont['entities'] != []]
with open(f'{dir_path}/remove_empty_data.jsonl', 'w',encoding='utf8')as f: # 文件命名
f.write('\n'.join(content))
print("输出数据")
- 上述处理在英文版本数据集上有不错体现,当然在中文版本可以在上述基础上,用paddle UIE等模型,先人工小批量标注,然后生成个base模型,通过模型对输入结果进行预标注,再人工复核
当然你可能会问还有更简单的方法吗,当然是有的!!!
闪亮登场!!!!
EasyData 为百度大脑推出的一站式数据处理和服务平台,主要围绕AI模型开发过程中所需的数据采集、数据质检、数据智能处理、数据标注等环节提供完整的数据服务。目前EasyData已支持图片、文本、音频、视频、表格五类基础数据的处理。
同时EasyData已与EasyDL、BML平台数据管理模块打通,EasyData处理的数据可直接应用于EasyDL、BML平台进行模型训练。
功能齐全很强大,小伙伴们可以试一试哦!
我就不做更多推广了,,信百度没问题,哈哈。
0.4 visualDL工具使用,可视化利器。
VisualDL 是一个面向深度学习任务设计的可视化工具。VisualDL 利用了丰富的图表来展示数据,用户可以更直观、清晰地查看数据的特征与变化趋势,有助于分析数据、及时发现错误,进而改进神经网络模型的设计。
目前,VisualDL 支持 scalar, image, audio, graph, histogram, prcurve, high dimensional 七个组件.
不进行过多介绍,可以参考我的项目或者博客。有详细讲解!!!
from visualdl import LogWriter
if __name__ == '__main__':
value = [i/1000.0 for i in range(1000)]
# 步骤一:创建父文件夹:log与子文件夹:scalar_test
with LogWriter(logdir="./log/scalar_test") as writer:
for step in range(1000):
# 步骤二:向记录器添加一个tag为`train/acc`的数据
writer.add_scalar(tag="train/acc", step=step, value=value[step])
# 步骤二:向记录器添加一个tag为`train/loss`的数据
writer.add_scalar(tag="train/loss", step=step, value=1/(value[step] + 1))
# 步骤一:创建第二个子文件夹scalar_test2
value = [i/500.0 for i in range(1000)]
with LogWriter(logdir="./log/scalar_test2") as writer:
for step in range(1000):
# 步骤二:在同样名为`train/acc`下添加scalar_test2的accuracy的数据
writer.add_scalar(tag="train/acc", step=step, value=value[step])
# 步骤二:在同样名为`train/loss`下添加scalar_test2的loss的数据
writer.add_scalar(tag="train/loss", step=step, value=1/(value[step] + 1))
1. 背景介绍
文本分类任务是自然语言处理中最常见的任务,文本分类任务简单来说就是对给定的一个句子或一段文本使用文本分类器进行分类。文本分类任务广泛应用于长短文本分类、情感分析、新闻分类、事件类别分类、政务数据分类、商品信息分类、商品类目预测、文章分类、论文类别分类、专利分类、案件描述分类、罪名分类、意图分类、论文专利分类、邮件自动标签、评论正负识别、药物反应分类、对话分类、税种识别、来电信息自动分类、投诉分类、广告检测、敏感违法内容检测、内容安全检测、舆情分析、话题标记等各类日常或专业领域中。
文本分类任务可以根据标签类型分为多分类(multi class)、多标签(multi label)、层次分类(hierarchical)等三类任务。
进入正片,本项目将演示多分类任务如何通过小样本样本进行模型微调.
数据集情况:
数据概览: 7000 多条酒店评论数据,5000 多条正向评论,2000 多条负向评论
推荐实验: 情感/观点/评论 倾向性分析
数据来源:携程网
原数据集: ChnSentiCorp_htl,由谭松波老师整理的一份数据集
cla.jsonl是数据集demo:
{"id":1286,"text":"這間酒店環境和服務態度亦算不錯,但房間空間太小~~不宣容納太大件行李~~且房間格調還可以~~ 中餐廳的廣東點心不太好吃~~要改善之~~~~但算價錢平宜~~可接受~~ 西餐廳格調都很好~~但吃的味道一般且令人等得太耐了~~要改善之~~\t","label":["正向"]}
{"id":1287,"text":"<荐书> 推荐所有喜欢<红楼>的红迷们一定要收藏这本书,要知道当年我听说这本书的时候花很长时间去图书馆找和借都没能如愿,所以这次一看到当当有,马上买了,红迷们也要记得备货哦!\t","label":["正向"]}
{"id":1288,"text":"商品的不足暂时还没发现,京东的订单处理速度实在.......周二就打包完成,周五才发货...\t","label":["负向"]}
{"id":1289,"text":"2001年来福州就住在这里,这次感觉房间就了点,温泉水还是有的.总的来说很满意.早餐简单了些.\t","label":["正向"]}
{"id":1290,"text":"不错的上网本,外形很漂亮,操作系统应该是个很大的 卖点,电池还可以。整体上讲,作为一个上网本的定位,还是不错的。\t","label":["正向"]}
{"id":1291,"text":"房间地毯太脏,临近火车站十分吵闹,还好是双层玻璃。服务一般,酒店门口的TAXI讲是酒店的长期合作关系,每月要交费给酒店。从酒店到机场讲得是打表147元,到了后非要200元,可能被小宰30-40元。\t","label":["负向"]}
{"id":1292,"text":"本来想没事的时候翻翻,可惜看不下去,还是和张没法比,他的书能畅销大部分还是受张的影响,对这个男人实在是没好感,不知道怎么买的,后悔\t","label":["负向"]}
1.1结果展示预览
输入:
酒店环境和服务都还不错,地理位置也不错,尤其是酒店北面的川北凉粉确实好吃。
设施老化,紧靠马路噪音太大。晚上楼上卫生间的水流声和空调噪音非常大,无法入眠。
很不错的一个酒店,床很大,很舒服.酒店员工的服务态度很亲切。
非常糟糕!我们通过其商务中心包了一辆车游西湖,该车拉我们去不正规景点买茶叶。
总的来说,酒店还不错。比较安静,地理位置比较好,服务也不错,包括入住和结账。
输出:
[{'text': '酒店环境和服务都还不错,地理位置也不错,尤其是酒店北面的川北凉粉确实好吃。\n', 'label': 'positive', 'score': 0.8420582413673401},
{'text': '设施老化,紧靠马路噪音太大。晚上楼上卫生间的水流声和空调噪音非常大,无法入眠。\n', 'label': 'negative', 'score': 0.9905866980552673},
{'text': '很不错的一个酒店,床很大,很舒服.酒店员工的服务态度很亲切。\n', 'label': 'positive', 'score': 0.9800688028335571},
{'text': '非常糟糕!我们通过其商务中心包了一辆车游西湖,该车拉我们去不正规景点买茶叶。\n', 'label': 'negative', 'score': 0.9315289258956909},
{'text': '总的来说,酒店还不错。比较安静,地理位置比较好,服务也不错,包括入住和结账。', 'label': 'positive', 'score': 0.90092933177948}]
1.2 数据集加载
!python doccano.py \
--doccano_file ./data/cla.jsonl \
--task_type 'cls' \
--save_dir ./data \
--splits 0.8 0.1 0.1 \
--negative_ratio 5 \
--prompt_prefix "情感倾向" \
--options "正向" "负向"
2022-07-18 11:28:41,687] [ INFO] - Converting doccano data...
0%| | 0/8 [00:00<?, ?it/s]
[2022-07-18 11:28:41,689] [ INFO] - Converting doccano data...
0%| | 0/1 [00:00<?, ?it/s]
[2022-07-18 11:28:41,690] [ INFO] - Converting doccano data...
0%| | 0/2 [00:00<?, ?it/s]
[2022-07-18 11:28:41,691] [ INFO] - Save 8 examples to ./data/train.txt.
[2022-07-18 11:28:41,691] [ INFO] - Save 1 examples to ./data/dev.txt.
[2022-07-18 11:28:41,691] [ INFO] - Save 2 examples to ./data/test.txt.
[2022-07-18 11:28:41,691] [ INFO] - Finished! It takes 0.00 seconds
doccano_file: 从doccano导出的数据标注文件。
save_dir: 训练数据的保存目录,默认存储在data目录下。
negative_ratio: 最大负例比例,该参数只对抽取类型任务有效,适当构造负例可提升模型效果。负例数量和实际的标签数量有关,最大负例数量 = negative_ratio * 正例数量。该参数只对训练集有效,默认为5。为了保证评估指标的准确性,验证集和测试集默认构造全负例。
splits: 划分数据集时训练集、验证集所占的比例。默认为[0.8, 0.1, 0.1]表示按照8:1:1的比例将数据划分为训练集、验证集和测试集。choices=[‘ext’, ‘cls’]
task_type: 选择任务类型,可选有抽取和分类两种类型的任务。
options: 指定分类任务的类别标签,该参数只对分类类型任务有效。默认为[“正向”, “负向”]。
prompt_prefix: 声明分类任务的prompt前缀信息,该参数只对分类类型任务有效。默认为"情感倾向"。
在数据转换阶段,我们会自动构造用于模型训练的prompt信息。例如句子级情感分类中,prompt为情感倾向[正向,负向],可以通过prompt_prefix和options参数进行声明。
is_shuffle: 是否对数据集进行随机打散,默认为True。
seed: 随机种子,默认为1000.
*separator: 实体类别/评价维度与分类标签的分隔符,该参数只对实体/评价维度级分类任务有效。默认为"##"。
输出部分展示:
{"content": "商品的不足暂时还没发现,京东的订单处理速度实在.......周二就打包完成,周五才发货...\t", "result_list": [{"text": "负向", "start": -4, "end": -2}], "prompt": "情感倾向[正向,负向]"}
{"content": "本来想没事的时候翻翻,可惜看不下去,还是和张没法比,他的书能畅销大部分还是受张的影响,对这个男人实在是没好感,不知道怎么买的,后悔\t", "result_list": [{"text": "负向", "start": -7, "end": -5}], "prompt": "情感倾向[负向,正向]"}
{"content": "全键盘带数字键的 显卡足够强大.N卡相对A卡,个人偏向N卡 GHOST XP很容易.除了指纹识别外.所有驱动都能装齐全了,指纹识别,非要在XP下使用的朋友,可以用替代驱动. (华硕官方地址,放心下吧)\t", "result_list": [{"text": "正向", "start": -4, "end": -2}], "prompt": "情感倾向[负向,正向]"}
{"content": "房间地毯太脏,临近火车站十分吵闹,还好是双层玻璃。服务一般,酒店门口的TAXI讲是酒店的长期合作关系,每月要交费给酒店。从酒店到机场讲得是打表147元,到了后非要200元,可能被小宰30-40元。\t", "result_list": [{"text": "负向", "start": -7, "end": -5}], "prompt": "情感倾向[负向,正向]"}
{"content": "<荐书> 推荐所有喜欢<红楼>的红迷们一定要收藏这本书,要知道当年我听说这本书的时候花很长时间去图书馆找和借都没能如愿,所以这次一看到当当有,马上买了,红迷们也要记得备货哦!\t", "result_list": [{"text": "正向", "start": -7, "end": -5}], "prompt": "情感倾向[正向,负向]"}
2.模型训练
!python finetune.py \
--train_path "./data/train.txt" \
--dev_path "./data/dev.txt" \
--save_dir "./checkpoint" \
--learning_rate 1e-5 \
--batch_size 16 \
--max_seq_len 512 \
--num_epochs 100 \
--model "uie-base" \
--seed 1000 \
--logging_steps 10 \
--valid_steps 50 \
--device "gpu"
部分训练效果展示:具体输出已折叠
(由于训练样本比较少,且比较简单所有很容易就达到F1=100%)
[2022-07-17 11:33:46,088] [ INFO] - global step 10, epoch: 10, loss: 0.00021, speed: 1.50 step/s
[2022-07-17 11:33:52,276] [ INFO] - global step 20, epoch: 20, loss: 0.00011, speed: 1.62 step/s
[2022-07-17 11:33:58,431] [ INFO] - global step 30, epoch: 30, loss: 0.00007, speed: 1.62 step/s
[2022-07-17 11:34:04,630] [ INFO] - global step 40, epoch: 40, loss: 0.00006, speed: 1.61 step/s
[2022-07-17 11:34:10,816] [ INFO] - global step 50, epoch: 50, loss: 0.00005, speed: 1.62 step/s
[2022-07-17 11:34:10,863] [ INFO] - Evaluation precision: 1.00000, recall: 1.00000, F1: 1.00000
[2022-07-17 11:34:10,863] [ INFO] - best F1 performence has been updated: 0.00000 --> 1.00000
[2022-07-17 11:34:11,996] [ INFO] - tokenizer config file saved in ./checkpoint/model_best/tokenizer_config.json
[2022-07-17 11:34:11,997] [ INFO] - Special tokens file saved in ./checkpoint/model_best/special_tokens_map.json
[2022-07-17 11:34:18,202] [ INFO] - global step 60, epoch: 60, loss: 0.00004, speed: 1.61 step/s
[2022-07-17 11:34:24,355] [ INFO] - global step 70, epoch: 70, loss: 0.00003, speed: 1.63 step/s
[2022-07-17 11:34:30,515] [ INFO] - global step 80, epoch: 80, loss: 0.00003, speed: 1.62 step/s
[2022-07-17 11:34:36,700] [ INFO] - global step 90, epoch: 90, loss: 0.00003, speed: 1.62 step/s
[2022-07-17 11:34:42,851] [ INFO] - global step 100, epoch: 100, loss: 0.00002, speed: 1.63 step/s
[2022-07-17 11:34:42,897] [ INFO] - Evaluation precision: 1.00000, recall: 1.00000, F1: 1.00000
推荐使用GPU环境,否则可能会内存溢出。CPU环境下,可以修改model为uie-tiny,适当调下batch_size。
增加准确率的话:–num_epochs 设置大点多训练训练
可配置参数说明:
train_path: 训练集文件路径。
dev_path: 验证集文件路径。
save_dir: 模型存储路径,默认为./checkpoint。
learning_rate: 学习率,默认为1e-5。
batch_size: 批处理大小,请结合显存情况进行调整,若出现显存不足,请适当调低这一参数,默认为16。
max_seq_len: 文本最大切分长度,输入超过最大长度时会对输入文本进行自动切分,默认为512。
num_epochs: 训练轮数,默认为100。
model 选择模型,程序会基于选择的模型进行模型微调,可选有uie-base和uie-tiny,默认为uie-base。
seed: 随机种子,默认为1000.
logging_steps: 日志打印的间隔steps数,默认10。
valid_steps: evaluate的间隔steps数,默认100。
device: 选用什么设备进行训练,可选cpu或gpu。
3.模型评估
!python evaluate.py \
--model_path ./checkpoint/model_best \
--test_path ./data/test.txt \
--batch_size 16 \
--max_seq_len 512
[2022-07-18 11:37:05,934] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load './checkpoint/model_best'.
W0718 11:37:05.965226 2210 gpu_context.cc:278] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0718 11:37:05.969079 2210 gpu_context.cc:306] device: 0, cuDNN Version: 7.6.
[2022-07-18 11:37:11,584] [ INFO] - -----------------------------
[2022-07-18 11:37:11,584] [ INFO] - Class Name: all_classes
[2022-07-18 11:37:11,584] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000
model_path: 进行评估的模型文件夹路径,路径下需包含模型权重文件model_state.pdparams及配置文件model_config.json。
test_path: 进行评估的测试集文件。
batch_size: 批处理大小,请结合机器情况进行调整,默认为16。
max_seq_len: 文本最大切分长度,输入超过最大长度时会对输入文本进行自动切分,默认为512。
model: 选择所使用的模型,可选有uie-base, uie-medium, uie-mini, uie-micro和uie-nano,默认为uie-base。
debug: 是否开启debug模式对每个正例类别分别进行评估,该模式仅用于模型调试,默认关闭。
4.结果预测
from pprint import pprint
import json
from paddlenlp import Taskflow
def openreadtxt(file_name):
data = []
file = open(file_name,'r',encoding='UTF-8') #打开文件
file_data = file.readlines() #读取所有行
for row in file_data:
data.append(row) #将每行数据插入data中
return data
data_input=openreadtxt('./input/nlp.txt')
schema = '情感倾向[正向,负向]'
few_ie = Taskflow('information_extraction', schema=schema, batch_size=32,task_path='./checkpoint/model_best')
# few_ie = Taskflow('sentiment_analysis', schema=schema, batch_size=32,task_path='./checkpoint/model_best')
results=few_ie(data_input)
with open("./output/result.txt", "w+",encoding='UTF-8') as f: #a : 写入文件,若文件不存在则会先创建再写入,但不会覆盖原文件,而是追加在文件末尾
for result in results:
line = json.dumps(result, ensure_ascii=False) #对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False
f.write(line + "\n")
print("数据结果已导出")
print(results)
输入文件展示:
酒店环境和服务都还不错,地理位置也不错,尤其是酒店北面的川北凉粉确实好吃。
设施老化,紧靠马路噪音太大。晚上楼上卫生间的水流声和空调噪音非常大,无法入眠。
很不错的一个酒店,床很大,很舒服.酒店员工的服务态度很亲切。
非常糟糕!我们通过其商务中心包了一辆车游西湖,该车拉我们去不正规景点买茶叶。
总的来说,酒店还不错。比较安静,地理位置比较好,服务也不错,包括入住和结账。
输出展示:
[{'text': '酒店环境和服务都还不错,地理位置也不错,尤其是酒店北面的川北凉粉确实好吃。\n', 'label': 'positive', 'score': 0.8420582413673401},
{'text': '设施老化,紧靠马路噪音太大。晚上楼上卫生间的水流声和空调噪音非常大,无法入眠。\n', 'label': 'negative', 'score': 0.9905866980552673},
{'text': '很不错的一个酒店,床很大,很舒服.酒店员工的服务态度很亲切。\n', 'label': 'positive', 'score': 0.9800688028335571},
{'text': '非常糟糕!我们通过其商务中心包了一辆车游西湖,该车拉我们去不正规景点买茶叶。\n', 'label': 'negative', 'score': 0.9315289258956909},
{'text': '总的来说,酒店还不错。比较安静,地理位置比较好,服务也不错,包括入住和结账。', 'label': 'positive', 'score': 0.90092933177948}]
当然paddlenlp也专门提供了情感分析的两个模型,默认使用的是BiLSTM。
以及SKEP。
集成百度自研的情感知识增强预训练模型SKEP,利用情感知识构建预训练目标,在海量中文数据上进行预训练,为各类情感分析任务提供统一且强大的情感语义表示能力。情感预训练模型SKEP(Sentiment Knowledge Enhanced Pre-training for Sentiment Analysis)。SKEP利用情感知识增强预训练模型, 在14项中英情感分析典型任务上全面超越SOTA,此工作已经被ACL 2020录用。SKEP是百度研究团队提出的基于情感知识增强的情感预训练算法,此算法采用无监督方法自动挖掘情感知识,然后利用情感知识构建预训练目标,从而让机器学会理解情感语义。SKEP为各类情感分析任务提供统一且强大的情感语义表示。
SKEP: Sentiment Knowledge Enhanced Pre-training for Sentiment Analysis
from pprint import pprint
import json
from paddlenlp import Taskflow
def openreadtxt(file_name):
data = []
file = open(file_name,'r',encoding='UTF-8') #打开文件
file_data = file.readlines() #读取所有行
for row in file_data:
data.append(row) #将每行数据插入data中
return data
data_input=openreadtxt('./input/nlp.txt')
schema = '情感倾向[正向,负向]'
few_ie = Taskflow("sentiment_analysis", schema=schema,model="skep_ernie_1.0_large_ch", batch_size=16)
results=few_ie(data_input)
with open("./output/result.txt", "w+",encoding='UTF-8') as f: #a : 写入文件,若文件不存在则会先创建再写入,但不会覆盖原文件,而是追加在文件末尾
for result in results:
line = json.dumps(result, ensure_ascii=False) #对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False
f.write(line + "\n")
print("数据结果已导出")
print(results)
[{'text': '酒店环境和服务都还不错,地理位置也不错,尤其是酒店北面的川北凉粉确实好吃。\n', 'label': 'positive', 'score': 0.9441452622413635}, {'text': '设施老化,紧靠马路噪音太大。晚上楼上卫生间的水流声和空调噪音非常大,无法入眠。\n', 'label': 'negative', 'score': 0.991821825504303}, {'text': '很不错的一个酒店,床很大,很舒服.酒店员工的服务态度很亲切。\n', 'label': 'positive', 'score': 0.989535927772522}, {'text': '非常糟糕!我们通过其商务中心包了一辆车游西湖,该车拉我们去不正规景点买茶叶。\n', 'label': 'negative', 'score': 0.9811170697212219}, {'text': '总的来说,酒店还不错。比较安静,地理位置比较好,服务也不错,包括入住和结账。', 'label': 'positive', 'score': 0.8622702360153198}]
5.活学活用(新闻文本分类demo)
获取相关数据集,然后经过处理,这里选取了农业、金融、房产的部分数据仅作为测试方案可行性
导出官网提供的新闻数据集,然后自己去标注平台进行标注!
!python doccano.py \
--doccano_file ./data/input.jsonl \
--task_type 'cls' \
--save_dir ./data \
--splits 0.85 0.15 0 \
--negative_ratio 5 \
--prompt_prefix "新闻分类" \
--options "农业" "房产" "金融"
!python finetune.py \
--train_path "./data/train.txt" \
--dev_path "./data/dev.txt" \
--save_dir "./checkpoint2" \
--learning_rate 1e-5 \
--batch_size 16 \
--max_seq_len 512 \
--num_epochs 200 \
--model "uie-base" \
--seed 1000 \
--logging_steps 10 \
--valid_steps 50 \
--device "gpu"
from pprint import pprint
import json
from paddlenlp import Taskflow
data = [
["美元再次举起金融屠刀,这10个国家的经济或即将岌岌可危”,西城再曝10家违规中介"],
["维基链时代来临,瞬间将袭卷整个中国,暴涨800%!抢到即赚到!"],
["我省发布今年全省城乡居民最低生活保障标准低限"],
]
schema = '新闻分类[农业,房产,金融]'
few_ie = Taskflow('information_extraction', schema=schema,task_path='./checkpoint2/model_best')
results=few_ie(["美元再次举起金融屠刀,这10个国家的经济或即将岌岌可危”,西城再曝10家违规中介","维基链时代来临,瞬间将袭卷整个中国,暴涨800%!抢到即赚到!","我省发布今年全省城乡居民最低生活保障标准低限"])
# print(results)
for idx, text in enumerate(data):
print('Data: {} \t Lable: {}'.format(text[0], results[idx]))
Data: 美元再次举起金融屠刀,这10个国家的经济或即将岌岌可危”,西城再曝10家违规中介 Lable: {‘新闻分类[农业,房产,金融]’: [{‘text’: ‘金融’, ‘probability’: 0.8674286780486753}]}
Data: 维基链时代来临,瞬间将袭卷整个中国,暴涨800%!抢到即赚到! Lable: {‘新闻分类[农业,房产,金融]’: [{‘text’: ‘农业’, ‘probability’: 0.4909489670645364}]}
Data: 我省发布今年全省城乡居民最低生活保障标准低限 Lable: {‘新闻分类[农业,房产,金融]’: [{‘text’: ‘农业’, ‘probability’: 0.980139386504348}]}
可以看出结果还是不错的,效果性能有的,这只是一次尝试,我还没验证具体性能
不过还是推荐使用专门的分类模型,ernie-3.0-效果会更好
**后续去验证一下hub、ERNIE、prompt三种方式性能,当然预计基于一个模型可能效果会差不多,到时推荐出一个最便捷的方案来! **
7.总结
UIE(Universal Information Extraction):Yaojie Lu等人在ACL-2022中提出了通用信息抽取统一框架UIE。该框架实现了实体抽取、关系抽取、事件抽取、情感分析等任务的统一建模,并使得不同任务间具备良好的迁移和泛化能力。PaddleNLP借鉴该论文的方法,基于ERNIE 3.0知识增强预训练模型,训练并开源了首个中文通用信息抽取模型UIE。该模型可以支持不限定行业领域和抽取目标的关键信息抽取,实现零样本快速冷启动,并具备优秀的小样本微调能力,快速适配特定的抽取目标。
UIE的优势
使用简单: 用户可以使用自然语言自定义抽取目标,无需训练即可统一抽取输入文本中的对应信息。实现开箱即用,并满足各类信息抽取需求。
降本增效: 以往的信息抽取技术需要大量标注数据才能保证信息抽取的效果,为了提高开发过程中的开发效率,减少不必要的重复工作时间,开放域信息抽取可以实现零样本(zero-shot)或者少样本(few-shot)抽取,大幅度降低标注数据依赖,在降低成本的同时,还提升了效果。
效果领先: 开放域信息抽取在多种场景,多种任务上,均有不俗的表现。
本人本次主要通过情感分类、新闻分类这个案例分享给大家,主要对开源的paddlenlp的案例进行了细化,官方文档没有涉及具体分类如何去微调,这边给出demo给大家参考,目前看来小样本多分类效果还行,后续我将扩大样本进行完整的测试。
当然大家可以在项目基础上替换数据集,做成一个分类模型试试效果!先从二分类—多分类一一尝试!
本人博客:https://blog.csdn.net/sinat_39620217?type=blog
相关文章:
Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】
项目连接:百度AIstudio直接fork我的项目就可以复现
Paddlenlp之UIE分类模型【以情感倾向分析新闻分类为例】含智能标注方案)
Paddlenlp之UIE分类模型【以情感倾向分析新闻分类为例】含智能标注方案)的更多相关文章
- Python调用百度接口(情感倾向分析)和讯飞接口(语音识别、关键词提取)处理音频文件
本示例的过程是: 1. 音频转文本 2. 利用文本获取情感倾向分析结果 3. 利用文本获取关键词提取 首先是讯飞的语音识别模块.在这里可以找到非实时语音转写的相关文档以及 Python 示例.我略作了 ...
- 基于Labelstudio的UIE半监督智能标注方案(本地版)
基于Labelstudio的UIE半监督智能标注方案(本地版) 更多技术细节参考上一篇项目,本篇主要侧重本地端链路走通教学,提速提效: 基于Labelstudio的UIE半监督深度学习的智能标注方案( ...
- 基于Label studio实现UIE信息抽取智能标注方案,提升标注效率!
基于Label studio实现UIE信息抽取智能标注方案,提升标注效率! 项目链接见文末 人工标注的缺点主要有以下几点: 产能低:人工标注需要大量的人力物力投入,且标注速度慢,产能低,无法满足大规模 ...
- 第四章:用Python对用户的评论数据进行情感倾向分析
文章目录 项目背景 获取数据 情感倾向 senta_bilstm 模型 情感划分 数据描述 数据分析 总体评论倾向 评论分布 各分布的情感倾向 评论分词 去除停用词 绘制词云图 结论 源码地址 本文可 ...
- 百度AI开放平台 情感倾向分析实例以及gbk编码解决
f=open('test.txt','a+',encoding='utf-8') for index,row in cxzg.iterrows(): text=str(row['text']) tex ...
- 【AUC】二分类模型的评价指标ROC Curve
AUC是指:从一堆样本中随机抽一个,抽到正样本的概率比抽到负样本的概率大的可能性! AUC是一个模型评价指标,只能用于二分类模型的评价,对于二分类模型,还有很多其他评价指标,比如logloss,acc ...
- 【分类模型评判指标 一】混淆矩阵(Confusion Matrix)
转自:https://blog.csdn.net/Orange_Spotty_Cat/article/details/80520839 略有改动,仅供个人学习使用 简介 混淆矩阵是ROC曲线绘制的基础 ...
- 机器学习算法(九): 基于线性判别模型的LDA手写数字分类识别
1.机器学习算法(九): 基于线性判别模型的LDA手写数字分类识别 1.1 LDA算法简介和应用 线性判别模型(LDA)在模式识别领域(比如人脸识别等图形图像识别领域)中有非常广泛的应用.LDA是一种 ...
- 机器学习04-(决策树、集合算法:AdaBoost模型、BBDT、随机森林、分类模型:逻辑回归)
机器学习04 机器学习-04 集合算法 AdaBoost模型(正向激励) 特征重要性 GBDT 自助聚合 随机森林 分类模型 什么问题属于分类问题? 逻辑回归 代码总结 波士顿房屋价格数据分析与房价预 ...
- PaddlePaddle︱开发文档中学习情感分类(CNN、LSTM、双向LSTM)、语义角色标注
PaddlePaddle出教程啦,教程一部分写的很详细,值得学习. 一期涉及新手入门.识别数字.图像分类.词向量.情感分析.语义角色标注.机器翻译.个性化推荐. 二期会有更多的图像内容. 随便,帮国产 ...
随机推荐
- 注册中心 —— SpringCloud Netflix Eureka
Eureka 简介 Eureka 是一个基于 REST 的服务发现组件,SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务 ...
- 如何优化k8s中HPA的弹性速率
本文分享自华为云社区<K8s 核心资源指标HPA性能优化之路>,作者:可以交个朋友. 一 背景 以弹性指标为cpu.memory为例.在Kubernetes 1.7版本中引入了聚合层,允许 ...
- 题解 CF1388A 【Captain Flint and Crew Recruitment】(思维、贪心)
AC代码: #include<bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; if (n ...
- vivo智能活动中台-悟空系统建设之路
作者:来自 vivo 互联网悟空系统研发团队 本文根据冯伟.姜野老师在"2023 vivo开发者大会"现场演讲内容整理而成.[vivo互联网技术]公众号回复[2023 VDC]获取 ...
- 拥抱开放,Serverless 时代的下一征程
Serverless 作为云计算的最佳实践和未来演进趋势,其全托管免运维的使用体验和按量付费的成本优势使得它在云原生时代备受推崇.Serverless 的使用场景也由事件驱动,数据处理等部分特定场景转 ...
- 如何安全的大数据量表在线进行DDL操作
本文为博主原创,转载请注明出处 随着业务的需要,工作中需要对生产数据库的一些表做一些DDL操作,由于生产数据库表的数据量都是几千万, 而且生产数据库的表还在不断的进行新增和查询操作.应用中需要对生产数 ...
- 04 Tcl字符串
Tcl字符串 4.1 Tcl将说有的变量值视作字符串,并将他们作为字符串进行保存. 命令 描述 append 将值追加到字符串尾 binary 二进制化字符串 format 字符串格式化 regexp ...
- 【VSCode】秒下vscode
有时从vscode官网下载速度奇慢甚至失败,介绍一种方法可以秒下 进入官网选择要下载的版本 像我的电脑,下载网址根本打不开 修改下载网址,替换下载地址中红框字符串:vscode.cdn.azure.c ...
- 【C++】类概念及使用
类定义中不允许对数据成员初始化 类外只能访问公有部分 类成员必须指定访问属性 类的成员函数是实现对封装的数据成员进行操作的唯一途径 类定义中不允许定义本类对象,因无法预知大小 类与结构形式相同,唯一区 ...
- .Net 使用 MongoDB
1.安装nuget包 MongoDB.Driver 2.简单代码 using MongoDB.Bson; using MongoDB.Driver; using System.Buffers; usi ...