北京企业建网站定制价格南昌网站建设公司特色
北京企业建网站定制价格,南昌网站建设公司特色,简历模板表格,关键词排名优化价格情感分析作为自然语言处理#xff08;NLP#xff09;的核心任务之一#xff0c;广泛应用于电商评论分析、影视口碑研判、舆情监控等场景。本文将基于 Hugging Face 生态的 Transformers、Datasets 库#xff0c;结合哈工大中文 RoBERTa 预训练模型#xff0c;从零实现中文…情感分析作为自然语言处理NLP的核心任务之一广泛应用于电商评论分析、影视口碑研判、舆情监控等场景。本文将基于 Hugging Face 生态的 Transformers、Datasets 库结合哈工大中文 RoBERTa 预训练模型从零实现中文文本情感分析模型的训练、评估全流程。一、技术栈与环境准备1. 核心依赖库本次实战依赖以下核心库torch深度学习框架提供模型训练的底层支持transformersHugging Face 开源的 NLP 工具库封装了预训练模型、分词器、训练器等datasets高效加载、处理数据集的工具scikit-learn用于计算准确率、F1 分数等评估指标numpy数值计算基础库。2. 环境安装通过 pip 一键安装所需依赖pip install torch transformers datasets scikit-learn numpy二、核心思路与数据集准备1. 任务定义本次实现二分类情感分析标签 0负面情感标签 1正面情感。2. 数据集格式采用 CSV 格式数据集sentiment_data.csv包含两列核心字段text待分析的中文文本label情感标签0/1。数据集同时用于训练和验证实际场景建议拆分独立的训练 / 验证 / 测试集。三、模型选择选择哈工大开源的chinese-roberta-wwm-ext预训练模型该模型基于 RoBERTa 架构针对中文语料做了充分预训练在中文文本分类任务中表现优异。四、模型训练train_model.py1. 加载预训练模型与分词器首先加载预训练模型和对应的分词器Tokenizer分词器的作用是将自然语言文本转换为模型可识别的张量input_ids、attention_mask 等from transformers import AutoModelForSequenceClassification, AutoTokenizer # 预训练模型路径 model_dir rD:\pyprojecgt\flaskProject\langchainstudy\modelscope\chinese-roberta-wwm-ext # 加载分词器 tokenizer AutoTokenizer.from_pretrained(model_dir) # 加载分类模型指定分类类别数为2情感二分类 model AutoModelForSequenceClassification.from_pretrained( model_dir, num_labels2, device_mapauto # 自动分配模型到GPU/CPU )2. 加载并预处理数据集使用datasets库加载 CSV 数据集并对文本进行分词、截断、填充等预处理from datasets import load_dataset # 加载数据集拆分训练集和验证集 dataset load_dataset(csv, data_files{train: ./sentiment_data.csv, validation: sentiment_data.csv}) # 数据预处理函数将文本转为模型输入格式 def preprocess(example): return tokenizer( example[text], truncationTrue, # 截断超出最大长度的文本 paddingmax_length, # 填充到固定长度 max_length128 # 文本最大长度根据任务调整 ) # 批量处理数据集 encoded_dataset dataset.map(preprocess, batchedTrue) # 重命名标签列适配Trainer要求 encoded_dataset encoded_dataset.rename_column(label, labels) # 设置数据集格式为PyTorch张量 encoded_dataset.set_format(torch, columns[input_ids, attention_mask, labels])3. 配置训练参数与训练器TrainingArguments封装了训练过程的核心参数Trainer是 Hugging Face 提供的高级训练封装器简化训练流程from transformers import Trainer, TrainingArguments import numpy as np from sklearn.metrics import accuracy_score # 定义评估指标准确率 def compute_metrics(eval_pred): logits, labels eval_pred # logits为模型输出labels为真实标签 predictions np.argmax(logits, axis-1) # 取概率最大的类别为预测结果 return {accuracy: accuracy_score(labels, predictions)} # 训练参数配置 training_args TrainingArguments( output_diroutput/zh_model, # 模型保存路径 per_device_train_batch_size4, # 单设备批次大小 num_train_epochs1, # 训练轮次 logging_steps5, # 日志打印间隔 save_steps50, # 模型保存间隔 save_total_limit3, # 保留最新的3个模型 checkpoint ) # 初始化训练器 trainer Trainer( modelmodel, argstraining_args, train_datasetencoded_dataset[train], eval_datasetencoded_dataset[validation], compute_metricscompute_metrics, ) # 开始训练 trainer.train() # 保存训练后的模型和分词器 trainer.save_model(./output/zh_model) tokenizer.save_pretrained(./output/zh_model)4. 训练后快速预测训练完成后可通过pipeline快速构建情感分析管道验证模型效果from transformers import pipeline classifier pipeline( text-classification, model./output/zh_model, tokenizer./output/zh_model, device_mapcpu ) # 测试案例 test_texts [ 这家餐厅的菜太好吃了服务也特别棒, 今天的电影特别难看浪费钱又浪费时间 ] for text in test_texts: result classifier(text) print(f文本{text}\n情感分类{result}\n)五、模型评估evalmodel.py训练完成后需从准确率、F1 分数等维度量化模型性能同时可视化预测结果。1. 加载训练好的模型与测试数据import torch from sklearn.metrics import accuracy_score, f1_score, classification_report from transformers import AutoTokenizer, AutoModelForSequenceClassification # 设备选择优先GPU DEVICE torch.device(cuda if torch.cuda.is_available() else cpu) # 加载训练后的模型和分词器 model_dir rD:\pyprojecgt\flaskProject\langchainstudy\modelscope\04\output\zh_model tokenizer AutoTokenizer.from_pretrained(model_dir) model AutoModelForSequenceClassification.from_pretrained(model_dir, device_mapauto) model.eval() # 切换为评估模式禁用Dropout等训练层 # 测试数据集 test_data [ {text: 这个电影太棒了吧我还想再看一次, label: 1}, {text: 这部电影很无聊浪费时间, label: 0}, {text: 剧本不错演员演得也很好, label: 1}, {text: 剧情太拖沓根本看不下去, label: 0}, ]2. 模型推理与指标计算# 提取文本和真实标签 texts [item[text] for item in test_data] true_labels [item[label] for item in test_data] # 文本编码适配模型输入 inputs tokenizer(texts, paddingTrue, truncationTrue, return_tensorspt, max_length128) # 无梯度推理提升速度避免显存占用 predictions [] with torch.no_grad(): outputs model(**inputs) logits outputs.logits # 模型原始输出 predicted_classes torch.argmax(logits, dim1).tolist() # 取最大概率对应的类别 predictions predicted_classes # 计算评估指标 acc accuracy_score(true_labels, predictions) # 准确率 f1 f1_score(true_labels, predictions, averagemacro) # 宏平均F1分数 print(f准确率: {acc:.4f}) print(fF1分数: {f1:.4f}) print(分类报告) print(classification_report(true_labels, predictions, target_names[负面, 正面]))3. 预测结果可视化label_map {0: 负面, 1: 正面} # 逐行打印预测结果 for text, true_label, predicted_class in zip(texts, true_labels, predictions): print(f测试文本{text}) print(f真实标签{label_map[true_label]}) print(f预测标签{label_map[predicted_class]}) print( * 50)六、结果分析与优化方向1. 测试结果基于示例测试数据模型可实现 100% 的准确率和 F1 分数因测试集规模较小实际场景中需用更大规模、更多样化的测试集验证。2. 优化方向数据层面扩充数据集规模增加噪声数据如含错别字、口语化文本拆分独立的训练 / 验证 / 测试集训练层面调整num_train_epochs增加训练轮次、per_device_train_batch_size批次大小加入学习率调度器模型层面尝试chinese-bert-wwm、ernie等其他中文预训练模型或基于 LoRA 进行轻量化微调评估层面增加混淆矩阵、精准率 / 召回率等指标分析模型误判案例。七、总结本文基于 Hugging Face Transformers 完成了中文情感分析模型的训练与评估核心流程包括 “数据预处理→预训练模型加载→模型微调→性能评估”。Hugging Face 生态的封装性极大降低了 NLP 模型开发门槛开发者可基于此框架快速适配不同场景的文本分类任务。同时实际应用中需结合业务场景优化数据和训练策略以提升模型的泛化能力。整个代码如下train_model# 核心库导入 # 从transformers库导入序列分类模型、分词器、训练器、训练参数配置、推理管道 from transformers import ( AutoModelForSequenceClassification, # 适用于序列分类任务的预训练模型 AutoTokenizer, # 与预训练模型配套的分词器文本转模型输入 Trainer, # 高阶训练封装器简化训练流程无需手动写训练循环 TrainingArguments, # 训练参数配置类批量大小、轮次、保存路径等 pipeline # 快速构建推理管道训练后直接用于预测 ) from datasets import load_dataset # 高效加载/处理数据集的工具支持CSV/JSON等格式 import numpy as np # 数值计算库处理模型输出的logits from sklearn.metrics import accuracy_score # 计算准确率模型评估核心指标 # 1. 模型与路径配置 # 预训练模型本地路径哈工大中文RoBERTa-wwm-ext适配中文文本分类 # 注需确保该路径下有模型的config.json、pytorch_model.bin等文件 model_dir rD:\pyprojecgt\flaskProject\langchainstudy\modelscope\chinese-roberta-wwm-ext # 加载分词器将自然语言文本转换为模型可识别的张量input_ids/attention_mask等 tokenizer AutoTokenizer.from_pretrained(model_dir) # 加载序列分类模型基于预训练模型适配二分类任务 model AutoModelForSequenceClassification.from_pretrained( model_dir, num_labels2, # 情感分析二分类0负面1正面 device_mapauto # 自动分配模型到可用设备优先GPU无则CPU ) # 2. 加载数据集 # 加载CSV格式数据集拆分训练集train和验证集validation # 注示例中训练/验证集复用同一文件实际场景需拆分独立的数据集避免过拟合 dataset load_dataset( csv, # 指定数据集格式为CSV data_files{ train: ./sentiment_data.csv, # 训练集路径 validation: ./sentiment_data.csv # 验证集路径 } ) # 3. 数据预处理函数 def preprocess(example): 对单条数据进行预处理文本分词、截断、填充 Args: example: dataset中的单条数据字典格式包含text/label字段 Returns: 编码后的字典input_ids/attention_mask等 return tokenizer( example[text], # 待处理的中文文本 truncationTrue, # 截断超过max_length的文本避免长度超限 paddingmax_length, # 填充到max_length指定的固定长度 max_length128 # 文本最大长度根据任务调整过短丢信息过长耗资源 ) # 批量处理数据集batchedTrue提升处理效率 encoded_dataset dataset.map(preprocess, batchedTrue) # 打印数据集拆分信息确认train/validation是否加载成功 print(数据集拆分, list(dataset.keys())) # 4. 数据集格式适配 # 重命名标签列将label改为labels适配Trainer的默认参数名要求 encoded_dataset encoded_dataset.rename_column(label, labels) # 设置数据集格式为PyTorch张量Trainer需torch格式输入 # 指定核心列input_ids文本编码、attention_mask注意力掩码、labels标签 encoded_dataset.set_format( torch, columns[input_ids, attention_mask, labels] ) # 5. 训练参数配置 training_args TrainingArguments( output_diroutput/zh_model, # 模型/日志/检查点输出路径 per_device_train_batch_size4, # 单设备训练批次大小GPU显存不足可调小 num_train_epochs1, # 训练轮次示例设为1实际可设3-5轮 logging_steps5, # 每5步打印一次训练日志loss/学习率等 save_steps50, # 每50步保存一次模型检查点 save_total_limit3, # 仅保留最近3个检查点避免占满磁盘 # 可选补充参数新手可先忽略 # learning_rate2e-5, # 学习率预训练模型微调常用2e-5/5e-5 # evaluation_strategysteps, # 按步数评估模型 # eval_steps50, # 每50步评估一次准确率 ) # 6. 评估指标定义 def compute_metrics(eval_pred): 计算模型评估指标准确率 Args: eval_pred: 包含模型输出logits和真实标签的元组 Returns: 字典格式的评估结果key为指标名value为指标值 logits, labels eval_pred # logits模型原始输出labels真实标签 predictions np.argmax(logits, axis-1) # 取logits最大值对应的类别为预测结果 return {accuracy: accuracy_score(labels, predictions)} # 计算准确率 # 7. 初始化训练器并开始训练 trainer Trainer( modelmodel, # 待训练的模型 argstraining_args, # 训练参数配置 train_datasetencoded_dataset[train], # 训练数据集 eval_datasetencoded_dataset[validation], # 验证数据集 compute_metricscompute_metrics, # 训练过程中计算评估指标 ) # 开始训练自动打印训练进度、loss、验证准确率等 trainer.train() # 8. 保存训练好的模型 # 保存模型权重、配置文件等用于后续推理/部署 trainer.save_model(./output/zh_model) # 保存分词器推理时需用相同分词器处理文本必须同步保存 tokenizer.save_pretrained(./output/zh_model) # 9. 训练后快速推理 # 构建文本分类推理管道直接调用训练好的模型 classifier pipeline( text-classification, # 指定任务类型为文本分类 model./output/zh_model, # 加载训练好的模型 tokenizer./output/zh_model, # 加载配套分词器 device_mapcpu # 推理时使用CPU若有GPU可改为cuda提速 ) # 测试用例正面/负面情感文本 test_texts [ 这家餐厅的菜太好吃了服务也特别棒, # 正面情感 今天的电影特别难看浪费钱又浪费时间 # 负面情感 ] # 遍历测试文本打印预测结果 for text in test_texts: result classifier(text) print(f文本{text}\n情感分类{result}\n)eval_model# 导入PyTorch框架用于模型推理和张量计算 import torch # 从sklearn.metrics导入评估指标准确率、F1分数、分类报告 from sklearn.metrics import accuracy_score, f1_score, classification_report # 从transformers导入分词器和分类模型AutoTokenizer/AutoModelForSequenceClassification适配多类预训练模型 from transformers import AutoTokenizer, AutoModelForSequenceClassification # 1. 设备配置 # 自动检测可用设备优先使用GPUCUDA若无则使用CPU DEVICE torch.device(cuda if torch.cuda.is_available() else cpu) # 打印当前使用的设备便于调试确认 print(f当前使用计算设备{DEVICE}) # 2. 加载训练好的模型和分词器 # 训练后模型的保存路径需根据实际训练输出路径调整 model_dir rD:\pyprojecgt\flaskProject\langchainstudy\modelscope\04\output\zh_model # 模型名称/路径与model_dir一致也可直接复用model_dir model_name rD:\pyprojecgt\flaskProject\langchainstudy\modelscope\04\output\zh_model # 加载与训练时匹配的分词器用于文本转模型可识别的张量 tokenizer AutoTokenizer.from_pretrained(model_dir) # 加载训练好的文本分类模型 model AutoModelForSequenceClassification.from_pretrained( model_name, device_mapauto # 自动将模型分配到可用设备GPU/CPU ) # 将模型切换为评估模式禁用Dropout、BatchNorm等训练特有层避免影响推理结果 model.eval() # 3. 准备测试数据集 # 自定义测试数据集包含待分析文本和对应的真实情感标签0负面1正面 test_data [ {text: 这个电影太棒了吧我还想再看一次, label: 1}, # 正面情感示例 {text: 这部电影很无聊浪费时间, label: 0}, # 负面情感示例 {text: 剧本不错演员演得也很好, label: 1}, # 正面情感示例 {text: 剧情太拖沓根本看不下去, label: 0}, # 负面情感示例 ] # 定义标签映射字典将数字标签转换为易读的文本描述 label_map {0: 负面, 1: 正面} # 从测试数据中提取文本列表和真实标签列表 texts [item[text] for item in test_data] # 待预测的文本集合 true_labels [item[label] for item in test_data]# 文本对应的真实情感标签 # 4. 测试文本预处理 # 对测试文本进行分词、编码转换为模型可接受的张量格式 # paddingTrue自动填充到批次内最长文本长度 # truncationTrue截断超过max_length的文本 # return_tensorspt返回PyTorch张量 # max_length128文本最大长度需与训练时保持一致 inputs tokenizer(texts, paddingTrue, truncationTrue, return_tensorspt, max_length128) # 5. 模型推理无梯度计算 # 初始化空列表存储预测结果 predictions [] # torch.no_grad()禁用梯度计算减少显存占用、提升推理速度评估阶段无需反向传播 with torch.no_grad(): # 将编码后的输入传入模型获取输出 outputs model(**inputs) # 提取模型输出的原始logits未经过softmax的原始得分 logits outputs.logits # 对logits取argmax最大得分对应的索引得到预测类别并转换为列表 predicted_classes torch.argmax(logits, dim1).tolist() # 将预测结果赋值到列表中 predictions predicted_classes # 6. 计算模型评估指标 # 计算准确率预测正确的样本数 / 总样本数 acc accuracy_score(true_labels, predictions) print(f模型准确率: {acc:.4f}) # 保留4位小数打印 # 计算宏平均F1分数兼顾正负样本的召回率和精确率适合二分类场景 f1 f1_score(true_labels, predictions, averagemacro) print(f模型F1分数宏平均: {f1:.4f}) # 打印详细分类报告包含精确率、召回率、F1分数等按类别拆分 print(模型分类详细报告) print(classification_report(true_labels, predictions, target_names[负面, 正面])) # 7. 打印逐样本预测结果 # 遍历测试文本、真实标签、预测标签逐行展示对比结果 for text, true_label, predicted_class in zip(texts, true_labels, predictions): print(f测试文本{text}) print(f真实标签{label_map[true_label]}) print(f预测标签{label_map[predicted_class]}) print( * 50) # 分隔线提升可读性数据准备import random import pandas as pd # 1. 定义生成文本的素材库场景关键词模板 positive_scenes { 酒店: [干净整洁, 服务热情, 环境优雅, 设施齐全, 性价比高, 床很舒适, 早餐丰富, 位置优越, 隔音效果好, 前台高效, 房间宽敞, 采光很好, 卫浴干净, 网速很快, 停车方便, 浴巾柔软, 空调给力, 洗漱用品齐全, 周边便利, 态度亲切], 餐厅: [味道超赞, 食材新鲜, 分量很足, 服务周到, 环境雅致, 性价比高, 摆盘精致, 上菜很快, 口味正宗, 分量实在, 餐具干净, 氛围很好, 老板热情, 配菜丰富, 口感细腻, 不油不腻, 价格公道, 食材新鲜, 摆盘好看, 餐后甜点美味], 电影: [剧情紧凑, 演技在线, 特效炸裂, 立意深刻, 画面精美, 配乐动人, 逻辑清晰, 结尾惊艳, 代入感强, 值得二刷, 台词经典, 演员敬业, 节奏明快, 伏笔回收, 画面细腻, 情感真挚, 三观正, 剪辑流畅, 制作精良, 超出预期], 景点: [风景优美, 空气清新, 配套完善, 性价比高, 工作人员负责, 景色宜人, 拍照出片, 游览顺畅, 体验感拉满, 值得打卡, 门票合理, 路线清晰, 绿化很好, 古迹保存完整, 视野开阔, 人不算多, 指示明确, 停车方便, 文创精美, 四季皆宜], 商品: [质量上乘, 做工精细, 颜值很高, 使用便捷, 性价比高, 材质舒适, 经久耐用, 包装精美, 物流很快, 售后贴心, 尺寸合适, 颜色正, 手感很好, 操作简单, 续航持久, 配件齐全, 无异味, 颜值在线, 贴合需求, 物超所值] } negative_scenes { 酒店: [卫生堪忧, 服务冷漠, 环境嘈杂, 设施陈旧, 性价比低, 床很硬, 早餐难吃, 位置偏僻, 隔音超差, 前台拖沓, 房间狭小, 采光很差, 卫浴脏乱, 网速很慢, 停车困难, 浴巾发黄, 空调故障, 洗漱用品短缺, 周边荒凉, 态度恶劣], 餐厅: [味道难吃, 食材不新鲜, 分量极少, 服务恶劣, 环境脏乱, 性价比低, 摆盘粗糙, 上菜很慢, 口味怪异, 价格虚高, 餐具油腻, 氛围压抑, 老板冷漠, 配菜单一, 口感粗糙, 过于油腻, 价格离谱, 食材变质, 摆盘杂乱, 餐后甜点难以下咽], 电影: [剧情拖沓, 演技拉胯, 特效五毛, 立意浅薄, 画面模糊, 配乐难听, 逻辑混乱, 结尾烂尾, 代入感弱, 浪费票价, 台词尴尬, 演员敷衍, 节奏缓慢, 伏笔烂尾, 画面粗糙, 情感虚假, 三观不正, 剪辑混乱, 制作粗糙, 低于预期], 景点: [风景一般, 空气污浊, 配套缺失, 性价比低, 工作人员敷衍, 景色普通, 拍照难看, 游览拥堵, 体验感极差, 踩雷避雷, 门票昂贵, 路线混乱, 绿化很差, 古迹破损严重, 视野狭窄, 人满为患, 指示不明, 停车困难, 文创劣质, 季节限定坑人], 商品: [质量低劣, 做工粗糙, 颜值很低, 使用麻烦, 性价比低, 材质劣质, 容易损坏, 包装简陋, 物流缓慢, 售后恶劣, 尺寸偏差, 颜色不正, 手感很差, 操作复杂, 续航很短, 配件缺失, 异味浓重, 颜值掉线, 不符合需求, 物非所值] } positive_templates [ {}在同等档次的{}中应该是值得推荐的, {}整体体验非常好强烈推荐给大家, {}这是我近期体验过最好的{}没有之一, {}真心不错以后还会选择这里/这个, {}体验感超棒已经推荐给身边的朋友了, {}超出我的预期非常满意这次的体验, {}细节做得很到位值得大家尝试/选择, {}整体感受很棒会一直回购/复访的, {}不管是品质还是服务都无可挑剔, {}亲测好用/好评推荐给有需要的人 ] negative_templates [ {}在同等档次的{}中完全不值得推荐踩雷了, {}整体体验非常差真心不建议大家选择, {}这是我近期体验过最差的{}没有之一, {}真心糟糕以后再也不会选择这里/这个了, {}体验感极差已经提醒身边的朋友避雷了, {}低于我的预期非常失望这次的体验, {}细节做得一塌糊涂真心不建议尝试/选择, {}整体感受糟糕绝对不会回购/复访, {}不管是品质还是服务都让人无法接受, {}亲测踩雷/差评提醒大家别再上当了 ] # 2. 定义单条文本生成函数 def generate_positive_text(): 生成一条正面情感文本 scene random.choice(list(positive_scenes.keys())) # 随机选择1-3个关键词增加文本多样性 keyword_count random.choice([1, 2, 3]) keywords random.sample(positive_scenes[scene], keyword_count) keyword_str .join(keywords) template random.choice(positive_templates) # 修正模板中的指代让文本更自然 if 这里/这个 in template: template template.replace(这里/这个, 这里 if scene in [酒店, 餐厅, 景点] else 这个) if 回购/复访 in template: template template.replace(回购/复访, 复访 if scene in [酒店, 餐厅, 景点] else 回购) return template.format(keyword_str, scene) def generate_negative_text(): 生成一条负面情感文本 scene random.choice(list(negative_scenes.keys())) keyword_count random.choice([1, 2, 3]) keywords random.sample(negative_scenes[scene], keyword_count) keyword_str .join(keywords) template random.choice(negative_templates) if 这里/这个 in template: template template.replace(这里/这个, 这里 if scene in [酒店, 餐厅, 景点] else 这个) if 回购/复访 in template: template template.replace(回购/复访, 复访 if scene in [酒店, 餐厅, 景点] else 回购) return template.format(keyword_str, scene) # 3. 生成7000条数据正面3500条负面3500条 print(开始生成7000条情感数据...) data_list [] # 生成正面数据 for _ in range(3500): pos_text generate_positive_text() data_list.append({text: pos_text, label: 1}) # 生成负面数据 for _ in range(3500): neg_text generate_negative_text() data_list.append({text: neg_text, label: 0}) # 4. 整理数据并保存为CSV df pd.DataFrame(data_list) # 打乱数据顺序避免正面集中、负面集中提升训练效果 df df.sample(frac1, random_state42).reset_index(dropTrue) # 保存完整CSV文件 csv_filename sentiment_data.csv df.to_csv(csv_filename, indexFalse, encodingutf-8-sig) # utf-8-sig兼容更多编辑器 print(f数据生成完成已保存为 {csv_filename}) print(f数据总量{len(df)} 条) print(f正面数据label1{len(df[df[label]1])} 条) print(f负面数据label0{len(df[df[label]0])} 条)