二十一、基于 Hugging Face Transformers 实现中文情感分析情感分析

情感分析作为自然语言处理(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-wwmernie等其他中文预训练模型,或基于 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])} 条")
相关推荐
发哥来了3 小时前
《AI视频生成技术原理剖析及金管道·图生视频的应用实践》
人工智能
数智联AI团队3 小时前
AI搜索引领开源大模型新浪潮,技术创新重塑信息检索未来格局
人工智能·开源
不懒不懒4 小时前
【线性 VS 逻辑回归:一篇讲透两种核心回归模型】
人工智能·机器学习
冰西瓜6004 小时前
从项目入手机器学习——(四)特征工程(简单特征探索)
人工智能·机器学习
Ryan老房4 小时前
未来已来-AI标注工具的下一个10年
人工智能·yolo·目标检测·ai
丝斯20115 小时前
AI学习笔记整理(66)——多模态大模型MOE-LLAVA
人工智能·笔记·学习
小鸡吃米…5 小时前
机器学习中的代价函数
人工智能·python·机器学习
chatexcel6 小时前
元空AI+Clawdbot:7×24 AI办公智能体新形态详解(长期上下文/自动化任务/工具粘合)
运维·人工智能·自动化
bylander6 小时前
【AI学习】TM Forum《Autonomous Networks Implementation Guide》快速理解
人工智能·学习·智能体·自动驾驶网络