情感分析作为自然语言处理(NLP)的核心任务之一,广泛应用于电商评论分析、影视口碑研判、舆情监控等场景。本文将基于 Hugging Face 生态的 Transformers、Datasets 库,结合哈工大中文 RoBERTa 预训练模型,从零实现中文文本情感分析模型的训练、评估全流程。
一、技术栈与环境准备
1. 核心依赖库
本次实战依赖以下核心库:
torch:深度学习框架,提供模型训练的底层支持;transformers:Hugging 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.py)
1. 加载预训练模型与分词器
首先加载预训练模型和对应的分词器(Tokenizer),分词器的作用是将自然语言文本转换为模型可识别的张量(input_ids、attention_mask 等):
from transformers import AutoModelForSequenceClassification, AutoTokenizer # 预训练模型路径 model_dir = r"D:\pyprojecgt\flaskProject\langchainstudy\modelscope\chinese-roberta-wwm-ext" # 加载分词器 tokenizer = AutoTokenizer.from_pretrained(model_dir) # 加载分类模型,指定分类类别数为2(情感二分类) model = AutoModelForSequenceClassification.from_pretrained( model_dir, num_labels=2, device_map="auto" # 自动分配模型到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"], truncation=True, # 截断超出最大长度的文本 padding="max_length", # 填充到固定长度 max_length=128 # 文本最大长度(根据任务调整) ) # 批量处理数据集 encoded_dataset = dataset.map(preprocess, batched=True) # 重命名标签列(适配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_dir="output/zh_model", # 模型保存路径 per_device_train_batch_size=4, # 单设备批次大小 num_train_epochs=1, # 训练轮次 logging_steps=5, # 日志打印间隔 save_steps=50, # 模型保存间隔 save_total_limit=3, # 保留最新的3个模型 checkpoint ) # 初始化训练器 trainer = Trainer( model=model, args=training_args, train_dataset=encoded_dataset["train"], eval_dataset=encoded_dataset["validation"], compute_metrics=compute_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_map="cpu" ) # 测试案例 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 = r"D:\pyprojecgt\flaskProject\langchainstudy\modelscope\04\output\zh_model" tokenizer = AutoTokenizer.from_pretrained(model_dir) model = AutoModelForSequenceClassification.from_pretrained(model_dir, device_map="auto") 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, padding=True, truncation=True, return_tensors="pt", max_length=128) # 无梯度推理(提升速度,避免显存占用) predictions = [] with torch.no_grad(): outputs = model(**inputs) logits = outputs.logits # 模型原始输出 predicted_classes = torch.argmax(logits, dim=1).tolist() # 取最大概率对应的类别 predictions = predicted_classes # 计算评估指标 acc = accuracy_score(true_labels, predictions) # 准确率 f1 = f1_score(true_labels, predictions, average="macro") # 宏平均F1分数 print(f"准确率: {acc:.4f}") print(f"F1分数: {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 = r"D:\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_labels=2, # 情感分析二分类:0=负面,1=正面 device_map="auto" # 自动分配模型到可用设备(优先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"], # 待处理的中文文本 truncation=True, # 截断超过max_length的文本(避免长度超限) padding="max_length", # 填充到max_length指定的固定长度 max_length=128 # 文本最大长度(根据任务调整,过短丢信息,过长耗资源) ) # 批量处理数据集(batched=True提升处理效率) encoded_dataset = dataset.map(preprocess, batched=True) # 打印数据集拆分信息(确认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_dir="output/zh_model", # 模型/日志/检查点输出路径 per_device_train_batch_size=4, # 单设备训练批次大小(GPU显存不足可调小) num_train_epochs=1, # 训练轮次(示例设为1,实际可设3-5轮) logging_steps=5, # 每5步打印一次训练日志(loss/学习率等) save_steps=50, # 每50步保存一次模型检查点 save_total_limit=3, # 仅保留最近3个检查点(避免占满磁盘) # 可选补充参数(新手可先忽略): # learning_rate=2e-5, # 学习率(预训练模型微调常用2e-5/5e-5) # evaluation_strategy="steps", # 按步数评估模型 # eval_steps=50, # 每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( model=model, # 待训练的模型 args=training_args, # 训练参数配置 train_dataset=encoded_dataset["train"], # 训练数据集 eval_dataset=encoded_dataset["validation"], # 验证数据集 compute_metrics=compute_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_map="cpu" # 推理时使用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. 设备配置 ===================== # 自动检测可用设备:优先使用GPU(CUDA),若无则使用CPU DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 打印当前使用的设备,便于调试确认 print(f"当前使用计算设备:{DEVICE}") # ===================== 2. 加载训练好的模型和分词器 ===================== # 训练后模型的保存路径(需根据实际训练输出路径调整) model_dir = r"D:\pyprojecgt\flaskProject\langchainstudy\modelscope\04\output\zh_model" # 模型名称/路径(与model_dir一致,也可直接复用model_dir) model_name = r'D:\pyprojecgt\flaskProject\langchainstudy\modelscope\04\output\zh_model' # 加载与训练时匹配的分词器(用于文本转模型可识别的张量) tokenizer = AutoTokenizer.from_pretrained(model_dir) # 加载训练好的文本分类模型 model = AutoModelForSequenceClassification.from_pretrained( model_name, device_map="auto" # 自动将模型分配到可用设备(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. 测试文本预处理 ===================== # 对测试文本进行分词、编码,转换为模型可接受的张量格式 # padding=True:自动填充到批次内最长文本长度 # truncation=True:截断超过max_length的文本 # return_tensors="pt":返回PyTorch张量 # max_length=128:文本最大长度(需与训练时保持一致) inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt", max_length=128) # ===================== 5. 模型推理(无梯度计算) ===================== # 初始化空列表存储预测结果 predictions = [] # torch.no_grad():禁用梯度计算,减少显存占用、提升推理速度(评估阶段无需反向传播) with torch.no_grad(): # 将编码后的输入传入模型,获取输出 outputs = model(**inputs) # 提取模型输出的原始logits(未经过softmax的原始得分) logits = outputs.logits # 对logits取argmax(最大得分对应的索引),得到预测类别,并转换为列表 predicted_classes = torch.argmax(logits, dim=1).tolist() # 将预测结果赋值到列表中 predictions = predicted_classes # ===================== 6. 计算模型评估指标 ===================== # 计算准确率:预测正确的样本数 / 总样本数 acc = accuracy_score(true_labels, predictions) print(f"模型准确率: {acc:.4f}") # 保留4位小数打印 # 计算宏平均F1分数:兼顾正负样本的召回率和精确率,适合二分类场景 f1 = f1_score(true_labels, predictions, average="macro") 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(frac=1, random_state=42).reset_index(drop=True) # 保存完整CSV文件 csv_filename = "sentiment_data.csv" df.to_csv(csv_filename, index=False, encoding="utf-8-sig") # utf-8-sig兼容更多编辑器 print(f"数据生成完成!已保存为 {csv_filename}") print(f"数据总量:{len(df)} 条") print(f"正面数据(label=1):{len(df[df['label']==1])} 条") print(f"负面数据(label=0):{len(df[df['label']==0])} 条")